HOW TO SECURE DOCKER IMAGE??

amit potdar
3 min readNov 23, 2023

--

Securing Docker images is crucial to ensure the safety and integrity of your applications. Here’s a step-by-step guide to securing a Docker image, along with examples of best practices:

source: https://www.linkedin.com/pulse/funniest-docker-cartoons-guaranteed-eric-gold

1. Use Official Base Images:

Always start with official base images from trusted sources like Docker Hub. These images are regularly updated and maintained for security.

Example: Dockerfile

FROM nginx:latest

2. Update System Packages:

Update all system packages in the Dockerfile to patch security vulnerabilities.

Example: Dockerfile

RUN apt-get update && apt-get upgrade -y

3. Reduce Image Size:

Remove unnecessary files and dependencies to minimize the attack surface and reduce the image size.

Example: Dockerfile

RUN apt-get purge -y - auto-remove

4. Use COPY Instead of ADD:

Prefer the `COPY` instruction over `ADD` as it’s more explicit and avoids unexpected behaviors.

Example: Dockerfile

COPY app-files /app

5. Run as a Non-Root User:

Avoid running processes as the root user inside the container. Create a non-root user for running the application.

Example: Dockerfile

RUN useradd -m myuser
USER myuser

6. Use Environment Variables for Secrets:

Avoid hardcoding sensitive information like API keys or database passwords in the Dockerfile. Use environment variables instead.

Example:

ENV API_KEY=mysecretapikey

7. Enable Content Trust:

Enable Docker Content Trust to sign images and verify their signatures before running them.

Example (Command Line):

export DOCKER_CONTENT_TRUST=1
docker build -t myimage:latest .
docker push myimage:latest

8. Regularly Update Base Images:

Regularly update your Docker images and dependencies to patch security vulnerabilities.

Example (Command Line):

docker pull nginx:latest

9. Implement Network Security:

Configure network security policies to control traffic between containers and between containers and the host system.

Example (Docker Compose):

services:
app:
build: {path of dockerfile}
ports:
- "8080:80"
networks:
- mynetwork
networks:
mynetwork:
driver: bridge

10. Scan Images for Vulnerabilities:

Use security scanning tools like Trivy, Clair, or Anchore to scan your images for known vulnerabilities.

Example (Trivy):

trivy myimage:latest

11. Regularly Monitor and Audit Containers:

Implement logging, monitoring, and auditing for your containers to detect and respond to security threats.

12. Use the Latest Docker Version:

Always use the most recent version of Docker to ensure you have the latest security features and bug fixes.

13. Enable Docker Content Trust (DCT):

DCT ensures the integrity and authenticity of Docker images. Enable it globally or per session to verify image signatures.

Example (Command Line):

export DOCKER_CONTENT_TRUST=1

13. Limit Capabilities:

Restrict the capabilities available to containers using ` — cap-drop` and ` — cap-add` options. Limiting capabilities reduces the potential attack surface.

Example (Command Line):

docker run - cap-drop=ALL - cap-add=CHOWN myimage

14. Implement seccomp Profiles:

Use seccomp profiles to restrict system calls available to containers, enhancing security by minimizing the system call surface area.

Example (Docker Compose):

services:
myservice:
security_opt:
- seccomp=path/to/seccomp-profile.json

15. Secure Network Traffic:

Use firewalls, VPNs, or Docker’s network security features to secure network traffic between containers and the host system.

Running Applications as Non-Root User:

Create a Non-Root User in Dockerfile:

In your Dockerfile, create a non-root user and switch to that user for running the application.

Example (Dockerfile):

FROM ubuntu:latest
RUN useradd -ms /bin/bash myuser
USER myuser
WORKDIR /app
COPY . /app
CMD ["./myapp"]

16. Set Proper File Permissions:

Ensure the non-root user has the necessary permissions to access required files and directories within the container.

Example (Dockerfile):

RUN chown -R myuser:myuser /app

17. Drop Privileges in the Application Code:

Within your application code, drop unnecessary privileges after startup. For instance, in a Node.js application, use `process.setuid()` to drop privileges.

Example (Node.js):

const http = require('http');
const process = require('process');
const server = http.createServer((req, res) => {
// Handle requests
});
server.listen(3000, () => {
// Drop privileges after startup
process.setuid('myuser');
console.log('Server is running…');
});

By following these practices, you can secure your Docker environment and run applications with reduced privileges, minimising security risks.

--

--