-
Notifications
You must be signed in to change notification settings - Fork 170
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
142 lines (126 loc) · 4.89 KB
/
Copy pathdocker-compose.yml
File metadata and controls
142 lines (126 loc) · 4.89 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
# =============================================================================
# SmartNode — docker-compose.yml
#
# Usage:
# docker compose up # foreground, rebuild if Dockerfile changed
# docker compose up -d # detached
# docker compose up --build -d # force rebuild then run detached
# docker compose down # stop and remove containers
#
# # Start with full monitoring stack (Prometheus + Grafana + OTel Collector):
# docker compose --profile monitoring up -d
#
# The service is available at http://localhost:5000/frontend/
# Health endpoint: http://localhost:5000/api/health
# Metrics endpoint: http://localhost:5000/metrics
# Prometheus UI: http://localhost:9090 (monitoring profile)
# Grafana UI: http://localhost:3000 (monitoring profile, admin/admin)
# =============================================================================
services:
smartnode:
build:
context: .
dockerfile: Dockerfile
target: runtime
image: smartnode:latest
container_name: smartnode
restart: unless-stopped
ports:
- "5000:5000"
environment:
# ----------------------------------------------------------------
# Application settings — override here or via a .env file
# ----------------------------------------------------------------
SMARTNODE_ENV: "${SMARTNODE_ENV:-development}"
SMARTNODE_HOST: "0.0.0.0"
SMARTNODE_PORT: "5000"
SMARTNODE_TIME_SCALE: "${SMARTNODE_TIME_SCALE:-10}"
SMARTNODE_LOG_LEVEL: "${SMARTNODE_LOG_LEVEL:-INFO}"
LOG_FORMAT: "${LOG_FORMAT:-json}"
# ----------------------------------------------------------------
# Secrets — always supply real values in production
# ----------------------------------------------------------------
SMARTNODE_JWT_SECRET: "${SMARTNODE_JWT_SECRET:-dev-insecure-secret-change-me}"
SMARTNODE_API_KEY: "${SMARTNODE_API_KEY:-}"
# ----------------------------------------------------------------
# gunicorn tuning
# ----------------------------------------------------------------
GUNICORN_WORKERS: "${GUNICORN_WORKERS:-}"
GUNICORN_TIMEOUT: "${GUNICORN_TIMEOUT:-120}"
GUNICORN_LOG_LEVEL: "${GUNICORN_LOG_LEVEL:-info}"
volumes:
# Mount an optional config file without rebuilding the image.
# Create a local smartnode.json with your overrides, or remove
# this line if you manage all settings via environment variables.
- "./config:/app/config:ro"
healthcheck:
test: ["CMD", "python", "-c",
"import urllib.request; urllib.request.urlopen('http://localhost:5000/api/health')"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
# Run as non-root user (matches Dockerfile UID/GID 1001)
user: "1001:1001"
# Security hardening
security_opt:
- no-new-privileges:true
read_only: false
tmpfs:
- /tmp
# ---------------------------------------------------------------------------
# Monitoring profile — Prometheus + Grafana + OpenTelemetry Collector
# Start with: docker compose --profile monitoring up -d
# ---------------------------------------------------------------------------
prometheus:
image: prom/prometheus:v2.51.2
container_name: smartnode-prometheus
profiles: ["monitoring"]
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention.time=7d"
- "--web.console.libraries=/usr/share/prometheus/console_libraries"
- "--web.console.templates=/usr/share/prometheus/consoles"
- "--web.enable-lifecycle"
depends_on:
- smartnode
grafana:
image: grafana/grafana:10.4.2
container_name: smartnode-grafana
profiles: ["monitoring"]
restart: unless-stopped
ports:
- "3000:3000"
environment:
GF_SECURITY_ADMIN_USER: admin
GF_SECURITY_ADMIN_PASSWORD: admin
GF_USERS_ALLOW_SIGN_UP: "false"
GF_AUTH_ANONYMOUS_ENABLED: "false"
volumes:
- grafana_data:/var/lib/grafana
- ./observability/grafana-provisioning:/etc/grafana/provisioning:ro
depends_on:
- prometheus
otel-collector:
image: otel/opentelemetry-collector-contrib:0.100.0
container_name: smartnode-otel-collector
profiles: ["monitoring"]
restart: unless-stopped
ports:
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
- "8888:8888" # Collector metrics
volumes:
- ./observability/otel-collector.yml:/etc/otelcol-contrib/config.yaml:ro
depends_on:
- prometheus
volumes:
prometheus_data: {}
grafana_data: {}