forked from Nixius/authelia
1
0
Fork 0
ATLAS/docker/ss-atlas/templates/stack-template.yml

89 lines
3.2 KiB
YAML

# =============================================================================
# CUSTOMER STACK TEMPLATE — Gitea + PostgreSQL
# =============================================================================
# This is the Docker Swarm stack deployed for each paying customer.
# It defines what product/service they receive when they subscribe.
#
# PRODUCT: Gitea — a self-hosted Git service, backed by PostgreSQL.
# Each customer gets their own isolated instance at a sub-path.
#
# 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 (unique resource naming)
# {{.Subdomain}} - customer's username (used in path: /i/{subdomain})
# {{.Domain}} - base domain (e.g. bc.a250.ca)
# {{.TraefikNetwork}} - Traefik overlay network name
#
# Each customer gets their stack at: https://{{.Domain}}/i/{{.Subdomain}}
# Access is restricted to the owning user via Authelia forward-auth.
# =============================================================================
services:
web:
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: "{{.Domain}}"
GITEA__server__ROOT_URL: "https://{{.Domain}}/i/{{.Subdomain}}/"
GITEA__server__HTTP_PORT: "3000"
GITEA__security__INSTALL_LOCK: "true"
volumes:
- gitea_data:/var/lib/gitea
- gitea_config:/etc/gitea
networks:
- traefik_net
- backend
deploy:
replicas: 1
labels:
traefik.enable: "true"
traefik.docker.network: "atlas_{{.TraefikNetwork}}"
traefik.http.routers.customer-{{.ID}}-web.rule: "Host(`{{.Domain}}`) && PathPrefix(`/i/{{.Subdomain}}`)"
traefik.http.routers.customer-{{.ID}}-web.entrypoints: "websecure"
traefik.http.routers.customer-{{.ID}}-web.priority: "2"
traefik.http.routers.customer-{{.ID}}-web.tls: "true"
traefik.http.routers.customer-{{.ID}}-web.middlewares: "strip-customer-{{.ID}}@swarm,authelia-auth@swarm"
traefik.http.middlewares.strip-customer-{{.ID}}.stripprefix.prefixes: "/i/{{.Subdomain}}"
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
networks:
traefik_net:
external: true
name: "atlas_{{.TraefikNetwork}}"
backend:
driver: overlay
volumes:
gitea_data:
driver: local
gitea_config:
driver: local
db_data:
driver: local