105 lines
4.3 KiB
YAML
105 lines
4.3 KiB
YAML
# =============================================================================
|
|||
|
|
# 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"
|