π¬π§ English | π·πΊ Π ΡΡΡΠΊΠΈΠΉ
Production-ready nginx in Docker with built-in protection: rate limiting, security headers (including HSTS), token authorization.
Supports two modes:
- HTTP β for local development or a server without SSL
- HTTPS β for production, Let's Encrypt certificates via Certbot
- Docker Desktop (includes Docker Compose)
- Git
Check that everything is installed:
docker --version
docker compose versionconf/
http-nginx.conf # nginx config for HTTP mode
https-nginx.conf # nginx config for HTTPS mode
snippets/
security-headers.conf # Security headers
.env # Your settings (do not commit!)
.env.example # Settings template
compose.yml # Docker Compose
Dockerfile # nginx Alpine image
entrypoint.sh # Env var substitution on startup
init-ssl.sh # First-run script for HTTPS
git clone git@github.com:luckyfoxdesign/docker-nginx-http.git
cd docker-nginx-httpcp .env.example .envOpen .env and fill it in:
NGINX_CONF=http-nginx.conf # HTTP mode
DOMAINS=example.com # Your domain (or localhost)
PRIMARY_DOMAIN=example.com # Primary domain (same one)
LETSENCRYPT_EMAIL= # Can be left empty
AUTH_TOKEN=Bearer change-this # Secret token for the APITo generate a strong token:
openssl rand -hex 32
docker compose up -dcurl http://localhost/healthz
# Should return: OKThe domain must already point to the server's IP, otherwise Let's Encrypt won't issue a certificate.
git clone git@github.com:luckyfoxdesign/docker-nginx-http.git
cd docker-nginx-httpcp .env.example .envOpen .env and fill it in:
NGINX_CONF=http-nginx.conf # The script will switch to https itself
DOMAINS=example.com www.example.com # All domains separated by spaces
PRIMARY_DOMAIN=example.com # Primary domain (first in the list)
LETSENCRYPT_EMAIL=you@email.com # Email for Let's Encrypt notifications
AUTH_TOKEN=Bearer change-this # Secret token for the APITo generate a strong token:
openssl rand -hex 32
./init-ssl.shThe script does everything for you:
- Brings up nginx on HTTP for domain validation
- Obtains an SSL certificate from Let's Encrypt
- Switches nginx to HTTPS
- Starts automatic certificate renewal (certbot renews the files, nginx picks them up itself via reload every 12 hours β no manual steps, no downtime)
curl https://example.com/healthz
# Should return: OKSay you have an app container running on port 8080.
Uncomment and edit the block at the end of the file:
my-app:
image: my-app:latest
container_name: my-app-c
restart: always
networks:
- internal_net # Internal network only β not reachable from outside
# Do NOT add ports: β access only through nginxOpen conf/http-nginx.conf (or https-nginx.conf) and add a location inside the relevant server {}:
location /api/ {
proxy_pass http://my-app-c:8080;
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;
}The name
my-app-cis thecontainer_namefrom compose.yml. Docker uses it as DNS inside the network.
# HTTP mode
docker compose up -d
# HTTPS mode
docker compose --profile https up -d# Check container status
docker compose ps
# View nginx logs
docker compose logs -f nginx-s
# Reload nginx without downtime (after changing the config)
# New certificates are picked up automatically every 12h β manual reload is only needed after config edits
docker exec nginx-c nginx -s reload
# Force-renew the certificate
docker compose --profile https run --rm certbot renew --force-renewal
# Stop everything
docker compose downThe /api/* endpoints are protected by a Bearer token. Generate a strong token:
openssl rand -hex 32Put the result into .env:
AUTH_TOKEN=Bearer <generated-token>To call the API:
curl -H "Authorization: Bearer <your-token>" https://example.com/api/signalMIT