Find us on social media
DockerContainersIsolation5 min read
Docker container security
Non-root containers, read-only filesystems, resource limits, network isolation and image scanning.
Docker security principles
Docker is not secure by default. Follow these practices to reduce risks:
- Never run containers as root
- Don't use
--privilegedunless absolutely necessary - Limit resources (CPU, RAM)
- Isolate networks between containers
- Scan images before using them
Non-root containers
In your Dockerfile:
dockerfile
FROM node:20-alpine
# Create non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --chown=appuser:appgroup . .
# Switch to non-root user
USER appuser
CMD ["node", "server.js"]Read-only filesystem
Run containers with read-only filesystem:
bash
docker run --read-only --tmpfs /tmp --tmpfs /var/run my-appIn docker-compose:
yaml
services:
app:
image: my-app
read_only: true
tmpfs:
- /tmp
- /var/runResource limits
yaml
services:
app:
image: my-app
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.25'
memory: 128MOr with docker run:
bash
docker run --memory=512m --cpus=1.0 my-appNetwork isolation
Create separate networks for each service group:
yaml
services:
app:
networks:
- frontend
- backend
db:
networks:
- backend
nginx:
networks:
- frontend
networks:
frontend:
backend:
internal: true # No internet accessThe database is only accessible from the backend network.
Image scanning with Trivy
bash
# Install Trivy
sudo apt install -y wget
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo 'deb https://aquasecurity.github.io/trivy-repo/deb generic main' | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt update && sudo apt install -y trivy
# Scan an image
trivy image my-app:latest
# Scan only critical vulnerabilities
trivy image --severity CRITICAL my-app:latestIntegrate Trivy in your CI/CD to scan before deploying.
Docker Secrets
Never put passwords in Dockerfile environment variables:
yaml
services:
app:
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txtIn the app, read the secret from /run/secrets/db_password.
Additional best practices
dockerfile
# Use minimal images (alpine)
FROM node:20-alpine
# Don't install unnecessary packages
RUN apk add --no-cache dumb-init
# Use .dockerignore
# Copy only what's needed
COPY package.json package-lock.json ./
RUN npm ci --production
COPY src/ ./src/Recommendations
- Use official and minimal images (alpine)
- Update base images regularly
- Don't expose the Docker socket (
/var/run/docker.sock) - Use Docker Bench Security to audit your installation
- Implement health checks in all containers
- Never store secrets in the image
Was this guide helpful?