Security
Hardening
What the images do by default to reduce attack surface, and what you can add at runtime.
Built in
| Measure | Detail |
|---|---|
| Non-root execution | UID 1000 by default across every image. See Users and permissions. |
| No setuid or setgid binaries | busybox-suid is not installed; setuid bits from shadow are stripped. |
| Root-owned configuration | Everything under /etc stays root-owned; runtime config is rendered into /run. |
| Read-only rootfs support | Works with --read-only plus tmpfs mounts, so tampering does not survive a restart. |
No phpinfo() default page | A static placeholder is served when no application is mounted, so environment variables cannot leak. |
expose_php off | No X-Powered-By header. server_tokens off hides the Nginx version too. |
| Hidden files denied | /.env, /.git and any dot-prefixed path return 403. /.well-known/ is allowed. |
| Safe PHP dispatch | cgi.fix_pathinfo=0 and security.limit_extensions=.php. |
| Security headers | X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy on every response. |
| TLS | TLS 1.2 and 1.3 only, Mozilla intermediate ciphers, session tickets off, HSTS on. |
| Fixed redirect target | The HTTPS redirect uses the configured server name, not the request Host. |
| Secure cookies | HttpOnly, SameSite=Lax, and Secure whenever HTTPS is on; use_strict_mode on. |
allow_url_include off | Remote file inclusion disabled. |
| Digest-pinned base | alpine:3.24@sha256:..., plus apk upgrade at build time. |
| HTTPS package sources | Alpine repositories are fetched over HTTPS. |
| Pinned PHP | Exact release per minor, asserted after installation. |
| Scanned before publish | Trivy gates every tag. See Scanning and attestations. |
Recommended at runtime
These are not defaults because they depend on your application, but they are cheap wins.
--read-only --tmpfs /run:uid=1000,gid=1000 --tmpfs /var/log:uid=1000,gid=1000 \
--tmpfs /var/lib/nginx:uid=1000,gid=1000 --tmpfs /tmp
--cap-drop ALL --security-opt no-new-privileges
-e PHP_OPEN_BASEDIR=/var/www/html:/tmp
-e PHP_DISABLE_FUNCTIONS=exec,passthru,shell_exec,system,proc_open,popen
-e PHP_ALLOW_URL_FOPEN=Off
-e NGINX_SERVER_NAME=app.example.com
Mount your application read-only (:ro) and give PHP a separate writable volume for uploads and cache.
Reporting a vulnerability
Open an issue at github.com/AdamRollinson/docker/issues. For anything sensitive, use GitHub's private vulnerability reporting on the repository.