Configuration

SSL and HTTPS

Enable HTTPS with your own certificate or a generated one, control the redirect, HSTS and TLS settings.

HTTPS is opt-in. With NGINX_SSL_ENABLED=false (the default) all NGINX_SSL_* variables are ignored and the container serves plain HTTP only.

Your own certificate

Mount the certificate and key read-only at the default paths, or point the path variables at them.

docker run --rm -d -p 80:80 -p 443:443 --user root \
  -e NGINX_SSL_ENABLED=true \
  -e NGINX_SERVER_NAME=app.example.com \
  -v /etc/letsencrypt/live/app.example.com/fullchain.pem:/etc/nginx/ssl/cert.pem:ro \
  -v /etc/letsencrypt/live/app.example.com/privkey.pem:/etc/nginx/ssl/key.pem:ro \
  -v $(pwd)/public:/var/www/html:ro \
  adamrollogi/php-nginx:8.4

The entrypoint checks both files are readable before starting and exits with a clear message if not.

Self-signed certificate

For local development or behind a terminating load balancer:

docker run --rm -d -p 8080:8080 -p 8443:8443 \
  -e NGINX_PORT=8080 \
  -e NGINX_SSL_ENABLED=true \
  -e NGINX_SSL_PORT=8443 \
  -e NGINX_SSL_SELF_SIGNED=true \
  -e NGINX_SSL_SELF_SIGNED_CN=app.local \
  adamrollogi/php-nginx:8.4

A 2048-bit RSA certificate with CN and SAN set to NGINX_SSL_SELF_SIGNED_CN (plus IP:127.0.0.1) is generated into /etc/nginx/ssl/ on first start and reused afterwards. Mount that directory to keep it between containers.

The HTTP to HTTPS redirect

With NGINX_SSL_REDIRECT=true (the default), a second listener on NGINX_SSL_REDIRECT_PORT (which inherits NGINX_PORT) answers:

  • /health with 200 OK, so load balancers keep probing over plain HTTP.
  • /.well-known/acme-challenge/ from the document root, so Let's Encrypt HTTP-01 validation works.
  • everything else with a 301 to https://<host>[:port]<uri>.

The host in that redirect is chosen in this order:

  1. NGINX_SSL_REDIRECT_HOST if set.
  2. The first entry of NGINX_SERVER_NAME, unless it is _, a wildcard or a regex.
  3. The request's Host header, with a warning logged at startup.
Option 3 reflects whatever Host a client sends, which is an open redirect. Set NGINX_SERVER_NAME or NGINX_SSL_REDIRECT_HOST for anything internet-facing.

The port is omitted from the redirect when NGINX_SSL_PORT is 443.

Set NGINX_SSL_REDIRECT=false to serve HTTPS only with no HTTP listener.

HSTS

Strict-Transport-Security: max-age=63072000; includeSubDomains is sent on HTTPS responses by default. Tune with NGINX_SSL_HSTS_MAX_AGE or disable with NGINX_SSL_HSTS=false. There is no preload directive; add it through a drop-in if you have submitted your domain.

TLS settings

VariableDefault
NGINX_SSL_PROTOCOLSTLSv1.2 TLSv1.3
NGINX_SSL_CIPHERSMozilla intermediate list (ECDHE and DHE with AES-GCM and ChaCha20)
NGINX_SSL_PREFER_SERVER_CIPHERSoff
NGINX_SSL_SESSION_CACHEshared:SSL:10m
NGINX_SSL_SESSION_TIMEOUT1d

Session tickets are disabled. TLS 1.0 and 1.1 are refused. ssl_session_cache and ssl_session_timeout are http-level directives, so the entrypoint patches them into the rendered nginx.conf rather than the server block.

Session cookies

When NGINX_SSL_ENABLED=true, PHP_SESSION_COOKIE_SECURE resolves to On automatically, so PHPSESSID carries the Secure flag. Override it explicitly if you terminate TLS elsewhere and still want the flag.

Health checks

The image's HEALTHCHECK runs healthcheck.sh, which probes /health on the redirect port over HTTP when the redirect is on, or on the HTTPS port (ignoring the certificate) when it is off. Point external probes at the same endpoint.

Read-only root filesystem

If you run with --read-only and NGINX_SSL_SELF_SIGNED=true, add --tmpfs /etc/nginx/ssl:uid=1000,gid=1000 so the certificate can be written. See Users and permissions.