Skip to content

Commit 60b2158

Browse files
committed
feat: Add initial Coolify Docker Compose setup
1 parent 7959566 commit 60b2158

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed

docker-compose.coolify.yml

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
services:
2+
# Sources Generator - Generates sources.yml files from instances.yaml template
3+
sources-generator:
4+
image: alpine:3.22.0
5+
container_name: sources-generator
6+
working_dir: /app
7+
volumes:
8+
- ./instances.yml:/app/instances.yaml
9+
- ./config:/app/config
10+
command: >
11+
sh -c "
12+
mkdir -p /app/config/pgwatch-postgres /app/config/pgwatch-prometheus &&
13+
echo '# PGWatch Sources Configuration - PostgreSQL Instance' > /app/config/pgwatch-postgres/sources.yml &&
14+
sed 's/~sink_type~/postgresql/g' /app/instances.yaml >> /app/config/pgwatch-postgres/sources.yml &&
15+
echo '# PGWatch Sources Configuration - Prometheus Instance' > /app/config/pgwatch-prometheus/sources.yml &&
16+
echo '' >> /app/config/pgwatch-prometheus/sources.yml &&
17+
sed 's/~sink_type~/prometheus/g' /app/instances.yaml >> /app/config/pgwatch-prometheus/sources.yml &&
18+
echo 'Generated sources.yml files for both postgres and prometheus'
19+
"
20+
21+
# Target Database - The PostgreSQL database being monitored
22+
target-db:
23+
image: postgres:15
24+
container_name: target-db
25+
environment:
26+
POSTGRES_DB: target_database
27+
POSTGRES_USER: postgres
28+
POSTGRES_PASSWORD: postgres
29+
command:
30+
[
31+
"postgres",
32+
"-c",
33+
"shared_preload_libraries=pg_stat_statements",
34+
"-c",
35+
"pg_stat_statements.track=all",
36+
]
37+
ports:
38+
- "55432:5432"
39+
volumes:
40+
- target_db_data:/var/lib/postgresql/data
41+
- ./config/target-db/init.sql:/docker-entrypoint-initdb.d/init.sql
42+
43+
# Postgres Sink - Storage for metrics in PostgreSQL format
44+
sink-postgres:
45+
image: postgres:15
46+
container_name: sink-postgres
47+
environment:
48+
POSTGRES_DB: postgres
49+
POSTGRES_USER: postgres
50+
POSTGRES_PASSWORD: postgres
51+
ports:
52+
- "55433:5432"
53+
volumes:
54+
- sink_postgres_data:/var/lib/postgresql/data
55+
- ./config/sink-postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
56+
57+
# Prometheus Sink - Storage for metrics in Prometheus format
58+
sink-prometheus:
59+
image: prom/prometheus:v3.4.2
60+
container_name: sink-prometheus
61+
ports:
62+
- "59090:9090"
63+
volumes:
64+
- ./config/prometheus:/etc/prometheus
65+
- prometheus_data:/prometheus
66+
command:
67+
- "--config.file=/etc/prometheus/prometheus.yml"
68+
- "--storage.tsdb.path=/prometheus"
69+
- "--web.console.libraries=/etc/prometheus/console_libraries"
70+
- "--web.console.templates=/etc/prometheus/consoles"
71+
- "--storage.tsdb.retention.time=200h"
72+
- "--web.enable-lifecycle"
73+
74+
# PGWatch Instance 1 - Monitoring service (Postgres sink)
75+
pgwatch-postgres:
76+
image: cybertecpostgresql/pgwatch:3
77+
container_name: pgwatch-postgres
78+
command:
79+
[
80+
"--sources=/etc/pgwatch/sources.yml",
81+
"--metrics=/etc/pgwatch/metrics.yml",
82+
"--sink=postgresql://pgwatch:pgwatchadmin@sink-postgres:5432/measurements",
83+
"--web-addr=:8080",
84+
]
85+
ports:
86+
- "58080:8080"
87+
depends_on:
88+
- sources-generator
89+
- sink-postgres
90+
volumes:
91+
- ./config/pgwatch-postgres/sources.yml:/etc/pgwatch/sources.yml
92+
- ./config/pgwatch-postgres/metrics.yml:/etc/pgwatch/metrics.yml
93+
94+
# PGWatch Instance 2 - Monitoring service (Prometheus sink)
95+
pgwatch-prometheus:
96+
image: cybertecpostgresql/pgwatch:3
97+
container_name: pgwatch-prometheus
98+
command:
99+
[
100+
"--sources=/etc/pgwatch/sources.yml",
101+
"--metrics=/etc/pgwatch/metrics.yml",
102+
"--sink=prometheus://0.0.0.0:9091/pgwatch",
103+
"--web-addr=:8089",
104+
]
105+
ports:
106+
- "58089:8089"
107+
- "59091:9091"
108+
depends_on:
109+
- sources-generator
110+
- sink-prometheus
111+
volumes:
112+
- ./config/pgwatch-prometheus/sources.yml:/etc/pgwatch/sources.yml
113+
- ./config/pgwatch-prometheus/metrics.yml:/etc/pgwatch/metrics.yml
114+
115+
# Grafana with datasources - Visualization layer
116+
grafana:
117+
image: grafana/grafana:12.0.2
118+
container_name: grafana-with-datasources
119+
environment:
120+
GF_SECURITY_ADMIN_USER: monitor
121+
GF_SECURITY_ADMIN_PASSWORD: demo
122+
GF_INSTALL_PLUGINS: yesoreyeram-infinity-datasource
123+
ports:
124+
- "3000:3000"
125+
volumes:
126+
- grafana_data:/var/lib/grafana
127+
- ./config/grafana/provisioning:/etc/grafana/provisioning
128+
- ./config/grafana/dashboards:/var/lib/grafana/dashboards
129+
depends_on:
130+
- sink-postgres
131+
- sink-prometheus
132+
flask-backend:
133+
build:
134+
context: ./flask-backend
135+
dockerfile: Dockerfile
136+
container_name: flask-pgss-api
137+
environment:
138+
- FLASK_ENV=production
139+
- PROMETHEUS_URL=http://sink-prometheus:9090
140+
depends_on:
141+
- sink-prometheus
142+
ports:
143+
- "55000:5000"
144+
145+
# PostgreSQL Reports Generator - Runs reports after 1 hour
146+
postgres-reports:
147+
image: python:3.11-slim
148+
container_name: postgres-reports
149+
working_dir: /app
150+
volumes:
151+
- ./reporter/postgres_reports.py:/app/postgres_reports.py
152+
- ./reporter/requirements.txt:/app/requirements.txt
153+
- ./.pgwatch-config:/app/.pgwatch-config
154+
- ./instances.yml:/app/instances.yml
155+
environment:
156+
- PROMETHEUS_URL=http://sink-prometheus:9090
157+
depends_on:
158+
- sink-prometheus
159+
- pgwatch-prometheus
160+
command: >
161+
sh -c "
162+
echo 'Installing Python dependencies...' &&
163+
pip install -r requirements.txt &&
164+
pip install pyyaml &&
165+
echo 'Waiting 30 minutes before generating reports...' &&
166+
sleep 1800 &&
167+
echo 'Starting PostgreSQL reports generation...' &&
168+
while true; do
169+
echo 'Extracting cluster and node name from instances.yml...' &&
170+
CLUSTER=$$(python3 -c \"import yaml; data=yaml.safe_load(open('instances.yml')); print(data[0]['custom_tags']['cluster'])\") &&
171+
NODE_NAME=$$(python3 -c \"import yaml; data=yaml.safe_load(open('instances.yml')); print(data[0]['custom_tags']['node_name'])\") &&
172+
echo \"Using cluster: $$CLUSTER, node: $$NODE_NAME\" &&
173+
echo 'Generating PostgreSQL reports...' &&
174+
if [ -f /app/.pgwatch-config ] && grep -q '^api_key=' /app/.pgwatch-config; then
175+
API_KEY=$$(grep '^api_key=' /app/.pgwatch-config | cut -d'=' -f2-) &&
176+
python postgres_reports.py --prometheus-url http://sink-prometheus:9090 --cluster \"$$CLUSTER\" --node-name \"$$NODE_NAME\" --output /app/all_reports_$$(date +%Y%m%d_%H%M%S).json --token $$API_KEY --project postgres-ai-monitoring
177+
else
178+
echo 'No API key configured, generating reports without upload...' &&
179+
python postgres_reports.py --prometheus-url http://sink-prometheus:9090 --cluster \"$$CLUSTER\" --node-name \"$$NODE_NAME\" --output /app/all_reports_$$(date +%Y%m%d_%H%M%S).json --no-upload
180+
fi &&
181+
echo 'Reports generated. Sleeping for 24 hours...' &&
182+
sleep 86400
183+
done
184+
"
185+
186+
volumes:
187+
target_db_data:
188+
sink_postgres_data:
189+
prometheus_data:
190+
grafana_data:

0 commit comments

Comments
 (0)