
Central Deploy Manager
2026
The deployment plumbing behind this site and its smaller siblings: signed webhooks, health-checked Docker rollouts, and Caddy routing on one VPS.

Aquarium
2026
A small 3D aquarium for the browser, built with React and Three.js and deployed like a real app because apparently I cannot leave anything simple.

Bird of the Day
2026
A tiny daily bird site powered by recent eBird observations, a small Express API, and an unreasonable amount of affection for birds.
CentraID
2026
A six-person capstone connecting a NestJS/PostgreSQL backend, an Expo mobile app, and a classroom reader service for verified check-ins.
React Native Cloud Prototypes
2025
Two Expo/Firebase prototypes: one for vehicle access approvals and one for QR-based classroom attendance.
Wurmkickflip
2026
An extremely serious physics experiment about teaching a worm to ride a skateboard. The physics works; the worm remains a work in progress.
2026
Central Deploy Manager
The deployment plumbing behind this site and its smaller siblings: signed webhooks, health-checked Docker rollouts, and Caddy routing on one VPS.

My notes
I built this because copying a slightly different deployment setup into every tiny side project was getting old fast. I wanted each app to own its code and Dockerfile while one boring, predictable service handled the dangerous bit on the server.
Now a new app mostly needs a health endpoint, a small config file, and a webhook secret. The manager builds a candidate container, checks that it is alive, and only then swaps it into production. It is not the flashiest project here, but it is the reason the flashier ones can live on their own subdomains without me manually babysitting every deploy.
Central Deploy Manager is the deployment layer I built to move my personal VPS from a one-off portfolio deployment into a small multi-app hosting setup.
The manager exposes a signed webhook endpoint, maps app IDs to root-owned deployment config files, and runs a shared Docker rollout script for each app. The rollout keeps the pattern I wanted from the original website deploy: build the image, start a candidate container on a temporary loopback port, health-check it, then swap the production container only after the candidate passes.
The system currently supports the portfolio site, Aquarium, and Bird of the Day from one server. Caddy handles the public domains and TLS, while Docker containers stay bound to 127.0.0.1 on app-specific ports.
The part I like most is that adding another app is mostly configuration: clone a repo, give it a Dockerfile and health endpoint, add one app env file, add one allowlist entry, and point a GitHub Actions workflow at the central deploy endpoint.