Part 9: VSCode as the GitOps Cockpit
The whole point of the pipeline is that the interface to my infrastructure is a text editor. Edit a file, commit, and the fleet rebuilds. So VSCode is worth setting up deliberately, and its config is itself version-controlled in an itg-infra repo.
Config lives in git, not just on the laptop
I keep the workspace file, extension list, and user settings in itg-infra/vscode/ (ITG.code-workspace, extensions.json, user-settings.json). The subtlety: putting JSON in a repo does not mean VSCode reads it. VSCode reads from its own profile directory, so the git-controlled copies are the source of truth and I sync them into the live profile.
On a Mac, the live files are under ~/Library/Application Support/Code/User/ (for example settings.json). There is a settings.json there, but note there is no matching extensions.json in that folder, extensions are tracked differently, so keeping a git-controlled extensions.json as a recommended-extensions manifest is the pragmatic move rather than expecting VSCode to consume it directly.
Commit-triggered push
The magic that makes it feel like a cockpit is auto-push on commit. VSCode's git integration has a git.postCommitCommand setting; set it to push (or sync) and every commit fires the push, which trips the Forgejo webhook, which runs the pipeline. Commit becomes deploy.
While you are in here: nano to vim, and the clock
Two small quality-of-life fixes that came up:
systemctl editopening nano drove me up a wall. SettingEDITORandSYSTEMD_EDITOR=vimin/etc/environment(baked into the base, Part 1) fixes it fleet-wide.- Pinning the timezone with the
/etc/localtimesymlink (also Part 1) means log timestamps andsystemctl editand everything else read in local time instead of UTC.
The naming convention
Somewhere in here I standardized on calling my specific Forgejo instance forge, not a generic "the git server." Small thing, but naming your own instance makes the runbooks and the mental model click.
Lessons
- Git-controlled editor config is the source of truth; sync it into VSCode's profile, do not assume VSCode reads your repo.
git.postCommitCommand = pushturns commit into deploy.- Fix
EDITOR/SYSTEMD_EDITORin the base so the whole fleet stops handing you nano.
Runbooks
The build
- Image Mode & Base
- Storage
- Hostnames & DNS
- Registry
- Actions Runner
- The Pipeline
- Nightly Auto-Deploy
- First Workload
- VSCode Cockpit
- Hugo Auto-Deploy
- Cloudflare & Kobo
- Runner Provisioning
- Tailscale Router
- SWAG & Website
- Split-DNS
- Plex
- Media Library Support
- The Day After
- Self-Hosted Media
- Hypervisor Joins the Fleet
- The Matrix Homeserver
Reference