forked from Nixius/authelia
1
0
Fork 0

Switch customer stack to Gitea + PostgreSQL two-service pattern

- web: Gitea (self-hosted Git), exposed via Traefik behind Authelia
- db: PostgreSQL 16, internal backend network only, never exposed
- Establishes the canonical web+db template structure for future products

Made-with: Cursor
This commit is contained in:
Leopere 2026-03-03 17:02:49 -05:00
parent 463483f769
commit c68edc70d1
Signed by: colin
SSH Key Fingerprint: SHA256:nRPCQTeMFLdGytxRQmPVK9VXY3/ePKQ5lGRyJhT5DY8
1 changed files with 43 additions and 10 deletions

View File

@ -1,17 +1,21 @@
# =============================================================================
# CUSTOMER STACK TEMPLATE — Uptime Kuma
# CUSTOMER STACK TEMPLATE — Gitea + PostgreSQL
# =============================================================================
# This is the Docker Swarm stack that gets deployed for each paying customer.
# This is the Docker Swarm stack deployed for each paying customer.
# It defines what product/service they receive when they subscribe.
#
# PRODUCT: Uptime Kuma — a self-hosted uptime/monitoring dashboard.
# PRODUCT: Gitea — a self-hosted Git service, backed by PostgreSQL.
# Each customer gets their own isolated instance at their subdomain.
#
# To sell a different product, replace the `web` service image and adjust
# the port in the Traefik loadbalancer label accordingly.
# Structure:
# web — the application, exposed via Traefik behind Authelia auth
# db — PostgreSQL, internal only (backend network, never exposed)
#
# To sell a different product: replace the `web` image, update the port
# in the Traefik loadbalancer label, and adjust `db` env/image as needed.
#
# Template variables (injected at deploy time by swarm/client.go):
# {{.ID}} - customer's username (used for unique resource naming)
# {{.ID}} - customer's username (unique resource naming)
# {{.Subdomain}} - customer's subdomain (same as ID by default)
# {{.Domain}} - base domain (e.g. bc.a250.ca)
# {{.TraefikNetwork}} - Traefik overlay network name
@ -21,11 +25,21 @@
# =============================================================================
services:
web:
image: louislam/uptime-kuma:1
image: gitea/gitea:1-rootless
environment:
GITEA__database__DB_TYPE: postgres
GITEA__database__HOST: db:5432
GITEA__database__NAME: gitea
GITEA__database__USER: gitea
GITEA__database__PASSWD: gitea
GITEA__server__DOMAIN: "{{.Subdomain}}.{{.Domain}}"
GITEA__server__ROOT_URL: "https://{{.Subdomain}}.{{.Domain}}"
GITEA__server__HTTP_PORT: "3000"
volumes:
- uptime_data:/app/data
- gitea_data:/var/lib/gitea
networks:
- traefik_net
- backend
deploy:
replicas: 1
labels:
@ -35,7 +49,22 @@ services:
traefik.http.routers.customer-{{.ID}}-web.entrypoints: "websecure"
traefik.http.routers.customer-{{.ID}}-web.tls: "true"
traefik.http.routers.customer-{{.ID}}-web.middlewares: "authelia-auth@swarm"
traefik.http.services.customer-{{.ID}}-web.loadbalancer.server.port: "3001"
traefik.http.services.customer-{{.ID}}-web.loadbalancer.server.port: "3000"
restart_policy:
condition: on-failure
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: gitea
POSTGRES_USER: gitea
POSTGRES_PASSWORD: gitea
volumes:
- db_data:/var/lib/postgresql/data
networks:
- backend
deploy:
replicas: 1
restart_policy:
condition: on-failure
@ -43,7 +72,11 @@ networks:
traefik_net:
external: true
name: "atlas_{{.TraefikNetwork}}"
backend:
driver: overlay
volumes:
uptime_data:
gitea_data:
driver: local
db_data:
driver: local