Apache Solr ships with an admin UI and a full REST-like API on port 8983, both completely open by default with no TLS and no authentication unless it’s explicitly configured. That’s a reasonable default for local development, but it’s a liability for anything reachable outside a trusted internal network. Putting Nginx in front of Solr adds TLS termination, a proper domain name, access control, and a layer where request-level restrictions (like blocking access to the admin UI from the public internet while still allowing the search API) can be enforced cleanly.
This guide walks through configuring Nginx as a reverse proxy for Solr, covering both single-node and SolrCloud considerations, along with the security precautions that matter most for this particular service.
Understanding How Solr Handles Proxying
Unlike NiFi or Superset, Solr doesn’t require much proxy-awareness configuration on its own side. Its REST API and admin UI generally work fine behind a reverse proxy without special headers, since Solr doesn’t generate a lot of absolute redirect URLs the way a full web framework does. The real work in this setup is on the Nginx side: correctly routing paths, handling the admin UI’s static assets, and — critically — deciding what should and shouldn’t be exposed externally at all.
The admin UI in particular is worth thinking about carefully. It offers direct access to core/collection management, schema editing, and query execution. Exposing it publicly without additional access control is a common misconfiguration that turns a search index into an open door for data exfiltration or index deletion.
Requirements
- A running Solr instance (standalone or SolrCloud), reachable internally on its default port
8983. - Nginx installed on the front-end server.
- A domain name pointed at the Nginx server.
- A TLS certificate (Let’s Encrypt via Certbot works well).
- Basic auth credentials or an upstream identity provider, if the admin UI needs to be exposed at all.
Install Nginx:
sudo apt update && sudo apt install nginx -y
Confirm Solr is running:
sudo ss -tlnp | grep 8983
curl http://127.0.0.1:8983/solr/admin/info/system
Step 1: Decide What Gets Exposed
Before writing the Nginx config, decide on the access model. Three common patterns:
- Full proxy — both the search API and the admin UI are reachable externally, protected by authentication. Suitable for small internal teams needing UI access for debugging.
- API-only proxy — only
/solr/<collection>/selectand similar query endpoints are exposed; the admin UI (/solr/#/) and core management endpoints are blocked entirely at the Nginx layer. This is the recommended pattern for anything customer-facing. - Internal-only — Solr isn’t exposed externally at all, and Nginx is only used to add TLS for service-to-service communication within a private network.
The example configuration below implements pattern 2, since it’s the safest default, with notes on how to open it up to pattern 1 if needed.
Step 2: Write the Nginx Configuration
Create the config file:
sudo nano /etc/nginx/sites-available/solr.conf
Example configuration implementing the API-only pattern with basic auth as an extra layer:
server {
listen 80;
server_name solr.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name solr.example.com;
ssl_certificate /etc/letsencrypt/live/solr.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/solr.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Block the admin UI and core-management endpoints entirely
location ~ ^/solr/(admin|.*\/admin)(/|$) {
deny all;
return 403;
}
location ~ ^/solr/#/ {
deny all;
return 403;
}
# Allow read-only query endpoints for known collections
location ~ ^/solr/[^/]+/(select|query|get|suggest)$ {
auth_basic "Solr API Access";
auth_basic_user_file /etc/nginx/.solr_htpasswd;
proxy_pass http://127.0.0.1:8983;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
# Anything else under /solr/ is denied by default
location /solr/ {
deny all;
return 403;
}
location / {
return 404;
}
}
Generate the htpasswd file for basic auth:
sudo apt install apache2-utils -y
sudo htpasswd -c /etc/nginx/.solr_htpasswd solr_reader
If the admin UI genuinely needs to be exposed to an internal team, replace the “deny all” admin block with an IP allowlist plus basic auth instead of a flat denial:
location /solr/ {
allow 10.0.0.0/8;
allow 203.0.113.42;
deny all;
auth_basic "Solr Admin";
auth_basic_user_file /etc/nginx/.solr_htpasswd;
proxy_pass http://127.0.0.1:8983;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Enable and test:
sudo ln -s /etc/nginx/sites-available/solr.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Step 3: Testing the Setup
Test the query endpoint through the proxy:
curl -u solr_reader -k "https://solr.example.com/solr/mycollection/select?q=*:*&rows=1"
It should prompt for the basic auth password and return a JSON response with search results.
Confirm the admin UI is properly blocked (or properly restricted, depending on the chosen pattern):
curl -Ik https://solr.example.com/solr/#/
This should return a 403 if using the API-only pattern.
Verify core status endpoints used by monitoring tools still work, since some monitoring integrations query /solr/admin/cores or /solr/admin/collections directly — adjust the allow rules if internal monitoring needs specific endpoints.
Troubleshooting
502 Bad Gateway Confirm Solr is actually running and bound correctly:
sudo systemctl status solr
sudo ss -tlnp | grep 8983
403 Forbidden on legitimate query requests The regex in the location block matching allowed endpoints is strict by design. If the application uses an endpoint not covered (like /solr/mycollection/update for indexing, or a custom request handler), it needs to be explicitly added to the allowed pattern — don’t just open everything, add the specific handler.
SolrCloud queries fail intermittently In a SolrCloud setup, queries can be internally routed between nodes. If Nginx is only proxying to one node and that node is down or a shard has moved, requests can fail. Consider proxying to a load-balanced set of Solr nodes using an upstream block, or point the proxy at a dedicated Solr load balancer if one exists in the cluster.
Basic auth prompt appears repeatedly Usually a browser/cache issue, or credentials aren’t being cached because of a session/cookie policy mismatch. For programmatic API access, confirm the client is sending the Authorization header on every request, since HTTP basic auth doesn’t persist across requests without explicit client support.
Streaming/large result sets get cut off Increase proxy_read_timeout and check proxy_buffering settings; very large result sets (deep pagination, big faceting responses) can exceed default buffer sizes.
Security Considerations
Solr security deserves particular attention because its default state is genuinely open:
- Never expose Solr’s raw port 8983 externally. Bind Solr to
127.0.0.1or a private network interface once the Nginx proxy is verified. - Block the admin UI and update/delete endpoints from public access unless there’s a specific, access-controlled reason not to. The
update,delete, and core/collection management endpoints can modify or destroy data. - Layer authentication. Nginx basic auth is a reasonable outer layer, but Solr also supports its own
BasicAuthPluginand rule-based authorization — using both isn’t redundant, it’s defense in depth. - Enable standard security headers:
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
- Log and monitor query patterns. Unusual query volume or unfamiliar query parameters (like attempts to hit
/solr/admin/cores?action=UNLOAD) are worth alerting on. - Restrict by IP wherever the consumer set is known, since search APIs are frequently internal-only even when the frontend serving them is public.
Performance Tips
- Enable gzip for JSON responses, since Solr’s default response format is JSON and search results compress well:
gzip on;
gzip_types application/json;
gzip_min_length 512;
- Cache read-heavy, rarely-changing queries at the Nginx layer using
proxy_cachefor query patterns known to repeat frequently (like popular search terms or autocomplete suggestions), reducing load on Solr itself. - Use keepalive connections to the Solr upstream to avoid TCP handshake overhead on every query:
upstream solr_backend {
server 127.0.0.1:8983;
keepalive 32;
}
- Tune
proxy_buffersfor large faceted search responses, since undersized buffers cause Nginx to spool responses to disk temporarily, adding latency.
Real-World Use Cases
- Public-facing site search, where only the
selectendpoint for a specific collection is exposed, fully isolated from index management endpoints. - Internal search dashboards where the Solr admin UI is exposed to the engineering team only, gated by IP allowlist and basic auth, without needing a full VPN.
- Multi-tenant search platforms, where different subdomains or path prefixes route to different Solr collections, each with independently tunable rate limits.
- SolrCloud clusters behind a stable endpoint, where Nginx provides a consistent external hostname even as individual nodes in the cluster are added, removed, or rebalanced.
Best Practices Checklist
- Bind Solr to a private interface; never expose port 8983 directly to the internet.
- Explicitly allow only the specific query endpoints actually needed — default to denying everything else.
- Block or tightly restrict the admin UI and any update/delete/core-management endpoints.
- Layer Nginx-level authentication with Solr’s own authentication/authorization where possible.
- Cache frequent, low-volatility queries at the proxy layer to reduce backend load.
- Use keepalive connections between Nginx and Solr for better throughput under load.
- Monitor logs for unusual access patterns targeting administrative endpoints.
Solr’s default openness makes it one of the more security-sensitive services to reverse proxy well. The Nginx configuration itself is straightforward, but the real work is deciding — deliberately, endpoint by endpoint — what gets exposed and what doesn’t, rather than proxying the entire service wholesale and hoping nothing important is reachable.
