homelab
Automating blog deployments for my homelab
How I made this Astro blog build and publish through a small self-hosted deployment workflow.
I wanted this blog to stop feeling like a local folder that happened to build. The first useful step was a deployment workflow: push the source, build the Astro site in a controlled job, and publish only the generated static files to the web host.
The setup is intentionally small. Forgejo coordinates the workflow, a runner handles the build, and Nginx serves the final files. The rest of the homelab provides the surrounding infrastructure, but the public shape of the deployment stays simple.
Why I wanted this pipeline
Manual deploys are fine for experiments, but they do not scale well once a site becomes a real project. I wanted a repeatable path from repository changes to a fresh static build.
That gives me a few useful boundaries:
- the repository stays the source of truth,
- the build environment owns the tooling,
- the web host only serves static output,
- deployment secrets stay outside the repository,
- and each release follows the same steps.
The build environment
The workflow runs in a Node environment that matches the project requirements. It installs dependencies, builds the site, and checks that the generated output exists before publishing anything.
I like that separation. The host that serves the site does not need the full source tree, package manager state, or development tooling. It only needs the result of the build.
Publishing the static site
The deployment publishes the built output directory rather than the project source. Removed pages and renamed assets should disappear from the remote copy, so the sync step is configured to keep the published directory aligned with the current build.
The sensitive parts of that process live in Forgejo secrets and deployment settings. Hostnames, credentials, ports, and paths do not belong in the content or the repository.
Homelab context
This fits the way I want the homelab to work: each service has a narrow job. Forgejo manages project automation, the runner builds the site, and Nginx serves static files. Proxmox gives me the room to separate those responsibilities without turning the blog into a complicated application.
That separation makes the system easier to maintain. I can change the blog, adjust the deployment workflow, or move the static host without rewriting the entire setup.
Result
This made the blog feel more like infrastructure and less like a loose website. The pipeline is still modest, but it gives the repository a reliable deployment target: write content, build it, and publish the static output through a controlled workflow.
The next work in this series was less about deployment and more about shaping the repository into the site I wanted to maintain.