VPS Deployment Guide
Relevant source files
The following files were used as context for generating this wiki page:
This guide describes the process and architecture for deploying PuppyPad on a Virtual Private Server (VPS). PuppyPad uses a containerized architecture managed by Docker Compose, utilizing Caddy as a reverse proxy with automated TLS certificate management. The deployment process is streamlined through an installation script that handles environment setup, container orchestration, and automated maintenance tasks.
Sources: README.md:120-136, PLAN.md:15-30
System Architecture
PuppyPad runs as a set of three primary Docker containers that interact via a shared data volume and internal network.
- app: The core Express.js server handling routing, API requests, and dashboard logic.
- caddy: A reverse proxy that manages wildcard TLS certificates via Cloudflare DNS-01 challenges and routes traffic to the
appcontainer. - shots: A Playwright-based worker that generates screenshots of member sites by polling the internal API.
The architecture is designed for single-VPS hosting, with all persistent data stored under the ./data directory.
Sources: PLAN.md:15-35, src/server.js:203-214
Prerequisites
Before starting the deployment, you must configure external services:
- Cloudflare DNS: Point
Arecords for your base domain and wildcard (e.g.,example.comand*.example.com) to the VPS IP. These must be set to DNS only (grey cloud). - Cloudflare API Token: Create a token using the "Edit zone DNS" template for the specific zone. This allows Caddy to complete DNS-01 challenges for wildcard certificates.
- Software Dependencies: The VPS must have the following installed:
- Docker with the Compose plugin.
curl,jq, andcron.flock,sha256sum,tar, andtimeout.
Sources: README.md:121-125, scripts/install.sh:35-37
Installation Procedure
Deploy PuppyPad by following these steps:
- Create the application directory and set ownership:
sudo mkdir -p /srv/puppypad && sudo chown "$USER" /srv/puppypad && cd /srv/puppypad - Download and execute the installer:
curl -fsSL https://github.com/DeRusto/puppypad/releases/latest/download/install.sh | sh - Configure environment variables in
.envand.env.caddy. - Launch the containers:
docker compose up -d
Sources: README.md:127-133, scripts/install.sh:163-172
Configuration Parameters
The deployment requires several key environment variables defined in .env.
| Variable | Description | Source |
|---|---|---|
BASE_DOMAIN | The root domain (e.g., puppypad.org). | README.md:131 |
ACME_EMAIL | Email for Let's Encrypt certificate notifications. | README.md:131 |
ADMIN_EMAILS | Comma-separated list of emails that grant admin rights upon confirmation. | src/server.js:28 |
SHOT_TOKEN | Secret token for authenticating the shots worker. | src/server.js:31 |
CF_API_TOKEN | Cloudflare API token (stored in .env.caddy). | README.md:132 |
QUOTA_MB | Storage limit per site (default 500MB). | src/server.js:23 |
Automated Maintenance
The installation script automatically adds maintenance tasks to the host user's crontab.
Upgrade Watcher
The script scripts/upgrade-watch.sh runs every minute. It checks for upgrade requests left by the app in data/upgrade/. The app itself does not have Docker access; it only signals the host watcher to perform the upgrade.
Sources: README.md:162-171, scripts/install.sh:80-84
Nightly Backups
The script scripts/backup.sh runs every night at 03:15. It performs an online backup of the SQLite database and archives member files into ./backups. It retains the last 14 archives.
Sources: README.md:143-146, scripts/install.sh:81
Deployment Lifecycle
The deployment process handles different modes based on the existing environment.
| Mode | Condition | Result |
|---|---|---|
| Fresh | No VERSION file or .env. | Full installation, template environment files created. |
| Upgrade | VERSION file exists. | Pulls images, backs up data, switches files, and restarts. |
| Migrate | .env and DB exist but no VERSION. | Moves a git-based deployment to official release tracking. |
Sources: scripts/install.sh:102-105, README.md:139-141
Rollback Logic
If an upgrade fails the health check, the install.sh script automatically reverts the deployment.
- Backup: A backup is taken before files are touched.
- File Swap: Previous files are stored in
.upgrade/prev.tar. - Health Check: The script waits for the
/healthzendpoint to return200 OKand ensures all containers stay running for 15 seconds. - Reversion: If unhealthy, the script restores files from
prev.tarand reverts.envimage digests.
Sources: scripts/install.sh:205-235, README.md:155-160
Conclusion
PuppyPad deployment centers on a robust install.sh script that manages the transition between releases while ensuring data safety through automated backups. By decoupling the upgrade orchestration from the application container, the system maintains a secure security boundary while allowing for seamless "one-click" updates from the administrative dashboard.