CI / ci (push) Canceled after 0s
Removed dockge from the app as it is not required due to the manager page picking up most of its abilities.
113 lines
5.0 KiB
YAML
113 lines
5.0 KiB
YAML
name: next-chair-infra
|
|
|
|
# Shared infrastructure for the multi-business VPS deployment: Caddy
|
|
# (reverse proxy + automatic TLS via Let's Encrypt) and one MySQL server
|
|
# shared by every business (a separate database + user per business, NOT
|
|
# one shared schema — see step 1 below).
|
|
#
|
|
# Lives in stacks/infra/, one directory per stack (each with its own
|
|
# compose.yaml) — see stacks/blake-heritage/, stacks/marios/ for the same
|
|
# shape per business, and stacks/manager/ for the management UI's own
|
|
# stack. Deliberately separate from docker-compose.local.yaml at the
|
|
# repo root, which is the single-business local/Docker-Desktop setup and
|
|
# stays untouched by any of this.
|
|
#
|
|
# Stack management/provisioning is handled by NextChair Manager (see
|
|
# manager/ at the repo root) — there is no separate stack-management UI
|
|
# alongside it.
|
|
#
|
|
# ── One-time setup ───────────────────────────────────────────────────────
|
|
# docker network create next-chair-edge
|
|
# cp .env.infra.example stacks/infra/.env (then fill in real values)
|
|
# docker compose -f stacks/infra/compose.yaml --env-file stacks/infra/.env up -d
|
|
#
|
|
# ── Per business ──────────────────────────────────────────────────────
|
|
# Use the management UI (manager/) once it's running — it automates all
|
|
# of the steps below. To do it by hand instead:
|
|
# 1. Create that business's database + user on the shared MySQL server.
|
|
# There's no automatic way to do this per business via env vars —
|
|
# the mysql:8.0 image's MYSQL_DATABASE/USER/PASSWORD vars only
|
|
# provision ONE database at first boot, and /docker-entrypoint-
|
|
# initdb.d scripts only ever run once against an empty data
|
|
# directory — so this one step is manual, run once per business:
|
|
# docker exec -it next-chair-mysql mysql -uroot -p
|
|
# CREATE DATABASE blake_heritage CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
|
|
# CREATE USER 'blake_heritage'@'%' IDENTIFIED BY 'choose-a-strong-password';
|
|
# GRANT ALL PRIVILEGES ON blake_heritage.* TO 'blake_heritage'@'%';
|
|
# FLUSH PRIVILEGES;
|
|
# 2. Copy .env.business.example to stacks/<slug>/.env, fill it in with
|
|
# the credentials just created and that business's domain.
|
|
# 3. Add stacks/infra/sites/<slug>.caddy (see that directory's own
|
|
# note) and reload Caddy:
|
|
# docker exec next-chair-caddy caddy reload --config /etc/caddy/Caddyfile
|
|
# 4. docker compose -f stacks/<slug>/compose.yaml --env-file stacks/<slug>/.env up -d
|
|
|
|
services:
|
|
caddy:
|
|
image: caddy:2-alpine
|
|
container_name: next-chair-caddy
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
ports:
|
|
# Overridable for local testing (a machine already running
|
|
# something else on 80/443) — a real deployment leaves these at
|
|
# their defaults, since Let's Encrypt's HTTP challenge and normal
|
|
# HTTPS traffic both expect the standard ports.
|
|
- "${CADDY_HTTP_PORT:-80}:80"
|
|
- "${CADDY_HTTPS_PORT:-443}:443"
|
|
volumes:
|
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
|
# One .caddy file per business, imported by the Caddyfile — see
|
|
# sites/.gitkeep's own note. Adding/removing a file here needs a
|
|
# `caddy reload` (see the per-business setup steps above) to take
|
|
# effect; Caddy doesn't watch this directory on its own.
|
|
- ./sites:/etc/caddy/sites
|
|
# Caddy's own automatic-HTTPS certificate storage — must persist
|
|
# across restarts or every restart re-issues every certificate
|
|
# against Let's Encrypt's rate limits.
|
|
- next-chair-caddy-data:/data
|
|
- next-chair-caddy-config:/config
|
|
networks:
|
|
- next-chair-edge
|
|
|
|
next-chair-mysql:
|
|
image: mysql:8.0
|
|
container_name: next-chair-mysql
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
# No MYSQL_DATABASE/MYSQL_USER/MYSQL_PASSWORD here deliberately — this
|
|
# server hosts one database per business (see step 1 above), not one
|
|
# shared schema. Only MYSQL_ROOT_PASSWORD (in .env) is required for
|
|
# the image to boot.
|
|
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_0900_ai_ci
|
|
ports:
|
|
# Host-machine access (e.g. a GUI client over an SSH tunnel) — every
|
|
# business's app container reaches this over the shared Docker
|
|
# network via the service name `next-chair-mysql`, never this.
|
|
- "${MYSQL_HOST_PORT:-3306}:3306"
|
|
volumes:
|
|
- next-chair-mysql-data:/var/lib/mysql
|
|
healthcheck:
|
|
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-change-me-too}"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 20
|
|
start_period: 10s
|
|
networks:
|
|
- next-chair-edge
|
|
|
|
volumes:
|
|
next-chair-mysql-data:
|
|
name: next-chair-mysql-data
|
|
next-chair-caddy-data:
|
|
name: next-chair-caddy-data
|
|
next-chair-caddy-config:
|
|
name: next-chair-caddy-config
|
|
|
|
networks:
|
|
next-chair-edge:
|
|
name: next-chair-edge
|
|
external: true
|