Container Security
debt(d5/e5/b5/t7)
Closest to 'specialist tool catches' (d5). The term's detection_hints.tools lists Trivy, Grype, Hadolint, Checkov, and docker-bench — all specialist security scanning tools. These catch CVEs in images, Dockerfile misconfigurations (running as root, no USER directive), and privileged container settings. Not caught by standard PHP linters or compilers; requires dedicated container security tooling.
Closest to 'touches multiple files / significant refactor' (e5). The quick_fix involves modifying Dockerfile (USER directive, read-only filesystem), adjusting container runtime configuration (dropping capabilities), and implementing scanning pipelines. While each individual fix is small, properly securing containers touches Dockerfile, docker-compose/orchestration configs, CI/CD pipelines for scanning, and potentially application code for secrets handling. Not architectural rework, but spans multiple files and processes.
Closest to 'persistent productivity tax' (b5). Container security applies broadly (web, cli contexts per applies_to) and becomes a continuous concern — every new image, every dependency update, every deployment requires security consideration. Teams must maintain scanning pipelines, keep base images updated, and enforce security policies. It's not system-defining (b9) but creates ongoing overhead across development workflows.
Closest to 'serious trap' (t7). The misconception field explicitly states developers believe 'containers provide strong isolation from the host' when in reality 'containers share the kernel; a kernel exploit or misconfigured container can escape to the host; containers are not VMs.' This directly contradicts how developers familiar with VMs expect isolation to work. The mental model of containers-as-lightweight-VMs is pervasive and dangerous, leading to assumptions about security boundaries that don't exist.
Also Known As
TL;DR
Explanation
Container security spans the full lifecycle: build (minimal base images, no secrets in layers, multi-stage builds), ship (image scanning for CVEs, signed images), run (non-root user, read-only filesystem, dropped capabilities, seccomp profiles, network policies). Containers share the host kernel — a container escape gives access to the host. PHP containers should run as a non-root user, have no write access to the application directory, and have sensitive directories mounted read-only.
Diagram
flowchart TD
subgraph Attack Surface
IMG[Base image<br/>CVEs in OS packages]
ROOT[Running as root<br/>container escape]
SECRETS[Secrets in ENV<br/>or image layers]
NETWORK[No network policy<br/>lateral movement]
end
subgraph Hardening
SCAN[Scan image: Trivy Snyk]
NONROOT[USER nonroot<br/>in Dockerfile]
VAULT[Secrets from Vault<br/>or K8s secrets]
NETPOL[NetworkPolicy<br/>deny by default]
end
IMG --> SCAN
ROOT --> NONROOT
SECRETS --> VAULT
NETWORK --> NETPOL
style IMG fill:#f85149,color:#fff
style ROOT fill:#f85149,color:#fff
style SCAN fill:#238636,color:#fff
style NONROOT fill:#238636,color:#fff
Common Misconception
Why It Matters
Common Mistakes
- Running containers as root — if the container is compromised, the attacker has root inside it.
- Secrets in Dockerfile ENV or image layers — image history exposes them; use secrets management or runtime injection.
- Using :latest tags — unpredictable base image changes break reproducibility and introduce unknown vulnerabilities.
- Not scanning images for CVEs — vulnerable base images are used in production without awareness.
Code Examples
# Insecure Dockerfile:
FROM php:latest # Unpinned, unknown contents
RUN apt-get install -y curl # Extra attack surface
COPY . /app
COPY .env /app/.env # Secrets in image layer!
USER root # Running as root
EXPOSE 80
# Hardened Dockerfile:
FROM php:8.3.4-fpm-alpine AS runtime # Pinned, minimal
RUN addgroup -g 1001 app && adduser -D -u 1001 -G app app
WORKDIR /app
# Copy only production files, no secrets:
COPY --chown=app:app src/ ./src/
COPY --chown=app:app vendor/ ./vendor/
USER app # Non-root
EXPOSE 9000
# Secrets injected at runtime via env vars or secrets manager