-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
213 lines (207 loc) · 7.99 KB
/
Copy pathdocker-compose.yml
File metadata and controls
213 lines (207 loc) · 7.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
APP_VERSION: "${APP_VERSION:-8.21.4}"
image: docker-dash:${APP_VERSION:-8.21.4}
container_name: docker-dash
restart: unless-stopped
env_file:
- .env
ports:
- "${APP_PORT:-8101}:${APP_PORT:-8101}"
volumes:
# Container runtime socket — read-only for security
# Docker: /var/run/docker.sock (default)
# Podman: /run/podman/podman.sock (set DOCKER_SOCKET in .env)
- ${DOCKER_SOCKET:-/var/run/docker.sock}:/var/run/docker.sock:ro
# Persistent data (SQLite DB, stats)
- docker-dash-data:/data
# Shared certs dir — Caddyfile written here by the app, read by Caddy
- caddy-certs:/data/certs
# Shared policy.json dir for the v6.7 egress filter sidecar (if running)
- egress-policy:/data/egress-policy
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:${APP_PORT:-8101}/api/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
# Security: no privilege escalation, but needs docker socket
security_opt:
- no-new-privileges:true
# Optional Outbound Network Filter sidecar (v6.7+) — enable with:
# docker compose --profile egress up -d
# Configure via Docker Dash UI: System → Egress → per-row "Enable filter"
#
# Before starting: set these envs on the `app` service (via .env):
# DD_EGRESS_SIDECAR_ENDPOINT=dd-egress-filter:29193
# DD_EGRESS_SIDECAR_NAME=dd-egress-filter
# DD_EGRESS_BLOCKLOG_INGESTER=1
#
# The sidecar peeks TLS SNI + HTTP Host on every connection, compares to
# the policy allowlist (written by Docker Dash into /etc/dd-egress/policy.json
# via the shared egress-policy volume), and forwards or resets. IMDS is
# always blocked. No TLS decryption.
dd-egress-filter:
build:
context: ./docker/egress-filter
image: docker-dash-egress-filter:${APP_VERSION:-8.21.4}
container_name: dd-egress-filter
restart: unless-stopped
# Uses the default bridge so target containers on the default bridge can
# reach it via 172.17.0.X without extra network plumbing. For user-defined
# bridges or Swarm overlays, attach the sidecar to those networks manually
# (or run one sidecar per network) — see docs/planning/v6.7/.../README.md.
network_mode: bridge
volumes:
- egress-policy:/etc/dd-egress:ro
- egress-logs:/var/log/dd-egress
environment:
DD_EGRESS_LISTEN: ":29193"
DD_EGRESS_POLICY_PATH: /etc/dd-egress/policy.json
DD_EGRESS_BLOCKLOG_PATH: /var/log/dd-egress/denied.log
DD_EGRESS_METRICS_LISTEN: ":9191"
# Deliberately NO `ports:` here — sidecar must not be exposed to the host
# (preflight P4 validated). Traffic reaches it via iptables redirect from
# within filtered containers' netns.
security_opt:
- no-new-privileges:true
profiles:
- egress
# Optional Redis for HA mode — enable with: docker compose --profile ha up -d
# Then on the `app` service (via .env):
# DD_MODE=ha
# REDIS_URL=redis://redis:6379
#
# v7.2.0 ships the foundation (Redis-backed rate limiter + cluster abstraction).
# DO NOT run multi-replica in HA mode yet — WS pub/sub + cron leader election
# land in v7.2.0-alpha.1 / v7.2.0-rc.1. Running v7.2.0 HA with 2+ replicas
# causes duplicate cron execution (duplicate backups, concurrent VACUUM).
#
# Single-instance HA (1 replica + Redis) is useful for warming up operational
# tooling (Prometheus scrape of Redis, sticky-session LB config drill, etc.)
# before rolling out true multi-replica in v7.2.0.
redis:
image: redis:7-alpine
container_name: docker-dash-redis
restart: unless-stopped
command: redis-server --save 60 1000 --maxmemory 128mb --maxmemory-policy allkeys-lru
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
security_opt:
- no-new-privileges:true
profiles:
- ha
# Optional observability stack (v7.2.0) — enable with:
# docker compose --profile observability up -d
#
# Ships Prometheus (scrape /api/metrics every 15s) + Grafana (auto-provisioned
# datasource + "Docker Dash — Overview" dashboard). Works in BOTH standalone
# and HA mode — the dashboard panels gate HA-only metrics (cluster role,
# Redis connected) via value mappings.
#
# Grafana default: admin / admin (forced change on first login).
# Grafana exposed on :${GRAFANA_PORT:-3001}; Prometheus NOT exposed externally.
# See docs/features/observability.md for hardening + integration with
# existing Prometheus / Grafana installs.
prometheus:
image: prom/prometheus:v3.0.1
container_name: docker-dash-prometheus
restart: unless-stopped
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
- --storage.tsdb.retention.time=7d
- --web.enable-lifecycle
volumes:
- ./docker/observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro
# v7.6.0 — bind alert rules dir so prometheus.yml `rule_files: alerts/*.yml` resolves
- ./docker/observability/alerts:/etc/prometheus/alerts:ro
- prometheus-data:/prometheus
# Not exposed to host by default — Grafana reaches it on the internal
# network. Uncomment to expose for external scraping.
# ports:
# - "${PROMETHEUS_PORT:-9091}:9090"
security_opt:
- no-new-privileges:true
profiles:
- observability
grafana:
image: grafana/grafana:11.3.0
container_name: docker-dash-grafana
restart: unless-stopped
ports:
- "${GRAFANA_PORT:-3001}:3000"
volumes:
- ./docker/observability/grafana/provisioning:/etc/grafana/provisioning:ro
- ./docker/observability/grafana/dashboards:/etc/grafana/dashboards:ro
- grafana-data:/var/lib/grafana
environment:
# Default admin / admin — Grafana FORCES change on first login.
# For automated provisioning, set GF_SECURITY_ADMIN_PASSWORD in .env
# so the first-login password change is pre-applied.
- GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER:-admin}
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin}
# Disable anonymous access — operators must log in. Flip to true +
# set Viewer role if you want the dashboard publicly visible.
- GF_AUTH_ANONYMOUS_ENABLED=false
# Disable user sign-up / email invites on this self-hosted install.
- GF_USERS_ALLOW_SIGN_UP=false
- GF_USERS_ALLOW_ORG_CREATE=false
depends_on:
- prometheus
security_opt:
- no-new-privileges:true
profiles:
- observability
# Optional HTTPS reverse proxy — enable with: docker compose --profile tls up -d
# Configure via Docker Dash UI: System → SSL/TLS → Enable HTTPS
caddy:
image: caddy:2-alpine
container_name: docker-dash-caddy
restart: unless-stopped
ports:
- "${TLS_PORT:-8443}:443"
- "${HTTP_REDIRECT_PORT:-80}:80"
volumes:
# Shared volume — Caddyfile written by app, reloaded automatically
- caddy-certs:/data/certs:ro
- caddy-data:/data
- caddy-config:/config
# Bootstrap Caddyfile — used when no Caddyfile has been configured yet
- ./caddy-bootstrap:/bootstrap:ro
command: sh -c '[ -f /data/certs/Caddyfile ] || cp /bootstrap/Caddyfile.default /data/certs/Caddyfile; exec caddy run --config /data/certs/Caddyfile --adapter caddyfile'
depends_on:
- app
profiles:
- tls
volumes:
docker-dash-data:
name: docker-dash-data
caddy-certs:
name: docker-dash-caddy-certs
caddy-data:
caddy-config:
egress-policy:
name: docker-dash-egress-policy
egress-logs:
name: docker-dash-egress-logs
redis-data:
name: docker-dash-redis-data
prometheus-data:
name: docker-dash-prometheus-data
grafana-data:
name: docker-dash-grafana-data