2.4 KiB
Deploying CluPilot on a fresh server
Developed locally, deployed by pulling. Two scripts do the work:
# once, on a fresh Debian/Ubuntu server as root
bash deploy/install.sh
# afterwards, to bring it up to date
cd /opt/clupilot && bash deploy/update.sh
What the installer does
Docker, git and wireguard-tools; clone into /opt/clupilot; generate every
secret (APP_KEY, VPN_CONFIG_KEY, database password, Reverb keys); start the
stack; migrate; create the WireGuard hub and print its public key; create your
Owner account; close the firewall down to 22, 80, 443 and 51820/udp.
It is safe to re-run: an existing .env is kept and the hub key is never
regenerated — doing so would silently disconnect every onboarded host.
Every prompt has an environment variable, so it can also run unattended:
GIT_TOKEN=… ADMIN_EMAIL=… ADMIN_PASSWORD=… APP_DOMAIN=app.clupilot.com \
ADMIN_DOMAIN=admin.clupilot.com bash deploy/install.sh
Order of the update
Migrations run before the new containers take traffic: code that expects a
column the database does not have yet answers with 500s. The image is rebuilt
only when docker/, composer or npm manifests actually changed. Queue workers
are restarted at the end — they are long-running PHP processes and keep the old
classes in memory otherwise. That one bit us during development: a fixed job
kept failing until the worker was restarted.
What the installer deliberately leaves to you
- DNS and TLS. Put a reverse proxy in front (Zoraxy, Caddy, nginx). The
console hostname must not be publicly resolvable:
/adminanswers only on the hostnames inADMIN_HOSTSand 404s everywhere else, but keeping it out of public DNS is the layer above that. STRIPE_WEBHOOK_SECRET. Stripe dashboard → Developers → Webhooks →https://<app-domain>/webhooks/stripe, eventscheckout.session.completedandcheckout.session.async_payment_succeeded. The secret starts withwhsec_and differs between test and live mode.- Backups. At minimum the MariaDB volume and
/etc/wireguardin thewireguardvolume — losing the hub key means re-peering every host.
Hiding the site while you build
Settings → Website visibility. Outsiders then get a placeholder (503,
noindex), while anyone on the management VPN and any signed-in operator keeps
seeing the real thing. The console stays reachable either way, so the switch can
always be flipped back.