Web
Astro’s generated HTML, CSS, JavaScript, project images, and the Pagefind search index, served by nginx.
node:24-alpine → nginx:alpine One commit, two images, no hand-copied secrets—eventually—and hopefully no 2am surprises.
This is how a change travels through the actual repository, build runner, private registry, deploy host, and runtime. The excerpts are deliberately small and reviewed; secrets and private network details do not belong in a portfolio diagram.
npm run build
# astro build && pagefind --site dist on:
push:
branches: [main]
workflow_dispatch: - uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: docker/setup-buildx-action@v3 goonk-cv:latest goonk-cv:a1b2c3d
goonk-cv-api:latest goonk-cv-api:a1b2c3d tags:
- <registry>/<project>:latest
- <registry>/<project>:<short-sha> docker compose pull
docker compose up -d keep pull <project>/production > .env
docker compose up -d web → nginx → static Astro + Pagefind
api → Express → Spotify / Immich / Last.fm / Gitea application state ≠ monitoring state
unknown ≠ unhealthy keep can—and cannot—seeThe server distributes encrypted material and records access. Encryption and decryption happen at the edges, so the server never needs the plaintext or the private key that would reveal it.
.env encrypt locally .env | Concern | Build / CI | Deploy / runtime |
|---|---|---|
| Purpose | Produce and publish immutable images | Configure one environment |
| Example | Registry publishing credential | Spotify, Immich, and API credentials |
| Storage | Gitea Actions secret where required | Encrypted keep vault; decrypted by the deploy identity |
| Inside image? | No. Application secrets are not build artifacts. | |
| Rotation | Change publishing access | Push a new vault revision and redeploy |
Astro’s generated HTML, CSS, JavaScript, project images, and the Pagefind search index, served by nginx.
node:24-alpine → nginx:alpine A deliberately separate Express process for Spotify, Last.fm, Immich, Gitea, and the small pieces that cannot be static.
node:24-alpine → node api/index.mjs Two containers, one persistent data volume, and one deploy host do not need a control plane. Docker Compose describes the system that actually exists, keeps recovery understandable, and leaves fewer things to break at 2am.
Build identity is embedded in the artifact. Deployment identity comes separately from Trace, after the deploy host has run its health checks. If either source is unavailable, this panel says so instead of guessing.