72 lines
3.2 KiB
Markdown
72 lines
3.2 KiB
Markdown
|
|
---
|
|||
|
|
title: CV on Indri
|
|||
|
|
modified: 2026-04-29
|
|||
|
|
last-reviewed: 2026-04-29
|
|||
|
|
tags:
|
|||
|
|
- how-to
|
|||
|
|
- operations
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# CV on Indri
|
|||
|
|
|
|||
|
|
How the CV/resume static site (`cv.eblu.me`) is deployed on indri natively. Replaces the prior minikube Deployment; mirrors the rationale of [[devpi-on-indri]].
|
|||
|
|
|
|||
|
|
## Why native, not Kubernetes
|
|||
|
|
|
|||
|
|
CV is a tiny static site (HTML + CSS + PDF). It needs no daemon, no database, no auth. Caddy on indri can serve the extracted tarball directly via `file_server`. Removing the minikube Deployment shrinks the cluster's footprint and removes a network hop (Fly → indri Caddy → ProxyGroup ingress → minikube pod becomes Fly → indri Caddy → local files).
|
|||
|
|
|
|||
|
|
## Layout
|
|||
|
|
|
|||
|
|
| Concern | Path / detail |
|
|||
|
|
|---|---|
|
|||
|
|
| Content dir | `/Users/erichblume/blumeops/cv/content/` |
|
|||
|
|
| Version sentinel | `/Users/erichblume/blumeops/cv/.installed-version` |
|
|||
|
|
| Caddy entry | `cv` service in `ansible/roles/caddy/defaults/main.yml` (`kind: static`) |
|
|||
|
|
| Public URL | `https://cv.eblu.me` (via [[flyio-proxy]]) |
|
|||
|
|
| Private URL | `https://cv.ops.eblu.me` (Caddy on indri) |
|
|||
|
|
| Tarball source | Forgejo generic package `cv` (`forge.eblu.me/eblume/-/packages`) |
|
|||
|
|
|
|||
|
|
The role is driven by `cv_version` in `ansible/roles/cv/defaults/main.yml`. The download and extract steps only fire when the on-disk sentinel doesn't match `cv_version` — i.e. after a version bump.
|
|||
|
|
|
|||
|
|
## Deploy
|
|||
|
|
|
|||
|
|
Two paths:
|
|||
|
|
|
|||
|
|
**From a release workflow** (most common):
|
|||
|
|
|
|||
|
|
1. Run the `Release CV` workflow in the cv repo → produces a new generic package
|
|||
|
|
2. Run the blumeops `Deploy CV` workflow → bumps `cv_version` in `ansible/roles/cv/defaults/main.yml` and pushes to main
|
|||
|
|
3. From gilbert: `mise run provision-indri -- --tags cv`
|
|||
|
|
4. From gilbert: `fly ssh console -a blumeops-proxy -C "sh -c 'rm -rf /tmp/cache && nginx -s reload'"` to purge the public-edge cache
|
|||
|
|
|
|||
|
|
**Manual** (e.g., reverting): edit `cv_version` in the role defaults yourself, then steps 3–4.
|
|||
|
|
|
|||
|
|
## Verify
|
|||
|
|
|
|||
|
|
```fish
|
|||
|
|
ssh indri 'cat ~/blumeops/cv/.installed-version'
|
|||
|
|
ssh indri 'ls -la ~/blumeops/cv/content/'
|
|||
|
|
curl -fsSI https://cv.ops.eblu.me/ # private
|
|||
|
|
curl -fsSI https://cv.eblu.me/ # public
|
|||
|
|
curl -fsSI https://cv.eblu.me/resume.pdf | grep -i disposition
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
The PDF response should include `content-disposition: attachment; filename="erich-blume-resume.pdf"`.
|
|||
|
|
|
|||
|
|
## Bumping the cv version
|
|||
|
|
|
|||
|
|
Edit `cv_version` in `ansible/roles/cv/defaults/main.yml` and re-run `mise run provision-indri -- --tags cv`. The role recreates the content dir from the new tarball; the sentinel update triggers the next idempotent skip.
|
|||
|
|
|
|||
|
|
## Backup
|
|||
|
|
|
|||
|
|
The content dir is **not** in `borgmatic_source_directories`. The tarball is re-downloadable from the Forgejo generic package store on every deploy, and the source is in the cv repo — recovery is just re-running the role.
|
|||
|
|
|
|||
|
|
## Rollback
|
|||
|
|
|
|||
|
|
If a bad version is published, set `cv_version` back to the previous tag in `ansible/roles/cv/defaults/main.yml` and re-run the role. The full minikube manifest set is preserved in git history (commits prior to the migration cleanup) for the worst case.
|
|||
|
|
|
|||
|
|
## Related
|
|||
|
|
|
|||
|
|
- [[devpi-on-indri]] — same shape, different upstream
|
|||
|
|
- [[restart-indri]] — graceful indri restart procedure
|
|||
|
|
- [[cv]] — service reference
|