- flake.nix: 6 derivations (hub, scraper, tools-gateway, tools-workers, tools-frontend, llm-api) - Fetch submodule source via builtins.fetchGit with pinned revs - Fix cargo HOME/TMPDIR for Nix sandbox permission issues - Fix llm-api: CMake/Clang deps for llama.cpp-sys2 bindgen - Add LIBCLANG_PATH, LD_LIBRARY_PATH for Rust bindgen builds - Systemd units: tools-gateway (3501), tools-frontend (3500), tools-workers, llm-api (8080) - tools.target for grouped management - Env configs: /etc/tools/env, /etc/llm-api/env - GitHub Actions: nix-build.yml — matrix build + nix copy + deploy - Update Traefik apps.yaml: tools/host.docker.internal:3500, llm-api/host.docker.internal:8080 - iptables: allow Docker→host on 3099, 4091, 3500, 3501, 8080 - Add scripts/nix-deploy.sh for CI/CD deploy step
Infrastructure
Docker Compose and Traefik configuration for asepharyana-hub.
Layout
infra/
├── compose/ # One compose file per stack/service
│ ├── traefik.yml # Public reverse proxy
│ ├── shared.yml # Shared Redis
│ ├── nats.yml # NATS message broker + JetStream
│ ├── dapr.yml # Dapr placement service
│ └── scraper.yml # Scraper API (app + Dapr sidecar)
├── docker/ # Dockerfiles and image runtime helpers
├── dapr/ # Dapr component configs
│ ├── config.yaml # Global Dapr configuration
│ └── components/ # Pub/sub (Redis), state store (Redis)
├── traefik/ # Dynamic Traefik configuration
│ ├── dynamic/ # Routers, services, middlewares, TLS certs
│ └── TRAEFIK_ENV_CONFIG.md
First-time setup
Create the shared Docker network before starting any service:
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:
# 1. Shared services
docker compose -f infra/compose/shared.yml up -d
# 2. Message bus + Dapr placement
docker compose -f infra/compose/nats.yml up -d
docker compose -f infra/compose/dapr.yml up -d
# 3. Reverse proxy
docker compose -f infra/compose/traefik.yml up -d
# 4. Application services (with Dapr sidecars)
docker compose -f infra/compose/scraper.yml up -d
Environment variables
Common variables used by infra compose files:
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 servicesmiddlewares.yaml— shared middleware chainsssl.yaml— TLS certificates forasepharyana.my.idandasepharyana.web.id
Validation
Run syntax checks after editing infra YAML:
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'):
with path.open() as fh:
yaml.safe_load(fh)
print(f'OK {path}')
PY
Check compose rendering when Docker is available:
for f in infra/compose/*.yml; do
docker compose -f "$f" config >/dev/null && echo "OK $f"
done