infrastructure summary — stage 1

babypistachio.com

Backend mobile-development test environment on a single VPS, fronted by a reverse proxy with automatic HTTPS.

01Services

ServiceImageReachable at
traefik traefik:v3.6 public ports 80 / 443 — reverse proxy, TLS termination, routes every subdomain
socket-proxy tecnativa/docker-socket-proxy:0.3 internal lets Traefik discover containers without touching the raw Docker socket
apache httpd:2.4 public babypistachio.com — static site
gitea gitea/gitea:1.22 public git.babypistachio.com — repository hosting
jenkins jenkins/jenkins:lts-jdk21 public ci.babypistachio.com — CI/CD
api built from ./api (node:22-alpine) public api.babypistachio.com/health — placeholder service confirming the environment works end to end
postgres postgres:16 internal no public route, not yet wired into any service — ready for the real app

02Network layout

03What got fixed along the way

Five real issues surfaced while bringing this up, each documented in the repo's README so the fix doesn't get silently undone by a future change:

04Files

Security decisions worth knowing

No hardcoded secrets — everything sensitive comes from .env. Traefik's dashboard is enabled but has no external router, so it isn't reachable from the internet. Security headers (HSTS, X-Frame-Options, nosniff, XSS filter) apply to every public router. The VPS firewall should still restrict inbound traffic to 22/80/443 — Docker network isolation isn't a substitute for that.

Open risk — not yet resolved

Jenkins mounts the host Docker socket directly to support CI/CD builds. Anyone who compromises Jenkins has root-equivalent control of the host. Reasonable trade-off for a test environment, but not something to carry into production as-is — see the README for mitigation options (Docker-in-Docker agents, separate build VMs, rootless Docker).