NGINX on Alpine with the extras module set compiled in.
810
NGINX on Alpine with the “extras” module installed. There are probably other containers like this but this is the one I run.
Features:
Image: hlhd/nginx-extras:latest Base: alpine:3.22.1
At container start:
Environment knobs:
nginx.conf (defaults)
docker-compose (recommended)
version: "3.9"
services:
nginx:
image: hlhd/nginx-extras:latest
container_name: nginx-extras
restart: always
ports:
- "80:80"
- "443:443"
security_opt:
- no-new-privileges:true
tmpfs:
- /var/cache/nginx:rw,noexec,nosuid,nodev,size=64m
environment:
TZ: "America/Los_Angeles"
dns: ["10.0.0.1","10.0.0.2"]
dns_search: ["prplanit.internal"]
volumes:
# main config + sites
- /opt/docker/nginx-extras/nginx.conf:/etc/nginx/nginx.conf:ro
- /etc/nginx/conf.d:/etc/nginx/conf.d:ro # mount your vhosts here
- /opt/docker/nginx-extras/snippets:/etc/nginx/snippets:ro
# TLS & logs
- /opt/docker/nginx-extras/ssl:/etc/nginx/ssl
- /opt/docker/nginx-extras/logs:/var/log/nginx
- /opt/docker/nginx-extras/letsencrypt:/etc/letsencrypt
# share pid if you’ll SIGHUP from certbot
- /var/run/nginx:/var/run/nginx
# extras you rely on
- /etc/nginx/dhparam.pem:/etc/nginx/dhparam.pem
- /etc/nginx/cloudflare:/etc/nginx/cloudflare
- /mnt/timecapsule/Server/Web-App/NGINX:/mnt/timecapsule/Server/Web-App/NGINX
healthcheck:
test: ["CMD-SHELL","wget -qO- http://127.0.0.1:8080/healthz >/dev/null"]
interval: 30s
timeout: 5s
retries: 3
certbot:
image: certbot/dns-cloudflare:latest
container_name: certbot
restart: always
pid: "service:nginx" # lets deploy-hook HUP PID 1 (nginx) cleanly
volumes:
- /opt/docker/nginx-extras/letsencrypt:/etc/letsencrypt
- /opt/docker/nginx-extras/secrets/dns_cloudflare_api_token.ini:/secrets/dns_cloudflare_api_token.ini:ro
entrypoint:
- sh
- -c
- |
while :; do
certbot renew \
--dns-cloudflare \
--dns-cloudflare-credentials /secrets/dns_cloudflare_api_token.ini \
--preferred-challenges dns \
--non-interactive --agree-tos \
--deploy-hook 'kill -HUP 1' ;
sleep 12h
done
Tip: uncomment user: "101:101", read_only: true, and capability lines if/when you want to harden further.
docker run -d --name nginx-extras \
-p 80:80 -p 443:443 \
-v /etc/nginx/conf.d:/etc/nginx/conf.d:ro \
-v /opt/docker/nginx-extras/ssl:/etc/nginx/ssl \
-v /opt/docker/nginx-extras/letsencrypt:/etc/letsencrypt \
hlhd/nginx-extras:latest
Create /etc/nginx/conf.d/app.example.conf:
server {
listen 80;
server_name app.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# proxy defaults (global map $connection_upgrade exists)
proxy_http_version 1.1;
proxy_buffering off;
proxy_read_timeout 300s;
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_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
location / {
proxy_pass http://backend.internal:8080;
}
}
server {
listen 443 ssl;
server_name embed.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# require headers-more (already installed)
more_clear_headers X-Frame-Options;
add_header Content-Security-Policy "frame-ancestors 'self' https://apps.example.com" always;
location / { proxy_pass http://embed.internal:3000; }
}
# health
curl -fsS http://127.0.0.1:8080/healthz
# config dump / syntax check
docker exec -it nginx-extras nginx -T
docker exec -it nginx-extras nginx -t
# live logs
docker logs -f nginx-extras
listen 443 ssl;
http2 on;
ssl_trusted_certificate /etc/letsencrypt/live/precisionplanit.com/chain.pem;
ssl_session_timeout 5m;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;
ssl_stapling on;
ssl_stapling_verify on;
ssl_dhparam /etc/nginx/dhparam.pem;
Distributed under the GPL-3.0 License.
Content type
Image
Digest
sha256:c1823e6f5…
Size
9.9 MB
Last updated
12 days ago
docker pull hlhd/nginx-extras:latest-dev