Archived configs that are not deployed live under `docs/config/`.
## First-time setup
Create the shared Docker network before starting any service:
```bash
docker network create app-shared-net
```
Create `.env` from `.env.example` and fill production values. Do not commit `.env`.
## Deployment order
The GitHub deploy workflow combines the active compose files automatically. For manual deployment, use this order:
```bash
docker compose -f infra/compose/shared.yml up -d
docker compose -f infra/compose/traefik.yml up -d
docker compose \
-f infra/compose/scraper.yml \
up -d
```
## Environment variables
Common variables used by infra compose files:
```env
DATABASE_URL=
GITHUB_TOKEN=
SHARED_REDIS_EXPOSE=127.0.0.1:6379:6379
```
Traefik certificate path variables are optional because `infra/compose/traefik.yml` provides production-compatible defaults. See `infra/traefik/TRAEFIK_ENV_CONFIG.md` for the full list.
## Traefik
Traefik reads dynamic config from `infra/traefik/dynamic/`:
-`apps.yaml` — routers and upstream services
-`middlewares.yaml` — shared middleware chains
-`ssl.yaml` — TLS certificates
The primary certificate intentionally pairs `asephstech.pem` with `asephscloud.key` to preserve the current production layout.
## Validation
Run syntax checks after editing infra YAML:
```bash
python - <<'PY'
import pathlib, yaml
for path in pathlib.Path('infra').rglob('*.yml'):
with path.open() as fh:
yaml.safe_load(fh)
print(f'OK {path}')
for path in pathlib.Path('infra').rglob('*.yaml'):