← All tutorials

Cloud

How to Deploy a Hardened Nginx Container with Docker Compose

Published October 27, 2026 · 6 min read

On this page
  1. Prerequisites
  2. Step-by-Step Guide
  3. Conclusion

Containers make deployments repeatable, but default settings expose more than necessary. This guide serves a static site with Nginx using Docker Compose, with read-only content, a localhost-only port, health monitoring and automatic restarts.

Prerequisites

Step-by-Step Guide

Step 1: Create the project

mkdir -p ~/webapp/site
cd ~/webapp
cat > site/index.html <<'EOF'
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><title>Hello</title></head>
<body><h1>Served by Nginx in Docker</h1></body></html>
EOF

Step 2: Write compose.yaml

services:
  web:
    image: nginx:1.27-alpine
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - ./site:/usr/share/nginx/html:ro
    security_opt:
      - no-new-privileges:true
    healthcheck:
      test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1/"]
      interval: 30s
      timeout: 5s
      retries: 3
    restart: unless-stopped

Step 3: Start and verify

docker compose up -d
docker compose ps
curl -I http://127.0.0.1:8080

You should see HTTP/1.1 200 OK, and the service should report healthy after a short delay.

Step 4: Read logs and update

docker compose logs --tail 50 web
docker compose pull
docker compose up -d

Conclusion

You have a reproducible web container that is not directly reachable from the internet. Update pinned image versions regularly, scan images for known vulnerabilities, remove unused images with docker image prune and put TLS termination in front of the service.

Keep reading