Files

105 lines
4.3 KiB
YAML
Raw Permalink Normal View History

2026-10-09 02:48:31 +07:00
# =============================================================================
# docker-socket-proxy + gateway nginx (api-key) — per host SiCABE.
#
# Control-panel (sicabe-control-panel) TIDAK pernah menyentuh /var/run/docker.sock
# langsung. Di setiap host yang dikelola dipasang stack ini; panel berbicara ke
# endpoint HTTP gateway (lihat desain:
# docs/desain-kontrol-multi-host-docker-socket-proxy.md).
#
# Arsitektur:
# panel ──HTTP + X-Api-Key──► gateway (nginx, allowlist path)
# └──► docker-proxy (docker-socket-proxy, ACL)
# └──► /var/run/docker.sock (:ro)
#
# Keamanan (jangan longgarkan tanpa kebutuhan):
# * Socket daemon di-mount READ-ONLY (:ro).
# * docker-socket-proxy TIDAK punya auth — container tsb HANYA di jaringan
# internal compose (expose, tanpa port host). Yang diekspos ke host hanyalah
# gateway nginx.
# * nginx memeriksa header `X-Api-Key` (wajib sama dengan PROXY_API_KEY) dan
# allowlist path (hanya route yang dibutuhkan kontrol, sisanya 403).
# * ACL docker-socket-proxy hanya mengizinkan yang dibutuhkan:
# CONTAINERS (list/inspect/restart/stop/start/logs/top), POST (restart),
# INFO (version/ping), SYSTEM (/events).
# Kategori lain (EXEC, BUILD, IMAGES, NETWORKS, VOLUMES, ...) DIMATIKAN.
# * Versi image DIPATOK (bukan :latest) untuk produksi.
#
# Mode alternatif SSH-tunnel / single-host (tanpa api-key):
# Hapus/komentari service `gateway`, lalu pada service `docker-proxy` ganti
# `expose` dengan port publik:
# ports:
# - "127.0.0.1:${PROXY_PORT:-22375}:2375"
#
# Cara pakai (HTTP + api-key):
# PROXY_API_KEY='<secret-acak-kuat>' PROXY_BIND_IP=127.0.0.1 PROXY_PORT=22375 \
# docker compose up -d
# - PROXY_API_KEY WAJIB diisi (compose akan error bila kosong). Ini secret —
# jangan di-commit; isi via env/deploy.
# - PROXY_BIND_IP: 127.0.0.1 utk single-host/SSH-tunnel; IP internal host bila
# panel di host lain dalam network tepercaya. JANGAN expose ke internet.
# - Panel: SICABE_HOSTS=[{"name":"...","proxyUrl":"http://<bind-ip>:<port>",
# "apiKey":"<PROXY_API_KEY>","enabled":true}]
# =============================================================================
name: sicabe-docker-proxy
services:
# --- docker-socket-proxy: ACL, hanya di jaringan internal compose ---------
docker-proxy:
image: tecnativa/docker-socket-proxy:v0.5.0
container_name: sicabe-docker-proxy
environment:
# --- ACL: hanya yang dibutuhkan kontrol ---
CONTAINERS: "1" # list/inspect/restart/stop/start/logs/top
POST: "1" # dibutuhkan utk restart/start/stop
INFO: "1" # info daemon (version, /_ping, healthcheck)
SYSTEM: "1" # /events (feed Observability). Set "0" bila tak dipakai
# --- matikan semua yang tidak perlu ---
EXEC: "0"
SWARM: "0"
SERVICES: "0"
SECRETS: "0"
CONFIGS: "0"
NETWORKS: "0"
VOLUMES: "0"
IMAGES: "0"
BUILD: "0"
GRPC: "0"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
expose:
- "2375" # hanya reachable dari gateway (network compose)
read_only: true
tmpfs:
- /tmp
- /run # HAProxy menulis pidfile /run/haproxy.pid
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
# --- gateway nginx: api-key + allowlist path (satu-satunya port ke host) --
gateway:
image: nginx:1.30.4-alpine3.24
container_name: sicabe-docker-proxy-gateway
depends_on:
- docker-proxy
environment:
# WAJIB: compose error bila PROXY_API_KEY tidak di-set.
PROXY_API_KEY: ${PROXY_API_KEY:?PROXY_API_KEY wajib diisi (secret acak kuat)}
ports:
- "${PROXY_BIND_IP:-127.0.0.1}:${PROXY_PORT:-22375}:80"
volumes:
# Template di-substitute oleh envsubst docker-entrypoint nginx saat start
# (${PROXY_API_KEY} diganti nilai env; $http_* tetap utuh) → output ke
# /etc/nginx/conf.d/default.conf (menggantikan default bawaan image).
- ./nginx/gateway.conf.template:/etc/nginx/templates/default.conf.template:ro
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"