Control Resources & Harden Security
By default, a Docker container can consume 100% of your host's CPU and RAM. A single memory leak or infinite loop can hang your entire server. Learn to lock down resources and build layered security to keep your infrastructure bulletproof.
CPU & Memory Limits
Resource control revolves around two critical concepts:
Reservation = A soft promise ("at least this much").
Limit = A hard stop ("never more than this").
terminal
# Memory: Reserve 256MB, Hard Kill at 512MB
$ docker run -d --name web1 \
> --memory-reservation=256m \
> --memory=512m httpd
# CPU: Max 50% of 1 core
$ docker run -d --name web2 --cpus="0.5" httpd
# CPU Shares (Priority)
# Default is 1024. A container with 512 gets half priority.
$ docker run -d --name web3 --cpu-shares=512 httpd
# Prevent Slow Disk Swapping
# Forces the container to ONLY use RAM, no disk swap.
$ docker run -d --memory=512m --memory-swap=512m httpdObservability & Capacity Planning
Live Container Usage
Run docker stats in your terminal. It shows real-time CPU %, Memory usage, Network I/O, and Disk I/O for all running containers.
Inspect Hard Limits
Run docker inspect <container> to verify the exact parameters. Look under the HostConfig block for Memory, CpuQuota, and CpuShares.
Real Planning Example
- Host Specs 4 CPUs and 8 GB RAM.
- OS Overhead Reserve 30% for OS.
Usable CPU ≈ 2.8 | Usable RAM ≈ 5.6 GB - Workload Deploy 4 instances of your app.
Give each--cpus=0.5and--memory=1g. - Result Containers use 2 CPUs and 4 GB RAM total. You have a stable system, room for traffic spikes, and no crashes ✓.
Security Layers & Best Practices
Even with limits, containers can be dangerous if hacked. A bad container can attack neighbors, steal secrets, or escape to the host machine. Security isn't a single switch; it is layered protection.
10 Security Best Practices
- 1 Minimal Base Images: Smaller image = fewer vulnerabilities. (e.g.,
FROM alpine:3.18) - 2 Never Run as Root: Create a dedicated user in the Dockerfile. If hacked, the attacker gets a limited user. (e.g.,
USER appuser) - 3 Keep Images Updated: Old images have known CVEs. Rebuild regularly with
--no-cache. - 4 Multi-Stage Builds: Builder gets the tools; the final image only gets the compiled app. Smaller and safer.
- 5 Drop Capabilities: Remove unnecessary Linux privileges at runtime. (
--cap-drop=ALL) - 6 Prevent Privilege Escalation: Stop attackers from gaining extra rights. (
--security-opt=no-new-privileges) - 7 Resource Limits: Protects against Denial of Service (DoS) attacks.
- 8 Network Hygiene: Expose only required ports. Avoid
--network hostunless absolutely necessary. - 9 Image Scanning: Use tools like Trivy or Clair to scan images before deployment.
- 10 One Process Per Container: Avoid running SSH inside containers or bundling multiple services together.
The Ultimate Secure Run Command
terminal
$ docker run -d --name safe-app \
> --memory=512m --cpus="0.5" \
> --security-opt=no-new-privileges \
> --cap-drop=ALL \
> --read-only \
> --tmpfs /tmp:rw,size=64m \
> myuser/app:1.0Why is this so secure?
1. Limited CPU/RAM stops DoS attacks.
2. no-new-privileges blocks exploits like `sudo`.
3. cap-drop=ALL strips Linux kernel powers.
4. read-only makes the filesystem immutable; hackers can't download malware.
5. tmpfs provides just enough temporary RAM space for the app to write logs, disappearing instantly on exit.