Deploy Pinchy on DigitalOcean
DigitalOcean is a solid choice for running Pinchy — straightforward interface, predictable pricing, and data centers on multiple continents. If your team is distributed or you want to keep your AI agents close to your users, DigitalOcean’s global footprint makes that easy.
Why DigitalOcean for self-hosted AI agents?
Section titled “Why DigitalOcean for self-hosted AI agents?”- Global data centers — New York, San Francisco, London, Amsterdam, Frankfurt, Singapore, Bangalore, Sydney, and more. Pick the region closest to your team.
- Simple pricing — A Droplet with 4 GB RAM starts at around $24/month with predictable costs.
- Team accounts — Built-in team management for sharing infrastructure access.
What you’ll need
Section titled “What you’ll need”- A DigitalOcean account (free to create, pay-as-you-go)
- A domain name (optional for testing, required for production HTTPS)
- An LLM provider API key (Anthropic, OpenAI, or Google) — you’ll enter this in Pinchy’s setup wizard
Create your Droplet
Section titled “Create your Droplet”A “Droplet” is DigitalOcean’s name for a virtual server.
-
Log in to the DigitalOcean Control Panel
Click Create → Droplets.
-
Choose a region
Pick the datacenter closest to you or your users. Pinchy works in any region.
-
Choose an image
Select Ubuntu and keep the default version (24.04 LTS x64).
-
Choose a size
Under Droplet Type, keep Basic (Shared CPU). Under CPU options, Regular (SSD) is fine. Pick the $24/mo plan (4 GB RAM, 2 CPUs).
-
Choose authentication
Select SSH Key or Password. Either works for the automated setup below — you’ll need SSH access later for production hardening.
-
Paste the setup script
Expand Advanced Options and check Add Initialization scripts (free). Paste the following script into the text field. It automatically installs Docker, deploys Pinchy, sets up a firewall, and adds swap.
cloud-init.yml #cloud-config# Pinchy v0.5.4 — Automated VPS Setup# https://docs.heypinchy.com/guides/vps-deployment/## This cloud-init script installs Caddy (reverse proxy), Docker, and Pinchy,# configures a firewall, and adds swap. Paste it into the "User Data" field# when creating your server.## After boot, visit http://<your-server-ip>. Caddy shows a loading page while# images are pulling, then seamlessly hands off to Pinchy — no refresh needed.# To enable HTTPS later, replace `:80` in /etc/caddy/Caddyfile with your domain# and run `systemctl reload caddy` — Let's Encrypt is automatic.runcmd:# Add Caddy's official Cloudsmith apt repository (GPG-verified)- apt-get update -qq- apt-get install -y -qq debian-keyring debian-archive-keyring apt-transport-https curl gpg- curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg- curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list- apt-get update -qq# Stage loading page for Caddy's fallback upstream- mkdir -p /var/www/pinchy-loading- curl -fsSL https://github.com/heypinchy/pinchy/releases/download/v0.5.4/installing.html -o /var/www/pinchy-loading/index.html- sed -i "s/INSTALL_START_TIME/$(date +%s)000/" /var/www/pinchy-loading/index.html# Write Caddyfile BEFORE installing caddy, so Caddy's first start uses our config- mkdir -p /etc/caddy- |cat > /etc/caddy/Caddyfile <<'EOF'# Pinchy reverse proxy# Primary upstream: Pinchy on 127.0.0.1:7777# Fallback upstream: local loading page on 127.0.0.1:9999## lb_policy first → prefer primary; fall back only when primary is unreachable.# lb_try_duration 1s → fail fast so users never wait for a dead backend.# fail_duration 5s → mark unreachable backend as dead for 5s before retry.## To enable HTTPS: replace `:80` with your domain (e.g. pinchy.example.com)# and run `systemctl reload caddy`. Caddy provisions Let's Encrypt automatically.:80 {reverse_proxy 127.0.0.1:7777 127.0.0.1:9999 {lb_policy firstlb_try_duration 1sfail_duration 5s}}:9999 {bind 127.0.0.1handle /api/* {respond 503}handle {root * /var/www/pinchy-loadingtry_files /index.htmlfile_server}}EOF# Install Caddy, Docker, and UFW in one apt call (Caddy starts with our Caddyfile).# --force-confold keeps our pre-staged /etc/caddy/Caddyfile without dpkg's# interactive conffile prompt, which would otherwise fail cloud-init (no stdin)# and leave the caddy package in iU state (postinst skipped, `caddy` user never# created, systemd start fails with exit 217/USER).- DEBIAN_FRONTEND=noninteractive apt-get install -y -qq -o Dpkg::Options::=--force-confold caddy docker.io docker-compose-v2 ufw- systemctl enable --now caddy- systemctl reload caddy# Firewall- ufw allow OpenSSH- ufw allow 80/tcp- ufw allow 443/tcp- ufw --force enable# Docker- systemctl enable docker- systemctl start docker# Swap (recommended for 4 GB servers)- fallocate -l 2G /swapfile- chmod 600 /swapfile- mkswap /swapfile- swapon /swapfile- echo '/swapfile none swap sw 0 0' >> /etc/fstab# Generate pinned secrets — Pinchy keeps its secure 127.0.0.1:7777 default,# reachable only via Caddy on the same host.- mkdir -p /opt/pinchy- echo "PINCHY_VERSION=v0.5.4" >> /opt/pinchy/.env- echo "DB_PASSWORD=$(openssl rand -hex 32)" >> /opt/pinchy/.env- echo "BETTER_AUTH_SECRET=$(openssl rand -hex 32)" >> /opt/pinchy/.env- echo "ENCRYPTION_KEY=$(openssl rand -hex 32)" >> /opt/pinchy/.env- chmod 600 /opt/pinchy/.env# Download compose file and pull images (Caddy serves loading page throughout)- curl -fsSL https://raw.githubusercontent.com/heypinchy/pinchy/v0.5.4/docker-compose.yml -o /opt/pinchy/docker-compose.yml- cd /opt/pinchy && docker compose pull# Start Pinchy — Caddy automatically swaps to the primary upstream within 5s- cd /opt/pinchy && docker compose up -d# Wait for Pinchy to be healthy (polled directly, not through Caddy)- for i in $(seq 1 120); do curl -sf http://127.0.0.1:7777/api/health > /dev/null 2>&1 && break; sleep 2; done -
Set the hostname and create the Droplet
Under Finalize Details, change the hostname to
pinchy(or whatever you prefer) and click Create Droplet. It’ll be ready in about 30 seconds, but the setup script needs another 1-2 minutes to pull the Pinchy images. -
Note the IP address
The Droplet’s IPv4 address appears on the dashboard (e.g.,
164.90.x.x). -
Open Pinchy
Visit
http://<your-droplet-ip>in your browser. You’ll see a loading page that tracks the installation progress. Once the images are pulled (typically 1-2 minutes), it automatically redirects to the Pinchy setup wizard.The setup wizard will guide you through creating your admin account and configuring your first LLM provider.
Production setup
Section titled “Production setup”The steps above get Pinchy running over plain HTTP. The cloud-init script already pinned your secrets (DB_PASSWORD, BETTER_AUTH_SECRET, ENCRYPTION_KEY) in /opt/pinchy/.env and installed Caddy as a reverse proxy.
To enable HTTPS, follow the HTTPS setup steps in the Hetzner guide — the cloud-init flow is identical: edit /etc/caddy/Caddyfile, replace :80 with your domain, and reload Caddy. Let’s Encrypt is automatic.
See the VPS Deployment Guide — Production setup for further hardening (domain lock, automatic security updates).
How do I connect to my Droplet to run these commands?
You’ll need to use SSH (Secure Shell) — a way to run commands on a remote server from your terminal.
If you chose password authentication when creating the Droplet:
ssh root@<your-droplet-ip>Enter the password you set (or check your email for the one DigitalOcean generated).
If you chose SSH key authentication, make sure you have the key on your machine, then:
ssh root@<your-droplet-ip>Where do I find the terminal?
- Mac — Open Terminal (search for it in Spotlight with ⌘+Space)
- Windows — Open PowerShell (search in Start menu) or install Windows Terminal
- Linux — Open your terminal app (usually Ctrl+Alt+T)
While connected, every command you type runs on your Droplet. Type exit to disconnect.
Point your domain (optional but recommended)
Section titled “Point your domain (optional but recommended)”To use HTTPS, you need a domain pointing to your Droplet. Add a DNS record at your domain registrar (the service where you registered your domain):
| Type | Name | Value |
|---|---|---|
| A | pinchy (or your preferred subdomain) | Your Droplet’s IP address |
What’s an A record?
An A record is a DNS entry that maps a domain name (like pinchy.example.com) to an IP address (like 164.90.1.23). When someone visits your domain, their browser looks up the A record to find your server.
Look for “DNS records” or “DNS settings” in your domain registrar’s dashboard.
You can also manage DNS directly in DigitalOcean under Networking → Domains.
DigitalOcean-specific tips
Section titled “DigitalOcean-specific tips”Enable backups
Section titled “Enable backups”DigitalOcean offers automated weekly backups for 20% of the Droplet cost. Enable this under Droplet → Backups — it’s the easiest disaster recovery option.
Cloud firewall
Section titled “Cloud firewall”DigitalOcean offers Cloud Firewalls under Networking → Firewalls. For defense in depth, configure the cloud firewall to only allow ports 22, 80, and 443 — in addition to the host firewall (ufw) that the setup script already configured.
Volumes for persistent data
Section titled “Volumes for persistent data”For larger Knowledge Base deployments, attach a DigitalOcean Volume (up to 16 TB) and mount it as a data directory. See Mount Data Directories for details.
Scaling up
Section titled “Scaling up”If you outgrow the 4 GB Droplet, you can resize it in the control panel. Pinchy’s data lives in Docker volumes, so it survives Droplet resizes. Power off the Droplet first, resize, then power back on — downtime is typically under 2 minutes.