๐ Security Best Practices โ
1. Don't Run Containers as Root โ
By default, containers run as root. If your application has a vulnerability, an attacker gains root access directly โ essentially handing over the admin key.
dockerfile
# Create a non-root user in the Dockerfile
FROM node:18-slim
# Create the application user
RUN groupadd -r appuser && useradd -r -g appuser appuser
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
# Switch to the non-root user
USER appuser
CMD ["node", "server.js"]bash
# You can also specify a user at runtime
docker run -d --user 1000:1000 myapp
# Check which user a container is running as
docker inspect --format='{{.Config.User}}' myapp
appuser2. Read-Only File System โ
bash
# Set the container's file system to read-only (prevents tampering)
docker run -d --read-only --tmpfs /tmp --tmpfs /var/run myapp
# /tmp and /var/run use tmpfs (in-memory); mount directories the app needs to write to as volumes
# How to do this in docker-compose.yml
cat > docker-compose.yml << 'EOF'
services:
web:
image: nginx:alpine
read_only: true
tmpfs:
- /tmp
- /var/cache/nginx
- /var/run
EOF3. Don't Mount the Docker Socket โ
-v /var/run/docker.sock:/var/run/docker.sock seems convenient (you can manage Docker from inside a container), but it effectively grants the container root-level access to the host โ an attacker can use Docker to create privileged containers and escape directly to the host machine.
๐ก Tip: ๐ก Exception: CI/CD tools (like Jenkins) and certain orchestration tools need the Docker socket, but it should be restricted to read-only (:ro), and Docker-in-Docker (DinD) or rootless Docker should be used as alternatives.
4. Image Security Scanning โ
bash
# Scan an image for vulnerabilities using Docker Scout (built into Docker Desktop)
docker scout cves myapp:latest
# Scan using Trivy (open source, recommended)
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image myapp:latest
# Example scan output:
# myapp:latest (debian 12.4)
# Total: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 1, HIGH: 1, CRITICAL: 0)
#
# โโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโ
# โ Library โ Vulnerability โ Severity โ Fixed Version โ
# โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโค
# โ openssl โ CVE-2024-xxx โ HIGH โ 3.0.13-1~deb12u1 โ
# โโโโโโโโโโโโโโดโโโโโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโ
# Integrate scanning into CI/CD (block builds on high/critical vulnerabilities)
trivy image --exit-code 1 --severity HIGH,CRITICAL myapp:latest