Container Security Best Practices for Self-Hosting
Containers aren't inherently secure. Follow these best practices to harden your self-hosted container infrastructure.
Containers Are Not VMs
Containers share the host kernel. A container escape vulnerability gives an attacker access to the host and all other containers. Security must be layered.
Image Security
Use Official Images
Always prefer official images from Docker Hub or verified publishers. Community images may contain malware or vulnerabilities.
Pin Image Versions
Never use :latest in production. Pin to specific versions (postgres:16.2) so updates are intentional, not accidental.
Scan for Vulnerabilities
Use Trivy or Grype to scan images before deployment. Block images with critical CVEs.
Minimize Image Size
Smaller images have fewer vulnerabilities. Use Alpine-based images when possible. A 50 MB image has fewer attack vectors than a 500 MB one.
Runtime Security
Run as Non-Root
Containers should run as a non-root user. Add USER to your Dockerfile or use Podman's rootless mode.
Read-Only Filesystem
Mount the container filesystem as read-only. Only mount writable volumes where the application needs to write.
Drop Capabilities
Linux capabilities grant specific privileges. Drop all capabilities and add back only what's needed.
Resource Limits
Always set CPU and memory limits. A compromised container running a crypto miner shouldn't be able to consume all server resources.
Network Security
Isolate Networks
Put each project on its own network. A compromised container in Project A shouldn't be able to reach Project B's database.
Don't Expose Unnecessary Ports
Databases, Redis, and internal services should not have ports mapped to the host. Only expose what needs to be publicly accessible.
Use a Reverse Proxy
Never expose application ports directly. Route through Caddy or Nginx with SSL termination.
Secrets Management
Never Bake Secrets into Images
Don't put API keys, passwords, or tokens in Dockerfiles. Use environment variables or secret management tools.
Rotate Regularly
Change database passwords, API keys, and tokens periodically.