-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcompose.prod.yaml
More file actions
114 lines (107 loc) · 3.35 KB
/
Copy pathcompose.prod.yaml
File metadata and controls
114 lines (107 loc) · 3.35 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
# Production stack for OmniBot.
#
# This file deploys *published* images — it does not build anything, so the
# host needs nothing but Docker, this file and an env file:
#
# cp .env.prod.example .env.prod # then fill it in
# docker compose --env-file .env.prod -f compose.prod.yaml pull
# docker compose --env-file .env.prod -f compose.prod.yaml up -d
#
# Both images track `latest`, so deploying a release is always the same two
# commands and an automated deploy needs no edit on the host. `latest` only ever
# moves to a non-prerelease tag, so publishing a `-rc` does not deploy it.
# To build and run the images locally instead, use `docker build --target
# runtime .` — the CI builds both targets on every pull request.
name: omnibot
x-logging: &default-logging
driver: json-file
options:
max-size: "10m"
max-file: "3"
services:
# PostgreSQL is reachable only from the internal network: no published port.
postgres:
image: postgres:17.11-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:?POSTGRES_USER is required}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
POSTGRES_DB: ${POSTGRES_DB:?POSTGRES_DB is required}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- internal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
security_opt:
- no-new-privileges:true
deploy:
resources:
limits:
cpus: "1.0"
memory: 1g
logging: *default-logging
# One-shot init container: applies the Prisma migration history, then exits.
# It carries the Prisma CLI, which the bot image deliberately does not, and
# it is pinned to the same version as the bot so the schema the migrations
# produce is the one the code expects.
migrate:
image: ghcr.io/gravendev/omnibot-migrator:latest
restart: "no"
environment:
DATABASE_URL: &database_url postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?schema=public
depends_on:
postgres:
condition: service_healthy
networks:
- internal
security_opt:
- no-new-privileges:true
deploy:
resources:
limits:
cpus: "1.0"
memory: 512m
logging: *default-logging
bot:
image: ghcr.io/gravendev/omnibot:latest
restart: unless-stopped
environment:
DISCORD_TOKEN: ${DISCORD_TOKEN:?DISCORD_TOKEN is required}
DATABASE_URL: *database_url
LOG_LEVEL: ${LOG_LEVEL:-info}
depends_on:
postgres:
condition: service_healthy
migrate:
condition: service_completed_successfully
networks:
# `internal` reaches PostgreSQL, `egress` reaches the Discord gateway.
- internal
- egress
read_only: true
tmpfs:
- /tmp
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
# No healthcheck: the bot exposes no HTTP/TCP endpoint — see the
# Deployment section of README.md.
deploy:
resources:
limits:
cpus: "1.0"
memory: 512m
logging: *default-logging
networks:
# No route to the outside world: only the bot bridges the two networks.
internal:
internal: true
egress: {}
volumes:
postgres_data: