Features
A Deploy Pipeline for a Static Site That Refuses to Break It
Build, verify, then publish. Guards that catch a bad build before users do.
29 September 2026

Build and Verify Separately
The first principle is that the build step must not touch the live directory until it is proven safe. For static sites like GamingCap and Invoiceful, the build process generates a folder of HTML, CSS, and JavaScript files. The script runs this build in an isolated temporary directory. If the build command returns a non-zero exit code, the script halts immediately. No files are moved. No links are updated. The live site remains untouched, preserving the last known good state.
Verification follows the build. The script checks that the expected output files exist. It validates that the index file is present and that key assets were generated. This step catches silent failures where the build tool claims success but produces an empty or incomplete directory. Only after these checks pass does the script proceed to deployment.
Atomic Swapping
Deployment is not a copy operation; it is a swap. The script renames the current live directory to a backup name and moves the new build into place. This atomic operation ensures that users never see a half-deployed site. If the swap fails due to disk space or permission errors, the script restores the previous directory. The risk of downtime is reduced to the milliseconds required to rename two directories on the same filesystem.
Because Caddy serves these static files directly from disk, there is no server process to restart. The web server reads the new files immediately. This simplicity eliminates a common source of deployment errors: configuration mismatches between the build environment and the runtime server.
Systemd Timers for Scheduled Work
Scheduled tasks on the single VPS run as systemd oneshot services with timers, not cron. This approach provides better logging and dependency management. A timer can trigger the deploy script if a manual trigger is missed, or it can run verification checks periodically. The oneshot service ensures that the script runs to completion before the timer considers the job done. If the script hangs, systemd can kill it after a timeout, preventing resource leaks.
On a machine with 12GB of RAM, competing processes can strain memory. Running heavy builds at predictable times via timers allows for better resource planning. The deploy script can be configured to run during off-peak hours, reducing the chance that a build process competes with live traffic for CPU cycles.
Single Source of Truth
The deploy script is the single source of truth for how static sites are updated. It encapsulates the build, verification, and swap logic. This means that whether the deployment is triggered manually or by a timer, the same guards apply. There is no ad-hoc copying of files. There is no manual verification. The script enforces consistency.
For a static site, the complexity lies not in the code but in the process. A well-written deploy script turns a risky manual operation into a reliable, repeatable task. It ensures that the site remains available, even when the build process fails. The goal is not to deploy faster, but to deploy safely.


