Files
LedgerLine/docs/roadmap/phase-1.md
T
Movses AslanyanandClaude Sonnet 5.5 5e514ecf25 Add deployment phase and Traefik compose override
Insert a new Phase 1 (deployment: Compose + Traefik on a server, marked
Done) between the base project and the OTel concepts phase, and shift
the old phases 1-10 to 2-11. Update summary, intro, README and CLAUDE.md
references (spoiler rules now target Phase 9, the bottleneck hunt).

Add docker-compose.traefik.yml: an override that fronts the gateway with
Traefik and Let's Encrypt and removes all other published host ports.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-09 15:38:29 +03:30

4.2 KiB
Raw Blame History

Phase 1 — Deployment: Ledgerline on a server behind Traefik

Part of docs/roadmap/ — see intro.md for platform/background context and summary.md for how every phase fits together. Prev: phase-0.md · Next: phase-2.md

Status: Done

Message: Ledgerline is running on a remote server and served over HTTPS at https://ledgerline.vione.cloud. Verified against the live deployment, not just the config: the frontend loads, /api/health/all reports every service ok, and the origin serves a real Let's Encrypt certificate (valid until 2027-01-07, auto-renewed by Traefik).

  • Target: the throwaway server czy (Ubuntu 24.04, 1 vCPU, 1 GB RAM), repo at /opt/apps/LedgerLine. Docker 29.9 and Compose v5.6 installed from Docker's apt repo. A 2 GB swapfile was added (persisted in /etc/fstab) — nine containers do not fit in 1 GB of RAM without it, and steady state still uses roughly 700 MB plus swap.

  • How it's wired: docker-compose.traefik.yml is an override, not an edit of docker-compose.yml, so local development is unchanged. It adds Traefik v3.6 on ports 80/443 (Docker provider, exposedByDefault=false, HTTP→HTTPS redirect, Let's Encrypt via HTTP-01), routes Host(`ledgerline.vione.cloud`) to the gateway on port 8000, and strips the published host ports from every other service (ports: !reset []) so Postgres, Redis and the services are reachable only on the Compose network.

  • No application or tests/ changes. The Dockerfile and base compose file are untouched; schema applied and data seeded on the server with the same steps as make seed (800 accounts, 250,000 transactions).

  • Deploy / redeploy command (always both files — a bare docker compose up would use the base file alone and publish every port):

    docker compose -f docker-compose.yml -f docker-compose.traefik.yml up -d --build
    
  • Cloudflare gotchas hit on the way:

    • The first certificate attempt failed with an ACME 404 because the Cloudflare DNS record did not yet point at the server — a packet capture on the server showed no inbound traffic from Cloudflare at all. Traefik only retries issuance on restart, so after fixing the record it needed docker compose ... restart traefik.
    • With the orange-cloud proxy on, the SSL/TLS mode must be Full — Flexible combined with Traefik's HTTPS redirect causes a redirect loop.
  • Caveats to remember: the deployment is public, including the /api/admin/chaos endpoints (anyone who finds them can flip flags); internet scanners probed the site within seconds of it going live. The server is disposable by design, and Traefik's state lives in the letsencrypt volume, which is lost on an OS reinstall (a new certificate is simply issued on the next run).

Time-box: 1 evening.

Deliverable: the unmodified-behaviour Ledgerline system reachable at a real domain over HTTPS, reproducible with one compose command.

Concepts

  • Traefik's model: entrypoints (the ports it listens on), routers (rule → service), services (where to send traffic), middlewares, and providers (where config comes from — here, Docker labels on containers). Compare with nginx, where the same information lives in one static config file.
  • Compose override files. -f base -f override merges the files; !reset clears an inherited key (here, ports) instead of appending to it.
  • ACME HTTP-01 behind a CDN. Let's Encrypt must be able to reach port 80 on the hostname's actual origin. With Cloudflare proxying, that only works once the DNS record points at the right server.
  • Why this phase exists before observability. The telemetry work in Phases 2–11 is more convincing when the system under observation is a real deployment rather than a laptop, and the platform (observability-ansible) is already a remote deployment — Ledgerline now sits on the same footing.

Done when: https://ledgerline.vione.cloud shows the frontend with a valid certificate; /api/health/all is all ok; only ports 22, 80 and 443 are reachable on the server; and the deploy is one documented compose command.