Files
server-infra/README.md
2026-02-28 01:58:12 +01:00

2.6 KiB

server-infra

Shared Docker services for the Hetzner server: nginx proxy manager, umami analytics, Gitea + Actions runner.

Services

Service Port (host) Description
nginx proxy manager 80, 443, 81 (admin) Reverse proxy + SSL termination
umami internal Web analytics
gitea 127.0.0.1:3100 → nginx, 2222 (SSH) Self-hosted git at git.padelnomics.io
act_runner Gitea Actions CI runner

Directory layout

/opt/server-infra/          # this repo (owned by infra_service)
├── gitea/docker-compose.yml
├── reverse-proxy/docker-compose.yml   # recovered from running container
├── umami/docker-compose.yml           # recovered from running container
├── setup.sh                           # phase 1: user + dirs + uv
└── bootstrap.sh                       # phase 2: recover compose files, start Gitea

/data/server-infra/
├── gitea/                  # Gitea data volume
└── act_runner/             # Runner data volume

Setup (new server)

Phase 1 — user, dirs, uv

ssh root@<server-ip> 'bash -s' < setup.sh

Creates infra_service system user (docker group), /opt/server-infra/, /data/server-infra/, installs uv.

Phase 2 — sync repo + recover

rsync -av --chown=infra_service:infra_service \
    ~/Projects/server-infra/ root@<server-ip>:/opt/server-infra/

ssh root@<server-ip> 'bash -s' < bootstrap.sh

Recovers umami/docker-compose.yml and reverse-proxy/docker-compose.yml from running containers, creates data dirs, sets ownership.

Phase 3 — start Gitea

ssh hetzner_root 'sudo -u infra_service docker compose \
    -f /opt/server-infra/gitea/docker-compose.yml up -d'

Web installer at http://<server-ip>:3100. Set ROOT_URL to https://git.padelnomics.io. After setup, add a proxy host in nginx proxy manager → 127.0.0.1:3100.

Phase 4 — start act_runner

  1. Generate a runner token in Gitea: Site Administration → Actions → Runners → Create runner token
  2. Create /opt/server-infra/gitea/.env:
    GITEA_RUNNER_TOKEN=<token>
    
  3. Restart with the env file:
    ssh hetzner_root 'sudo -u infra_service docker compose \
        -f /opt/server-infra/gitea/docker-compose.yml up -d'
    

DNS

git.padelnomics.io must be DNS-only (grey cloud) in Cloudflare — not proxied — so that SSH on port 2222 reaches the server directly.

Secrets

The infra_service user owns all compose files. Secrets (runner token) go in /opt/server-infra/gitea/.env — never committed.