services: portfolio: build: context: . dockerfile: Dockerfile image: it_portfolio:latest container_name: it_portfolio # ── Networking ────────────────────────────────────────────────────────── ports: - "8080:8080" # ── Resource limits (near-zero footprint for a static site) ───────────── deploy: resources: limits: cpus: "0.10" # 10 % of one core at most memory: 32M reservations: cpus: "0.01" memory: 8M # ── Hardening ─────────────────────────────────────────────────────────── read_only: true # container filesystem is immutable tmpfs: # /tmp is the only writable path nginx needs - /tmp:size=16m,mode=1777 security_opt: - no-new-privileges:true # prevent privilege escalation via setuid cap_drop: - ALL # drop every Linux capability… # (no cap_add needed — port 8080 > 1024, user nginx, no raw sockets) # ── Lifecycle ─────────────────────────────────────────────────────────── restart: unless-stopped healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:8080/"] interval: 30s timeout: 5s retries: 3 start_period: 5s # ── Observability ─────────────────────────────────────────────────────── logging: driver: json-file options: max-size: "5m" max-file: "3"