Deployment guide

Apache Nutch

Overview

Apache Nutch is a mature, extensible open-source web crawler built on Apache Lucene. This SecureAnyCloud appliance ships Nutch 1.22 in local mode (Hadoop libraries bundled, but no Hadoop cluster), wired to a bundled Apache Solr 9.10 search index. You can crawl web content and search it in full text from a single node.

Nutch fetches, parses, de-duplicates and scores pages as batch jobs and hands the results to Solr over authenticated HTTP. Solr serves faceted, full-text and vector search over everything crawled. Both components are Apache-2.0, and there is no Elasticsearch or any SSPL-licensed datastore in the stack.

What you get:

  • Apache Nutch 1.22 (web crawler) at /opt/nutch, running in local mode on OpenJDK 11
  • Apache Solr 9.10.1 (Lucene 9 search index) at /opt/solr, running on OpenJDK 17 and listening on 127.0.0.1:8983 (loopback only, so you reach it over an SSH tunnel)
  • A pre-created Solr nutch core (schemaless _default configset) that Nutch indexes into
  • solr.service running as the unprivileged solr user. Nutch is a batch CLI with no daemon
  • BasicAuthPlugin and RuleBasedAuthorizationPlugin protecting every Solr endpoint
  • A per-VM SecureAnyCloud admin password generated at first boot (never shipped) and injected into both Solr and Nutch's Solr-indexer config
  • /usr/local/bin/nutch-demo-crawl, a bundled end-to-end demo that crawls a local page, indexes it into Solr and queries it back
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key, and a VNet with a subnet.

Standard_B2s (4 GB RAM) runs a crawl-and-index cycle out of the box, with a Solr heap of 512m and a Nutch batch JVM of up to 1024m. For large-scale crawling and bigger indexes, move to D4s or D8s and increase SOLR_HEAP and NUTCH_HEAPSIZE.

Configure the network security group (NSG) to allow inbound 22/tcp from your management CIDR. Solr listens on loopback only, so you reach the Solr Admin UI and REST API through an SSH tunnel and do not need to open 8983/tcp.

Step 1-3 - Deploy the VM and connect over SSH

Deploy the Apache Nutch image from the Azure Marketplace, then connect to the VM over SSH:

ssh azureuser@<vm-ip>
4

Service Status and Versions

sudo systemctl is-active solr.service /opt/solr/bin/solr version NUTCH_JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 /opt/nutch/bin/nutch version | grep -i nutch ss -tln | grep 8983

solr.service is active and listening on 8983. The bundled Solr reports 9.10.1 and Nutch reports 1.22. Nutch has no long-running daemon, because you run it as a batch job when you crawl.

5

Auth Wall and System Info

curl -s -o /dev/null -w 'no-auth: HTTP %{http_code}\n' http://127.0.0.1:8983/solr/admin/info/system
PASS=$(sudo grep '^SOLR_ADMIN_PASSWORD=' /stage/scripts/nutch-credentials.log | cut -d= -f2-)
curl -sf -u "sac:${PASS}" 'http://127.0.0.1:8983/solr/admin/info/system?wt=json' | head -c 300

The first call returns 401 from the BasicAuthPlugin auth wall, so no unauthenticated Solr admin is reachable off-host. The second call authenticates as SecureAnyCloud and returns the system info JSON, including solr-spec-version.

6

Read Per-VM Credentials

sudo cat /stage/scripts/nutch-credentials.log

Note SOLR_ADMIN_URL, SOLR_ADMIN_USER (SecureAnyCloud), SOLR_ADMIN_PASSWORD and NUTCH_CORE_URL. The password is a fresh 32-character hex string generated on this VM's first boot, so no two VMs share credentials. The same secret is already injected into Nutch's Solr-indexer config, so the crawler authenticates automatically.

7

End-to-End Crawl, Index and Search Demo

Run the bundled, self-contained demo to prove the whole pipeline. It serves a throwaway HTML page on 127.0.0.1:8899 and runs one Nutch crawl round that indexes into the Solr nutch core. It then queries the document back out with the per-VM credentials.

sudo nutch-demo-crawl
PASS=$(sudo grep '^SOLR_ADMIN_PASSWORD=' /stage/scripts/nutch-credentials.log | cut -d= -f2-)
curl -sf -u "sac:${PASS}" 'http://127.0.0.1:8983/solr/nutch/select?q=title:sac&fl=id,title,url&wt=json' | head -c 400

nutch-demo-crawl prints NUTCH_E2E_OK once the crawled document is searchable, and the follow-up query returns it under response.docs with numFound: 1.

8

Solr Admin UI Dashboard

Solr listens on 127.0.0.1 only, so first open an SSH tunnel from your workstation:

ssh -L 8983:127.0.0.1:8983 azureuser@<vm-ip>

Then browse to http://localhost:8983/solr/ and sign in as SecureAnyCloud with the per-VM password. The Dashboard shows the Solr instance, JVM memory (-Xmx512m on Standard_B2s), versions, and the active BasicAuthPlugin and RuleBasedAuthorizationPlugin.

9

The nutch Core

Pick nutch in the Core Selector. This is the core that Nutch indexes every crawled page into. Its overview lists the schema, document statistics and the query interface.

10

Search Crawled Content in the Query UI

Open the Query tab on the nutch core, set q to title:sac and click Execute Query. Solr returns the crawled demo document, where id is the page URL, with title, url, content and host fields populated by Nutch's indexing filters.

11

Crawl Your Own Website

To crawl a real site, put its seed URLs in a seeds directory and run one or more crawl rounds. bin/crawl -i indexes each round straight into the Solr nutch core, using the per-VM credentials already wired into conf/index-writers.xml:

sudo install -d -m 0700 /var/lib/nutch /var/lib/nutch/urls echo 'https://<your-domain>/' | sudo tee /var/lib/nutch/urls/seed.txt export NUTCH_JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 NUTCH_HEAPSIZE=1024 cd /opt/nutch
sudo -E bin/crawl -i -s /var/lib/nutch/urls /var/lib/nutch/crawl 2

Set http.agent.name (and ideally http.agent.email) in /opt/nutch/conf/nutch-site.xml to identify your crawler to the sites you fetch. Edit /opt/nutch/conf/regex-urlfilter.txt to restrict the crawl scope. Increase the round count (the trailing 2) to crawl deeper.

12

How Nutch Indexes into Solr

Nutch's Solr indexer target lives in /opt/nutch/conf/index-writers.xml. It points at the local nutch core with BasicAuth enabled:

sudo grep -E 'name="url"|name="auth"|name="username"' /opt/nutch/conf/index-writers.xml

The url is http://localhost:8983/solr/nutch, auth is true, and username is SecureAnyCloud. The password is injected at first boot and never baked into the image. The enabled plugins (protocol-http, parse-html/parse-tika, index-basic/index-anchor and indexer-solr) are set in /opt/nutch/conf/nutch-site.xml.

13

Tune Heap and Scaling

Solr heap is set in /etc/default/solr.in.sh (SOLR_HEAP="512m" on Standard_B2s); Nutch's batch JVM is capped by NUTCH_HEAPSIZE (MB). Both fit a crawl-and-index cycle inside 4 GB:

grep -E '^SOLR_HEAP|^SOLR_JAVA_HOME' /etc/default/solr.in.sh

For large crawls, raise SOLR_HEAP to 4096m+ and NUTCH_HEAPSIZE to 4096+ on D4s/D8s instances, then restart Solr with sudo systemctl restart solr.service. For very large crawls, migrate Nutch to a Hadoop cluster and Solr to SolrCloud (add ZooKeeper). The crawl commands are unchanged.

14

Logs and Troubleshooting

sudo journalctl -u solr.service --no-pager -n 40
sudo journalctl -u nutch-firstboot.service --no-pager -n 20
sudo tail -40 /var/solr/logs/solr.log 2>/dev/null

Solr writes its main log to /var/solr/logs/solr.log. Each Nutch crawl round prints its Hadoop-local job output to the terminal; redirect it to a file for long crawls. The systemd journal captures the first-boot credential-rotation script.

Security

  • BasicAuthPlugin (blockUnknown: true) enforces authentication on every Solr endpoint, and Solr listens on 127.0.0.1:8983 only, so there is no unauthenticated Solr endpoint and nothing is reachable off-host
  • /var/solr/data/security.json stores double-SHA-256 plus salt password digests. The plaintext per-VM copy in /stage/scripts/nutch-credentials.log is 0600 root:root
  • Per-VM credentials are generated at first boot, so there is no shared secret between deployments, and the upstream Solr default (no security) is never shipped
  • Nutch authenticates to Solr with the same per-VM credential. It is injected into index-writers.xml (which is 0600 root:root) at first boot and reset to a neutral value in the shipped image
  • To serve Solr to other hosts, put an HTTPS reverse proxy in front of 127.0.0.1:8983 (or set SOLR_JETTY_HOST in /etc/default/solr.in.sh and enable Solr SSL), and restrict NSG inbound to the IP ranges that need it
  • Terminate TLS at an upstream Azure Application Gateway or Front Door, or enable Solr's own SSL (jetty-ssl.xml plus a keystore) for HTTPS

Support

SecureAnyCloud provides 24/7/365 expert technical support. Guaranteed response within 24 hours, one hour average for critical issues. Contact sales@secureanycloud.com.

Deploy on Azure

Launch Apache Nutch 1.22 crawl-and-search appliance on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure