Deploying Sellf to Coolify
Coolify is a PaaS for managing applications on your own servers. It comes in two flavors:
| Coolify Self-Hosted | Coolify Cloud | |
|---|---|---|
| Where the Coolify dashboard runs | On your own VPS | On Coolify’s servers |
| Where your Sellf store runs | On your own VPS (same machine as Coolify, or a separate one) | On your own VPS (you connect it to the Cloud dashboard) |
| Cost | Free forever | $5/mo for 2 servers + $3/mo per extra server |
| You manage | Coolify itself + your apps + your servers | Just your apps + your servers (Coolify auto-updates itself) |
| Backups, alerts, auto-update | DIY | Included |
| Best for | DIY tinkerers, complete control, zero recurring cost | People who want managed Coolify but still own their data and hardware |
Key point common to both: your Sellf store always runs on a VPS that you rent (Hetzner, DigitalOcean, Contabo, etc.). Coolify Cloud doesn’t host your apps — it only hosts the control panel. So both options require you to have a server with enough RAM (see Requirements below).
This guide covers both modes. Pick one and follow only the steps for that mode where they differ.
Why pick Coolify at all?
Section titled “Why pick Coolify at all?”Pick Coolify if:
- You have (or are willing to rent) a VPS with 8 GB+ RAM. The Sellf build itself needs ~3 GB free for
bun run buildon Next.js 16 with Turbopack; on a 4 GB VPS Coolify + Postgres + Redis already eat ~1 GB, leaving the build to OOM. Verified 2026-05-27: 4 GB Hetzner CX22 OOM-kills the build; 8 GB Hetzner CX32 builds in ~8 minutes and serves successfully. - You want everything on your own infrastructure (no Supabase Cloud, no Vercel)
- You’re OK with self-hosting Postgres (and your own backups, on self-hosted Coolify)
- You want “deploy and forget” — Coolify handles auto-renew TLS, automatic redeploys on
git push, container restarts
Pick Coolify Cloud if you want all that AND you’d rather not run the Coolify dashboard yourself (auto-updates, backups, email alerts handled for you, ~$5/mo).
Pick Coolify Self-Hosted if you want zero recurring software bills (you still pay your VPS provider) AND you’re comfortable maintaining the Coolify management UI yourself (docker compose pull && restart once a month).
Don’t pick Coolify if any of these fit you better:
- You want free-tier hosting: Coolify still needs your own VPS, ~$5–10/mo minimum. See DEPLOYMENT-VERCEL-NETLIFY.md — Vercel + Supabase Cloud both have free tiers.
- You want the smallest possible footprint: see DEPLOYMENT-MIKRUS.md — Sellf alone runs on a $9/year mikr.us VPS without Docker.
Shortest path — use the StackPilot installer
Section titled “Shortest path — use the StackPilot installer”StackPilot’s install-coolify.sh automates this entire guide. Two invocation styles depending on which Coolify flavor you use:
Self-hosted Coolify (default):
./apps/sellf/install-coolify.sh \ --ssh-host <vps-alias> \ --repo-path /path/to/sellfThe script installs Coolify on the target (if absent), registers an admin user, generates an API token, creates the application, sets all the env vars, applies database migrations, and creates the Stripe webhook. Total time: ~12 minutes on a fresh VPS, ~7 minutes if Coolify is already running.
Coolify Cloud:
./apps/sellf/install-coolify.sh \ --coolify-cloud \ --coolify-token <your-api-token> \ --server-uuid <uuid-of-server-already-added-to-cloud> \ --repo-path /path/to/sellfFor Cloud, you’ve already done the one-time setup in Coolify Cloud (sign in, add your server, generate an API token). The script then just creates the project + app + env vars + Stripe webhook against https://app.coolify.io/api/v1/.... Total time: ~7 minutes.
Verified on a Hetzner CX32 (8 GB RAM) 2026-05-27.
If you prefer the manual flow (or are deploying without root SSH access on the VPS), follow the steps below.
Step 1 — Get Coolify running
Section titled “Step 1 — Get Coolify running”Mode A: Self-hosted (install Coolify on your VPS)
Section titled “Mode A: Self-hosted (install Coolify on your VPS)”If you don’t already have Coolify on a VPS, install it on Debian/Ubuntu:
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | sudo bashAfter install, open http://<your-vps-ip>:8000 and complete the first-run wizard (admin email + password). The wizard already adds the host VPS as your first “server” automatically.
Full Coolify install docs: https://coolify.io/docs/installation
Mode B: Coolify Cloud (sign up + connect a server)
Section titled “Mode B: Coolify Cloud (sign up + connect a server)”- Sign up at https://app.coolify.io
- Pick a plan ($5/mo for 2 servers is enough for one Sellf instance + room to grow)
- In the Cloud dashboard, click Servers → New Server
- Coolify will give you an SSH public key. Add it to your VPS’s
~/.ssh/authorized_keys(Coolify Cloud needs to SSH into your VPS to deploy apps there) - Enter your VPS’s IP address in the form and click Validate
- Once validation passes, your server is ready for deployments
For the rest of this guide, the Coolify dashboard URL is https://app.coolify.io (Cloud) instead of http://<your-vps-ip>:8000 (Self-Hosted). All other steps work identically — same UI, same API.
Step 2 — Create the application
Section titled “Step 2 — Create the application”In Coolify dashboard:
- Projects → New Project → name it
sellf - Inside the project, New Resource → Public Repository
- Paste:
- Git Repository:
https://github.com/jurczykpawel/sellf - Branch:
main - Build Pack:
Docker Compose - Compose File Location:
docker-compose.fullstack.yml
- Git Repository:
- Click Continue
Step 3 — Set environment variables
Section titled “Step 3 — Set environment variables”Coolify will read the compose file and ask for env vars referenced in it. You’ll need to fill in:
Generated locally (run in your terminal first)
Section titled “Generated locally (run in your terminal first)”echo "POSTGRES_PASSWORD=$(openssl rand -base64 24 | tr -d '=+/' | cut -c1-24)"echo "JWT_SECRET=$(openssl rand -base64 32)"echo "ANON_KEY=<generate via supabase JWT signing tool, see Step 3.1>"echo "SERVICE_ROLE_KEY=<same>"echo "CHECKOUT_BINDING_SECRET=$(openssl rand -base64 32)"echo "APP_ENCRYPTION_KEY=$(openssl rand -base64 32)"echo "LOGINWALL_SECRET=$(openssl rand -hex 32)"Step 3.1 — Generate Supabase JWT keys
Section titled “Step 3.1 — Generate Supabase JWT keys”Self-hosted Supabase needs an ANON_KEY and SERVICE_ROLE_KEY signed with your JWT_SECRET. Use Supabase’s online tool: https://supabase.com/docs/guides/self-hosting#api-keys (the page has a built-in generator). Or run locally:
JWT_SECRET="<your value from above>"# anon key:docker run --rm -i node:20-alpine sh -c "npm i -g jsonwebtoken-cli && jwt encode --secret '$JWT_SECRET' '{\"role\": \"anon\", \"iss\": \"supabase\"}'"# service_role key:docker run --rm -i node:20-alpine sh -c "npm i -g jsonwebtoken-cli && jwt encode --secret '$JWT_SECRET' '{\"role\": \"service_role\", \"iss\": \"supabase\"}'"Pasted into Coolify
Section titled “Pasted into Coolify”POSTGRES_PASSWORD=<from step 3>JWT_SECRET=<from step 3>ANON_KEY=<from step 3.1>SERVICE_ROLE_KEY=<from step 3.1>SUPABASE_URL=http://kong:8000 # internal Docker networkSUPABASE_ANON_KEY=<same as ANON_KEY>SUPABASE_SERVICE_ROLE_KEY=<same as SERVICE_ROLE_KEY>SITE_URL=https://<your-coolify-app-domain>STRIPE_SECRET_KEY=sk_test_… # or sk_live_… for productionSTRIPE_PUBLISHABLE_KEY=pk_test_…# STRIPE_WEBHOOK_SECRET — leave unset; you'll register the webhook from# the Sellf admin in Step 5 and the signing secret will land in the DB.CHECKOUT_BINDING_SECRET=<from step 3>APP_ENCRYPTION_KEY=<from step 3>LOGINWALL_SECRET=<from step 3>TRUSTED_PROXY=trueStep 4 — Deploy
Section titled “Step 4 — Deploy”Click Deploy in Coolify. First deploy takes 5–10 minutes (it builds Sellf’s Next.js bundle and pulls Supabase images). Coolify shows live build logs.
No separate migration step — docker-compose.fullstack.yml mounts ./supabase/migrations into the Postgres container’s /docker-entrypoint-initdb.d, so migrations run automatically on first boot. This is the main reason Coolify is closer to true one-click than Vercel/Netlify.
Step 5 — Sign up + register Stripe webhook (1 min, 1 click)
Section titled “Step 5 — Sign up + register Stripe webhook (1 min, 1 click)”After deploy, your app is at https://<your-coolify-app-domain>.
- Open the URL → sign up with your email → click the magic link from your inbox. The first registered user automatically becomes admin.
- In the admin, go to Settings → Payments (or
/dashboard/settings). - API keys card: paste your Stripe Publishable Key and Secret Key. Saved encrypted to your Supabase DB.
- Stripe Webhook card: click Register webhook. Sellf calls Stripe for you — creates the endpoint pointing at
https://<your-domain>/api/webhooks/stripe, subscribes to all the events it needs, and stores the signing secret encrypted instripe_configurations. No Stripe Dashboard hopping, no env var dance.
Env-config alt: If you’d rather keep secrets in Coolify env vars (e.g. for CI-driven redeploys), use the legacy flow — create the webhook manually at https://dashboard.stripe.com/test/webhooks, paste the
whsec_…into Coolify’sSTRIPE_WEBHOOK_SECRET, restart. Same outcome.
Step 6 — Custom domain + TLS
Section titled “Step 6 — Custom domain + TLS”In Coolify dashboard:
- Open your Sellf application
- Domains → Add Domain → enter your custom domain (e.g.
shop.example.com) - Point your DNS A record at the Coolify VPS IP
- Coolify auto-provisions a Let’s Encrypt cert in ~30 seconds
Update SITE_URL env var to match the new domain, restart.
Backup
Section titled “Backup”Coolify can’t see inside the Sellf Supabase. Set up your own backups:
# In Coolify dashboard → your project → Backups# OR via cron on the VPS:0 3 * * * docker exec sellf-db pg_dumpall -U postgres > /backups/sellf-$(date +%F).sqlFor S3-compatible offsite backups, see vault/brands/_shared/infra/INDEX.md for the backup-host-restic.sh pattern.
Update Sellf
Section titled “Update Sellf”In Coolify dashboard:
- Open your Sellf app
- Deployments → Redeploy — pulls latest
mainfrom GitHub, rebuilds - Migrations in newer Sellf versions run automatically on container restart (idempotent)
If you want auto-deploy on every git push to main, enable Webhooks → GitHub in Coolify project settings.
Troubleshooting
Section titled “Troubleshooting”Postgres container restarts in a loop
Section titled “Postgres container restarts in a loop”Symptom: sellf-db container keeps restarting, logs say FATAL: password authentication failed.
Cause: POSTGRES_PASSWORD env var was changed after the first boot. Postgres data dir was initialized with the old password; the new password can’t authenticate.
Fix: stop the stack, docker volume rm sellf_postgres_data, redeploy. Destroys all data — make sure you have a backup if you’re past first-deploy.
Kong API gateway returns 404 on every request
Section titled “Kong API gateway returns 404 on every request”Cause: missing or invalid supabase/kong.yml file in the repo. The compose mounts it read-only.
Fix: check the file exists at the path docker-compose.fullstack.yml expects (./supabase/kong.yml).
”Service quota exceeded” from Coolify
Section titled “”Service quota exceeded” from Coolify”Coolify free tier allows N resources per server. Check the Coolify pricing page — if you’re over, either delete unused resources or upgrade.
Build OOM-kills bun on a 4 GB VPS
Section titled “Build OOM-kills bun on a 4 GB VPS”Symptom: Coolify shows the deploy as “in progress” but the build container disappears with no error in the UI logs. dmesg on the host shows:
Out of memory: Killed process <pid> (bun) total-vm:76GB ...Cause: Next.js 16 + Turbopack + bun run build peaks around 3 GB resident, and Coolify’s own services + Postgres + Redis already use ~1 GB. A 4 GB VPS doesn’t fit.
Fix: upgrade to 8 GB+ (Hetzner CX32, Contabo VPS 200, Linode g6-standard-2, etc.) and redeploy. Or build the image elsewhere and let Coolify just pull it (see “Build server” in Coolify settings).
Stripe webhooks return 400 “Missing signature”
Section titled “Stripe webhooks return 400 “Missing signature””Same issue as the Vercel/Netlify guide — STRIPE_WEBHOOK_SECRET env var doesn’t match the Stripe Dashboard’s signing secret. Re-copy and restart the container.
Why this isn’t published as a “Coolify Template” yet
Section titled “Why this isn’t published as a “Coolify Template” yet”Coolify supports one-click templates from a marketplace. Sellf doesn’t have one yet because:
- The fullstack compose file uses Supabase images that need JWT-signed keys (Step 3.1) — Coolify’s template format doesn’t have native support for “generate this JWT, sign with that other generated value.” You’d still need the manual JWT step.
- Supabase Self-Hosted is a moving target (auth/realtime/storage versions change). The fullstack compose pins to known-good versions; a template would need maintenance.
If someone wants to contribute a Coolify template that bundles a JWT-signing init container, it would be welcome — open an issue.