-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdocker-compose.local.yml
More file actions
283 lines (271 loc) · 10.7 KB
/
Copy pathdocker-compose.local.yml
File metadata and controls
283 lines (271 loc) · 10.7 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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# TIP Protocol: Local 3-Node Dev Setup (the genesis founding committee)
#
# ── Selecting a database engine ──────────────────────────────────────────────
# All DB connection vars are read from the project-root .env file.
# Set these in .env (or export them) to switch engines; no compose edits needed.
#
# Default (postgres), no flags needed:
# docker compose -f docker-compose.local.yml up -d
#
# The SAME node1/node2/node3 services connect to whichever engine .env names;
# there are no per-engine node copies. Point them elsewhere, start that engine's
# profile so its DB container comes up, then bring up the nodes.
#
# MariaDB:
# Set in .env: DB_DRIVER=mariadb DB_HOST=mariadb
# Then: docker compose -f docker-compose.local.yml --profile mariadb up -d
#
# SQL Server:
# Set in .env: DB_DRIVER=mssql DB_HOST=tip-mssql DB_PORT=1433 DB_USER=sa
# Then: docker compose -f docker-compose.local.yml --profile mssql up -d
#
# Oracle (needs `npm install oracledb`, not bundled, large native binary):
# Set in .env: DB_DRIVER=oracle DB_HOST=oracle DB_PORT=1521
# Then: docker compose -f docker-compose.local.yml --profile oracle up -d
#
# SQLite (no DB service):
# Set in .env: DB_DRIVER=sqlite
# Then: docker compose -f docker-compose.local.yml up -d
# (Postgres starts but is idle; nodes fall back to SQLite via initDAGAsync)
#
# ── Node fixed IPs ───────────────────────────────────────────────────────────
# Only the nodes pin an IP; peers dial these exact addresses (TIP_PUBLIC_IP +
# the /ip4/.../p2p/ bootstrap multiaddr in each node env file). Every other
# service (postgres, DBs, prometheus, grafana) is reached by compose service
# name over DNS, so they take auto-assigned IPs.
# node1 -> 172.30.0.10 (API :4000, P2P :4001) founding / seed node
# node2 -> 172.30.0.11 (API :4100, P2P :4101)
# node3 -> 172.30.0.12 (API :4200, P2P :4201)
services:
# ── PostgreSQL (always starts, default DB) ──────────────────────────────────
# To use a different engine, set DB_DRIVER + DB_HOST in .env.
# Postgres will still start but remain idle while nodes connect elsewhere.
postgres:
image: postgres:16-alpine
container_name: tip-postgres
restart: unless-stopped
ports:
- "5432:5432"
environment:
POSTGRES_USER: ${DB_USER:-tipuser}
POSTGRES_PASSWORD: ${DB_PASSWORD:-Tip_Password_2025}
POSTGRES_DB: postgres
volumes:
- ./scripts/postgres-init.sql:/docker-entrypoint-initdb.d/01-init.sql:ro
- tip-postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "${DB_USER:-tip}"]
interval: 5s
timeout: 3s
retries: 10
start_period: 10s
networks:
- tip-local
# ── MariaDB (profile: mariadb) ───────────────────────────────────────────────
# Activate with --profile mariadb and set DB_DRIVER=mariadb DB_HOST=mariadb in .env
mariadb:
profiles: ["mariadb"]
image: mariadb:lts
container_name: tip-mariadb
restart: unless-stopped
ports:
- "3306:3306"
environment:
MARIADB_ROOT_PASSWORD: ${DB_PASSWORD:-Tip_Password_2025}
MARIADB_USER: ${DB_USER:-tipuser}
MARIADB_PASSWORD: ${DB_PASSWORD:-Tip_Password_2025}
MARIADB_DATABASE: ${DB_NAME:-tip_node1}
volumes:
- ./scripts/mariadb-init.sql:/docker-entrypoint-initdb.d/01-init.sql:ro
- tip-mariadb-data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 5s
timeout: 3s
retries: 12
start_period: 20s
networks:
- tip-local
# ── SQL Server 2022 (profile: mssql) ────────────────────────────────────────
# Activate with --profile mssql and set in .env:
# DB_DRIVER=mssql DB_HOST=tip-mssql DB_PORT=1433 DB_USER=sa
# DB_PASSWORD must meet SQL Server complexity (uppercase + digit + symbol).
# Init SQL runs automatically on first start via the entrypoint wrapper.
mssql:
profiles: ["mssql"]
image: mcr.microsoft.com/mssql/server:2022-latest
container_name: tip-mssql
restart: unless-stopped
ports:
- "1433:1433"
environment:
ACCEPT_EULA: "Y"
MSSQL_SA_PASSWORD: ${DB_PASSWORD:-Tip_Password_2025}
MSSQL_PID: Developer
volumes:
- ./scripts/mssql-init.sql:/scripts/init.sql:ro
- ./scripts/mssql-entrypoint.sh:/scripts/entrypoint.sh:ro
- tip-mssql-data:/var/opt/mssql
entrypoint: ["/bin/bash", "/scripts/entrypoint.sh"]
healthcheck:
test: ["CMD", "/opt/mssql-tools18/bin/sqlcmd", "-S", "localhost",
"-U", "sa", "-P", "${DB_PASSWORD:-Tip_Password_2025}", "-No", "-Q", "SELECT 1"]
interval: 10s
timeout: 5s
retries: 18
start_period: 30s
networks:
- tip-local
# ── Oracle Free 23ai (profile: oracle) ──────────────────────────────────────
# First start takes 2-3 min; wait for healthy before the nodes connect.
# APP_USER (tip) is created in FREEPDB1 with CONNECT + RESOURCE + UNLIMITED TABLESPACE.
oracle:
profiles: ["oracle"]
image: gvenzl/oracle-free:latest
container_name: tip-oracle
restart: unless-stopped
ports:
- "1521:1521"
environment:
ORACLE_PASSWORD: ${DB_PASSWORD:-Tip_Password_2025}
APP_USER: ${DB_USER:-tipuser}
APP_USER_PASSWORD: ${DB_PASSWORD:-Tip_Password_2025}
volumes:
- tip-oracle-data:/opt/oracle/oradata
- ./scripts/oracle-init.sh:/container-entrypoint-initdb.d/01-tip-nodes.sh:ro
healthcheck:
test: ["CMD", "healthcheck.sh"]
interval: 10s
timeout: 5s
retries: 30
start_period: 180s
networks:
- tip-local
# ── Node 1 - founding / seed node ────────────────────────────────────────────
node1:
build:
context: .
dockerfile: Dockerfile
target: runtime
image: tip-protocol/node:2.0.0
container_name: tip-node1
restart: unless-stopped
ports:
- "4000:4000" # REST API
- "4001:4001" # libp2p P2P
volumes:
- ./data:/app/data
- ./node/logs/node1:/app/node/logs
# Read-only key source: node reads its .tip.json via TIP_NODE_CREDENTIALS_FILE.
# In prod this is an orchestrator-injected secret, not a bind mount.
- ./genesis-data/backups:/app/genesis-data/backups:ro
# All config (identity, IP, DB, ports, log/verify) comes from the env_file.
env_file: .env
# Reach shared-postgres on the host (DB_HOST=host.docker.internal in the env_file).
extra_hosts: ["host.docker.internal:host-gateway"]
depends_on:
postgres:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:$${PORT:-4000}/health || exit 1"]
interval: 10s
timeout: 5s
retries: 6
start_period: 20s
networks:
tip-local:
ipv4_address: 172.30.0.10
# ── Node 2 ───────────────────────────────────────────────────────────────────
node2:
image: tip-protocol/node:2.0.0
container_name: tip-node2
restart: unless-stopped
ports:
- "4100:4100"
- "4101:4101"
volumes:
- ./node2-env/data:/app/data
- ./node/logs/node2:/app/node/logs
- ./genesis-data/backups:/app/genesis-data/backups:ro
# All config comes from the env_file.
env_file: ./node2-env/node-2.env
extra_hosts: ["host.docker.internal:host-gateway"]
depends_on:
node1:
condition: service_started
networks:
tip-local:
ipv4_address: 172.30.0.11
# ── Node 3 ───────────────────────────────────────────────────────────────────
node3:
image: tip-protocol/node:2.0.0
container_name: tip-node3
restart: unless-stopped
ports:
- "4200:4200"
- "4201:4201"
volumes:
- ./node3-env/data:/app/data
- ./node/logs/node3:/app/node/logs
- ./genesis-data/backups:/app/genesis-data/backups:ro
# All config comes from the env_file.
env_file: ./node3-env/node-3.env
extra_hosts: ["host.docker.internal:host-gateway"]
depends_on:
node1:
condition: service_started
networks:
tip-local:
ipv4_address: 172.30.0.12
# ── Prometheus (profile: observability) ─────────────────────────────────────
prometheus:
profiles: ["observability"]
image: prom/prometheus:v2.55.0
container_name: tip-prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./infra/observability/prometheus-local.yml:/etc/prometheus/prometheus.yml:ro
- tip-prometheus-data:/prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--web.console.libraries=/etc/prometheus/console_libraries"
- "--web.console.templates=/etc/prometheus/consoles"
networks:
- tip-local
# ── Grafana (profile: observability) ────────────────────────────────────────
grafana:
profiles: ["observability"]
image: grafana/grafana:11.3.0
container_name: tip-grafana
restart: unless-stopped
ports:
- "3030:3000"
environment:
GF_SERVER_HTTP_PORT: "3000"
GF_SECURITY_ADMIN_PASSWORD: admin
GF_USERS_ALLOW_SIGN_UP: "false"
GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH: /var/lib/grafana/dashboards/tip-home.json
volumes:
- ./infra/observability/grafana/provisioning:/etc/grafana/provisioning:ro
- ./infra/observability/grafana/dashboards:/var/lib/grafana/dashboards:ro
- tip-grafana-data:/var/lib/grafana
depends_on:
- prometheus
networks:
- tip-local
volumes:
tip-postgres-data:
tip-mariadb-data:
tip-mssql-data:
tip-oracle-data:
tip-prometheus-data:
tip-grafana-data:
networks:
tip-local:
driver: bridge
ipam:
config:
- subnet: 172.30.0.0/24