- DIGITAL Command Language 100%
| .scratch | ||
| conf.d | ||
| sites-available | ||
| sites-enabled | ||
| snippets | ||
| .gitignore | ||
| mime.types | ||
| nginx.conf | ||
| README.md | ||
sweetpea-nginx-config
Nginx reverse proxy configuration for sweetpea (Dell OptiPlex 7050 Micro, 10.0.50.47).
Nginx runs inside Docker via /opt/reverse-proxy/. This repo tracks the config mounted
into the container at /etc/nginx — vhosts, snippets, upstreams, and nginx.conf itself.
How it fits in the infrastructure
Internet / LAN clients / Tailscale clients
│
▼
sweetpea:80/443
nginx (Docker) ← this repo configures nginx
│
├── cloud.janovitch.com → qwerty:8080 (Nextcloud)
├── photos.janovitch.com → qwerty:2283 (Immich)
├── movies.janovitch.com → qwerty:8096 (Jellyfin)
├── *.home LAN/Tailscale → qwerty / arrs-vm services
└── arr-stack vhosts → arrs-vm:192.168.30.40 (VLAN30)
All external domains are proxied through Cloudflare. TLS is terminated at sweetpea.
Internal .home domains are resolved by dnsmasq on sweetpea and pushed to Tailscale
clients via split DNS — see docs/tailscale.md in the Raymer homelab repo.
Key files
| Path | Purpose |
|---|---|
nginx.conf |
Main nginx config |
conf.d/upstreams.conf |
All backend upstream definitions |
snippets/ssl.conf |
TLS settings, HSTS, security headers |
snippets/proxy.conf |
Proxy headers, websocket upgrade, timeouts |
snippets/letsencrypt-cert.conf |
Let's Encrypt cert paths |
snippets/self-signed-cert.conf |
Self-signed cert paths (catch-all) |
snippets/maintenance.conf |
Maintenance page fallback |
sites-available/ |
All vhost definitions |
sites-enabled/ |
Symlinks to enabled vhosts |
Vhost naming convention
Each arr-stack vhost has both a bare name and a .home variant so it resolves from
the LAN (via dnsmasq DHCP search domain) and from Tailscale clients (via split DNS):
server_name sonarr sonarr.home;
TLS certificates
| Cert | Path | Covers |
|---|---|---|
| Let's Encrypt wildcard | /etc/letsencrypt/live/aaronjanovitch.com/ |
*.aaronjanovitch.com, *.janovitch.com |
| Self-signed | /opt/ssl/fullchain.pem |
Default catch-all vhost |
Cert renewal is managed by a separate certbot container at /opt/certbot/.
Known gap: no post-renewal nginx reload hook — see ROADMAP.
Deployed on
Machine: sweetpea (10.0.50.47)
Docker stack: /opt/reverse-proxy/docker-compose.yml
Git remote (home): /srv/git/repos/sweetpea-nginx-config.git (local bare repo on sweetpea)
Workflow
# Connect
ssh sweetpea
# Edit a vhost
sudo nano /etc/nginx/sites-available/<vhost>
# Test config
docker exec nginx nginx -t
# Reload without downtime
docker exec nginx nginx -s reload
# Commit and push (sudo required — /etc/nginx is root-owned)
sudo git -C /etc/nginx add <files>
sudo git -C /etc/nginx commit -m "..."
sudo git -C /etc/nginx push home main
First-time push setup (safe.directory)
The bare remote (/srv/git/repos/sweetpea-nginx-config.git) is owned by git:git
but pushes run as root. Run once after provisioning or re-imaging sweetpea:
sudo git config --global --add safe.directory /srv/git/repos/sweetpea-nginx-config.git