Runbook — website development environment
Synced read-only from
/home/synvirt/synvirt-platform/docs-internal/runbooks/dev-environment.md. Edit at the source, not here.
Runbook — website development environment
Section titled “Runbook — website development environment”Set up 2026-10-07 at the owner’s request. Covers the three things a change to the marketing site touches: where you work, where the styles live, and how a change reaches the LAN preview and, later, the public site.
1. Where you work: the internal workspace
Section titled “1. Where you work: the internal workspace”https://10.10.26.4:8092 — code-server (VS Code in the browser) opened on
this repository, with an integrated terminal where claude and codex are on
the PATH. LAN only; it is never published through Caddy or public DNS.
| Item | Value |
|---|---|
| Service | synvirt-workspace.service (source: infra/systemd/synvirt-workspace.service) |
| Runs as | synvirt (repo owner, sudo) — not root |
| Config | ~synvirt/.config/code-server/config.yaml (bind address, auth: password, self-signed cert) |
| Binary | /usr/bin/code-server 4.140.0 (Debian package) |
| Agents | ~synvirt/.local/bin/claude (official installer), ~synvirt/.local/bin/codex (standalone binary, same build as root’s) |
The password line is set by the owner, by hand, in config.yaml; nothing in
this repo generates or stores it. The certificate is self-signed, so the
browser warns once — accept it for 10.10.26.4.
First use of each agent inside the terminal is a one-time login: claude
prints an OAuth URL; codex login likewise. Those credentials live in
~synvirt/.claude and ~synvirt/.codex, separate from root’s.
Status: task workspace. Restart: sudo systemctl restart synvirt-workspace.
Terminal and editor setup (2026-10-07)
Section titled “Terminal and editor setup (2026-10-07)”- Default terminal profile is zsh (
~synvirt/.zshrc, no framework) with starship (~synvirt/.config/starship.toml, ASCII symbols so no special font is needed), fzf (Ctrl-R history, Ctrl-T files, Alt-C directories), zsh-autosuggestions and zsh-syntax-highlighting;bat,eza,fdbehind the usual aliases (cat,ls/ll/la,fd). Shortcuts:repo,wpcss,wpwatch,wptest,t=task. bash remains available as a second profile; the login shell is unchanged. - Node for the
synvirtuser comes from/opt/synvirt/bin(node22 plusnpm,npx,corepack,pnpmshims copied from root’s fnm install). corepack fetches the workspace’s pnpm on first use into~/.cache/node. - code-server settings:
~synvirt/.local/share/code-server/User/settings.json. Extensions (Open VSX): Prettier, PHP Intelephense, EditorConfig, YAML, GitLens, Playwright, Docker, Color Highlight. Add more withcode-server --install-extension <id>assynvirt.
synvirt is not in the docker group, so task targets that call
docker compose need sudo from the workspace terminal (or the owner adds
the group membership — a deliberate decision, not something this runbook does).
2. Where the styles live
Section titled “2. Where the styles live”apps/wordpress/├── src/css/│ ├── site.css entry: @imports site/* in cascade order│ ├── site/ base theme partials (fonts, tokens, base, header, …)│ ├── direction.css entry: @imports direction/* in cascade order│ └── direction/ owner-directed layer (aurora hero, feature pages, vm-page, …)├── scripts/build-css.mjs lightningcss bundle + minify└── themes/synvirt-renewed/assets/css/{site,direction}.css BUILT — do not editdirection.cssis enqueued aftersite.cssand overrides it; both still exist because the public site was published that way. Partials are contiguous slices of the original files, in the original order, so the cascade is unchanged — the first build was verified byte-identical to the previously served CSS after normalisation.- Edit the partials. Never edit the built files;
task wp:css:checkfails when they drift. - Phase 2 (not done): collapse the two
:roottoken blocks (and the third one indirection/aurora-media.css) into onetokens.cssaligned withapps/wordpress/DESIGN.md. Do it as its own reviewed change.
Commands (repo root):
task wp:css # build oncetask wp:css:watch # rebuild on savetask wp:css:check # CI-style staleness checkCopy lives in themes/synvirt-renewed/content.json (en/es/zh); presentation
logic in functions.php and includes/presentation.php. Unchanged by this
setup.
3. From edit to preview to public
Section titled “3. From edit to preview to public”edit src/css or theme PHP └─ task wp:css (CSS only) └─ http://10.10.26.4:8093 LAN preview: mounts the working tree read-only └─ task wp:test Playwright checks against the preview └─ public site see "production caveat"- Preview:
task wp:preview:upstartswordpress-previewif it is down. It has its own database and plugin volumes; uploads are shared. PHP edits show after OPcache revalidation (≤ 60 s); verify with a?v=<random>query. - Tests:
task wp:testrunstests/preview.e2e.cjsandtests/feature-navigation.e2e.cjswith the workspace’splaywrightpackage and the shared browser install in/opt/synvirt/ms-playwright(PLAYWRIGHT_BROWSERS_PATH; installed once withnpx playwright install chromium-headless-shell).tests/publication.e2e.cjstargets the public site and is run by hand (pnpm test:publicationinapps/wordpress).
Production caveat (read this)
Section titled “Production caveat (read this)”As of 2026-10-07 the public site still bind-mounts the working tree.
infra/compose/compose.yaml mounts apps/wordpress/themes/synvirt-renewed
and apps/wordpress/mu-plugins read-only into the live wordpress
container. A saved edit, or a task wp:css build, reaches synvirt.mx after
OPcache (60 s) and the Souin page cache (120 s). There is no deploy step yet.
The proposed fix — production mounts a frozen copy under
/srv/synvirt-web/live/, updated by a task wp:deploy that backs up the
previous copy to /srv/synvirt-web/releases/<stamp>/, with the preview
overlay keeping the working-tree mount via volumes: !override — was
presented to the owner and not yet authorised. Until it is: build CSS
only when the result is meant to go live, and run task wp:backup before
PHP or seed changes.
4. Housekeeping
Section titled “4. Housekeeping”- Disk on
/is tight (≈ 2.8 GB free after this setup). Reclaimable without touching anything of the owner’s:pnpm store prune(root’s store is ≈ 1.2 GB plus 0.8 GB cache).release-backups/andrelease-staging/in/home/synvirtare product release artefacts — leave them alone. - Files created from a root shell end up root-owned inside the repo and then
block the workspace user;
chown -R synvirt:synvirtwhat you touched, or work from the workspace in the first place. - The theme,
src/css, scripts, tests and this runbook are not committed yet; the owner has not authorised commits of the untracked work.