nginx Configuration

The production nginx config is split across two files, both tracked in the git repo and synced to the server by deploy.sh:

Repo fileServer pathContains
admin/nginx.conf/opt/server-stack/nginx/conf.d/nortonshop.confBot blocking map, all server blocks (HTTP redirect, HTTPS www, bare-domain redirect, CDN, API, admin, auth, docs, s, signal)
admin/nginx-main.conf/opt/server-stack/nginx/nginx.confWorker settings, gzip, rate limit zones, security headers, includes conf.d/*.conf

deploy.sh compares both files on each deploy. If either has changed, it copies the updated version to the server and restarts the nginx container automatically.

Bot blocking

All crawlers, scrapers, AI bots, and search engines are blocked at two levels:

The bot list in nginx.conf uses case-insensitive substring matching (~* prefix), grouped by category: AI assistants, AI training crawlers, search engines, social media, SEO tools, archive crawlers, and other scrapers. Around 90 patterns cover 169+ known bots. New offenders can be added by appending a line like "~*scraperforce" 1; inside the map block (remember to watch for stray unicode characters when editing remotely) and reloading nginx with docker compose exec nginx nginx -t && docker compose exec nginx nginx -s reload.

When the site is ready to go live, selectively allow search engines by removing them from the $is_bot map in admin/nginx.conf and updating robots.txt with Allow: / rules for the engines you want. For example, to allow Google and Bing indexing, remove googlebot and bingbot from the map, and add User-agent: Googlebot / Allow: / to robots.txt.

Security rules

Security rules are split between the main site and admin subdomain server blocks:

All server blocks:

Main site (www.nortonshop.net):

Admin subdomain (admin.nortonshop.net):

Auth subdomain (auth.nortonshop.net):

Custom 404 pages

The main site uses 404.html in the project root. The CDN uses static/404.html. Both are themed to match the site and are deployed via deploy.sh, so they survive container restarts and Watchtower updates.

SSL

Certificates are obtained by Certbot during server-setup.sh. The certificate covers nortonshop.net, www.nortonshop.net, cdn.nortonshop.net, api.nortonshop.net, admin.nortonshop.net, auth.nortonshop.net, docs.nortonshop.net, and s.nortonshop.net. A cron job runs twice daily (3am and 3pm) to check for renewal:

docker compose run --rm --entrypoint certbot certbot renew --quiet

Certbot only actually renews when the certificate is within 30 days of expiry. After renewal, nginx is reloaded automatically to pick up the new certificate.

Testing bot blocking

To verify a specific bot is blocked, use curl with a spoofed user-agent:

curl -I -A "AhrefsBot" https://www.nortonshop.net/    # should return 403
curl -I -A "DeepSeekBot" https://www.nortonshop.net/   # should return 403
curl -I -A "Mozilla/5.0" https://www.nortonshop.net/   # should return 200 (normal browser)
If you add new PHP or JSON files to the admin folder, make sure they are included in the deny rules on the admin subdomain server block, or intentionally whitelisted in the PHP whitelist.
Back to top