A personal deploy server is a real weekend project, not a sitting: webhook, build, health-checked container swap, Caddy routing, env vars, a Postgres container with backups and cron are all ordinary pieces, and an agent can wire them on a single VPS. What stays behind is what the monthly bill pays for: multiple regions, autoscaling, managed Postgres with point-in-time recovery, DDoS filtering and someone else being paged at 3 a.m. Coolify, Dokploy and CapRover already do the self-hosted version, so writing your own is mostly worth it if you want something smaller than they are.
Before you buildRender's Hobby workspace costs nothing and a Free web service is fine for a demo. It sleeps after 15 minutes and the free Postgres expires after 30 days, so it is a trial, not a home.
Build me a personal deploy server to replace Render for my side projects. Requirements: - Node.js 22 + TypeScript on one Linux VPS with Docker and Caddy already installed. A Fastify admin UI (server-rendered, a little vanilla JS) listens on 127.0.0.1:4900; I reach it through an SSH tunnel. A second port, 4901, only accepts GitHub webhooks. - Storage: better-sqlite3 in ./data/deployd.db: apps (name, repo URL, branch, port, health path, domains), env vars encrypted with AES-256-GCM using a key from .env, deploys (commit, status, log) and cron jobs. Source and build logs live under ./data/src and ./data/logs. - Deploy: on a push webhook (HMAC-SHA256 check of X-Hub-Signature-256) or `deployd deploy <app>`, `git clone --depth 1` the commit, build with its Dockerfile (or `pack build` with the Paketo builder when there is none), and tag the image with the commit SHA. - Release: start the new container on a private Docker network, wait up to 60 seconds for the health path to return 200, then point Caddy at it through its admin API (localhost:2019) and stop the old one. A failed health check keeps the old container and marks the deploy failed. `deployd rollback <app>` re-points to the previous image; keep the last three images. - Domains: each app lists its domains; Caddy gets TLS certificates on its own once DNS points here. - Postgres: one postgres:17 container, a database and user per app injected as DATABASE_URL, and a nightly pg_dump to ./data/backups with 7 days of retention (`deployd db restore <app> <file>`). - Cron jobs: a schedule and a command per app, run with `docker run --rm` from the app's image using node-cron; the last 20 runs and their output are shown in the UI. - Single user, one admin token in .env. No accounts, no telemetry, local-first. Outbound calls: GitHub clones, image pulls and certificate issuance only. - Out of scope: autoscaling, several servers, regions, preview environments, managed Redis. - README: VPS setup, the DNS records, a firewall allowing only 22, 80 and 443, and two plain warnings: one server means downtime on every reboot, and a compromised host exposes every env var.
Opens your agent with the prompt filled in, you press enter. Or copy it and paste it into an empty folder.
The first prompt builds the core. Run these one at a time in the same folder to grow it into your own Render.
Extend the deploy server in this folder. Requirements: - On a pull_request webhook (opened, synchronize), build the branch and run it as a separate container at pr-<number>.<app domain>, with Caddy routing added through its admin API. - Give each preview its own database cloned from the app's database with `createdb --template`, and inject that DATABASE_URL; skip the clone for apps without Postgres. - Remove the container, route and database when the pull request closes, and after 7 days of no pushes. - Post the preview URL as a comment on the pull request with a GitHub token from .env. - Update the README with the wildcard DNS record this needs.
Add off-server backups to the deploy server in this folder. Requirements: - After each nightly pg_dump, encrypt the file with `age` using the public key in .env and upload it with the S3 API (`@aws-sdk/client-s3`) to a bucket from .env, keeping 30 daily copies. - `deployd backup verify` downloads the newest file, decrypts it into a throwaway postgres container, runs `SELECT count(*)` against each table and reports pass or fail. - Run the verify step weekly and show the result and the age of the last good backup on the UI home page. - Back up ./data/deployd.db and the Caddy data directory in the same job. - Update the README with a restore walkthrough from an empty server.
Add a Render importer to the deploy server in this folder. Requirements: - `deployd import-render render.yaml` reads a Render Blueprint (`yaml`) and creates apps for its web services, workers and cron jobs: repo, branch, build and start commands, health check path, and domains. - Variables with sync: false are listed and prompted for; fromDatabase and fromService references are mapped to this server's own DATABASE_URL and internal hostnames. - Print a table of what was created and what was skipped (static sites, disks, regions, plans) with the reason, and write nothing until I confirm. - Update the README with how to generate the Blueprint in Render and how to move a database with pg_dump.
A small team gets deploys, databases, TLS and logs without owning a server, and the first outage on a self-managed box usually costs more than the $7 it saved. Render also lets you grow from one service to a full stack with private networking, workers and cron on the same bill.
Estimate · A VPS with a couple of GB of RAM runs several small apps and a Postgres container for a few dollars a month; add storage for backups if you ship them off-box. The build is token usage on your agent plan.
| Plan | Monthly | Annual, per month | What you get |
|---|---|---|---|
| Hobby workspace | $0/workspace | — | Up to 25 services, 5 GB of bandwidth, 500 build pipeline minutes, single-service previews, custom domains, firewall and DDoS mitigation, chat support. Compute is billed on top. |
| Pro workspace | $25/workspace | — | Unlimited seats and services, 25 GB of bandwidth, 1,000 build minutes, full-stack previews, horizontal autoscaling, isolated environments, audit logs. Compute is billed on top. |
| Scale workspace | $499/workspace | — | Everything in Pro plus multiple workspaces, 1 TB of bandwidth, HIPAA-compliant workspaces, SAML SSO and SCIM, advanced roles. Compute is billed on top. |
| Enterprise | custom | — | Contractual uptime SLAs, a dedicated technical account team, a support Slack channel. |
| Web service: Starter | $7 | — | 512 MB RAM, 0.5 CPU, always on, billed prorated to the second. |
| Postgres: Basic | $6 | — | 256 MB RAM, 1 GB storage included, point-in-time recovery, logical exports. |
The Hobby workspace is $0, and Free compute plans cover web services, Postgres and Key Value with tight limits.
Kinda. The core is a weekend build with the prompt on this page, but real gaps remain: Managed Postgres with point-in-time recovery and automatic failover, Regions around the world, a CDN and DDoS filtering.
About $7 a month on the Hobby workspace + Starter instance plan, $84 a year (checked 2026-10-20).
Managed Postgres with point-in-time recovery and automatic failover; Regions around the world, a CDN and DDoS filtering; Autoscaling and zero-downtime deploys across several instances; Preview environments for every pull request; Someone else keeping the servers patched and on call. If any of those matter to you, keep paying.
Yes: Coolify (open source), Dokploy (open source), Dokku (open source).