Docker Security

Docker security is a layered concern: the Docker daemon itself (which runs as root), the container runtime isolation, the container images, and application configuration inside containers. The most dangerous default is that the Docker socket (/var/run/docker.sock) grants root-equivalent access to anyone who can reach it. Understanding and addressing this and other defaults is essential before running Docker on production servers.

Docker attack surface

Docker security risks:
  1. Docker socket (/var/run/docker.sock)
     Mounting this gives container full host control
     → Never mount docker.sock in containers unless absolutely necessary

  2. Running as root inside container
     If container escape occurs, attacker has root on host
     → Use USER directive in Dockerfile, run as non-root

  3. Unpatched base images
     Old Alpine/Ubuntu base images have known CVEs
     → Rebuild images regularly, scan with trivy/grype

  4. Exposed Docker API (port 2375/2376)
     Unauthenticated Docker API = full server compromise
     → Never expose port 2375 publicly

Running containers as non-root

# In Dockerfile — add a non-root user:
FROM ubuntu:22.04
RUN useradd -m -u 1001 appuser
WORKDIR /app
COPY . .
RUN chown -R appuser:appuser /app
USER appuser    # Switch to non-root user
CMD ["./myapp"]

# Run existing image as non-root:
docker run --user 1000:1000 nginx:alpine

# Verify user inside container:
docker exec mycontainer id

docker exec id output

uid=1001(appuser) gid=1001(appuser) groups=1001(appuser)
# Good — not running as root (uid=0)

Resource limits

# Without resource limits, one container can starve all others
# Set CPU and memory limits:
docker run -d   --memory="512m"   --memory-swap="512m"   --cpus="0.5"   --name myapp   myapp:latest

# In docker-compose.yml:
# services:
#   app:
#     deploy:
#       resources:
#         limits:
#           cpus: '0.5'
#           memory: 512M
#         reservations:
#           cpus: '0.25'
#           memory: 256M

# Verify limits are applied:
docker inspect myapp | grep -i "memory\|cpu"

Image security

# Scan images for CVEs with Trivy (excellent free scanner):
sudo apt install -y wget
wget https://github.com/aquasecurity/trivy/releases/latest/download/trivy_*_Linux-64bit.deb
sudo dpkg -i trivy_*_Linux-64bit.deb

# Scan an image:
trivy image nginx:latest

trivy scan output

nginx:latest (debian 12.5)

Total: 78 (UNKNOWN: 0, LOW: 36, MEDIUM: 33, HIGH: 8, CRITICAL: 1)
CRITICAL: CVE-2024-XXXX openssl 3.0.x < 3.0.y...
# Use minimal base images (smaller attack surface):
# Instead of: FROM ubuntu:22.04  (1.4GB)
# Use:        FROM alpine:3.19   (5MB)
# Or:         FROM scratch       (empty, for static binaries)
# Or:         FROM distroless/base (Google's minimal runtime images)

Conclusion

Docker security priority list: (1) never expose the Docker socket to containers that don't need it; (2) run application containers as non-root using the USER directive; (3) set memory and CPU limits on every container to prevent resource exhaustion; (4) scan images with Trivy before pushing to production and rebuild regularly to pick up base image security patches. The Docker socket grants root access — treat mounting it with the same caution as giving root credentials.

FAQ

Is Docker Security important for Ubuntu administrators?+

Yes. It supports practical Ubuntu administration because it connects directly to server reliability, security, troubleshooting, or daily operations.

Should I practice this on a live server?+

Use a lab VM first. After you understand the command output and rollback path, apply the workflow carefully on real systems.

What should I do after reading this article?+

Run the practice commands, write down what each one shows, and continue to the next article in the Ubuntu roadmap.

Need help with Ubuntu administration?

Work directly with Muhammad Irfan Aslam for Ubuntu Server, Linux, cloud, Docker, DevOps, CI/CD, or infrastructure troubleshooting support.

Hire Me for Support