Add the example stack payloads

The files copied to /srv/stacks/<stack>/ verbatim: compose files, vhosts,
Prometheus configuration, the webapp image source. Payloads are data, never
templated and never linted as Ansible content.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
Lucas Winther
2026-09-16 03:58:01 +02:00
co-authored by Claude Opus 5
parent 7b52e9af9e
commit b76c76e3b0
16 changed files with 399 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
# Prometheus and Grafana, deployed to every host from this one payload.
#
# It lives under server/shared/ rather than server/<host>/ because both hosts run
# exactly the same thing; ansible/playbooks/metrics.yml points stack_src here.
# Per-host differences (which networks exist, which extra directories to create)
# belong in the playbook, not in duplicated copies of this file.
#
# Both bind mounts below need a directory that exists with the right ownership
# before the container starts, and neither image will fix it for you:
#
# grafana-data the image runs as uid 472 and writes a SQLite database here
# prometheus-data the image runs as nobody (65534)
#
# The playbook pre-creates both. See "stack_dirs" in AGENTS.md for why that is
# the role's job and not a chown in pre_tasks.
services:
prometheus:
container_name: prometheus
image: prom/prometheus:v3.1.0
restart: unless-stopped
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
# Served under a sub-path by the reverse proxy, so it has to generate
# absolute URLs that include it.
- --web.external-url=https://app.example.com/internal/metrics/
- --web.route-prefix=/
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./prometheus-data:/prometheus
networks:
- default
- proxy-net
grafana:
container_name: grafana
image: grafana/grafana-oss:11.5.1
restart: unless-stopped
networks:
- default
- proxy-net
environment:
VIRTUAL_HOST: dashboards.example.com
VIRTUAL_PORT: "3000"
LETSENCRYPT_HOST: dashboards.example.com
GF_SERVER_ROOT_URL: https://dashboards.example.com
# Compose fails the run if this is not set, rather than starting Grafana
# with a blank admin password. The value comes from the host's .env, which
# is never synced from this repository — see docs/secrets.md.
GF_SECURITY_ADMIN_PASSWORD: ${GF_SECURITY_ADMIN_PASSWORD:?set it in .env on the host}
volumes:
- ./grafana-data:/var/lib/grafana
networks:
proxy-net:
external: true