Overview
Sptfy.in uses a split-stack architecture:- Backend: PocketBase in Docker on a VPS, reverse proxied via Nginx
- Frontend: SvelteKit app deployed on Cloudflare Pages
main branch:
- Backend: GitHub Actions → VPS
- Frontend: Cloudflare Pages auto-deploy
Architecture Diagram
Backend Deployment (VPS)
Prerequisites
- VPS with Docker installed (see Installation)
- Domain name configured in DNS
- SSH access to VPS
- GitHub repository (for automated deployments)
Nginx Reverse Proxy Setup
Nginx exposes PocketBase (running onlocalhost:8091) to the internet via HTTPS.
Obtain SSL certificate
- Enter your email
- Agree to terms of service
- Choose whether to redirect HTTP to HTTPS (recommended: Yes)
- Obtain the certificate
- Update Nginx configuration
- Set up auto-renewal
Automated Deployment with GitHub Actions
The repository includes a GitHub Actions workflow that auto-deploys PocketBase to your VPS on push tomain.
Add GitHub Secrets
Go to your GitHub repository → Settings → Secrets and variables → Actions → New repository secret.Add these secrets:
| Secret Name | Description | Example |
|---|---|---|
VPS_HOST | VPS IP or hostname | 203.0.113.50 |
VPS_USER | SSH username | ubuntu |
VPS_SSH_KEY | SSH private key | -----BEGIN OPENSSH PRIVATE KEY-----... |
Verify workflow file
The workflow is at The workflow triggers on:
.github/workflows/deploy.yml:- Push to
mainwhen PocketBase files change - Manual trigger via GitHub Actions UI
Manual Deployment (Without GitHub Actions)
If you prefer manual deployments:Frontend Deployment (Cloudflare Pages)
Cloudflare Pages auto-builds and deploys the SvelteKit frontend on every push tomain.
Create Cloudflare Pages project
- Go to Cloudflare Dashboard → Pages
- Click Create a project
- Connect to your GitHub repository
- Select the repository (e.g.,
yourusername/sptfyin) - Configure build settings:
- Production branch:
main - Build command:
npm run build(ornpx pnpm install && npx pnpm build) - Build output directory:
.svelte-kit/cloudflare - Root directory:
/(leave empty)
- Production branch:
Set environment variables
In the Cloudflare Pages project → Settings → Environment variables, add:Production variables:Preview variables (optional, for preview deployments):
Get
PUBLIC_TURNSTILE_SITE_KEY from Cloudflare Dashboard → Turnstile → Your Site → Site Key.Configure custom domain (optional)
- Go to project Settings → Custom domains
- Add your domain:
sptfy.in - Cloudflare will automatically configure DNS
- Wait for SSL certificate provisioning (1-5 minutes)
Trigger initial deployment
Push to Monitor the build:
main to trigger deployment:- Go to Cloudflare Pages → Your Project → Deployments
- Watch the build log
- Once completed, visit your site URL
Frontend Build Configuration
The SvelteKit app is configured for Cloudflare Pages viasvelte.config.js:
Cloudflare Pages automatically detects SvelteKit and uses the correct build command. No additional configuration needed.
Deployment Workflow
Full Stack Deployment
When you push tomain, both components deploy:
Deployment Triggers
Backend (PocketBase):- Push to
mainwith changes in:pocketbase/pb_hooks/**pocketbase/pb_migrations/**docker-compose.yml
- Manual trigger via GitHub Actions UI
- Any push to
main - Push to any branch (creates preview deployment)
Rollback Procedures
Frontend Rollback
- Go to Cloudflare Pages → Your Project → Deployments
- Find the previous working deployment
- Click … → Rollback to this deployment
- Instant rollback (no downtime)
Backend Rollback
If you must rollback:Monitoring and Health Checks
PocketBase Health Check
PocketBase exposes a health endpoint:Docker Health Check
Thedocker-compose.yml includes a health check:
(healthy) status.
Status Page (Optional)
The production instance uses BetterStack for uptime monitoring:- Public status page:
https://status.sptfy.in - Monitors both frontend and backend
- Auto-alerts on downtime
You can use any monitoring service (UptimeRobot, Pingdom, etc.). Monitor:
- Frontend:
https://sptfy.in - Backend:
https://pbbase.yourdomain.com/api/health
Troubleshooting
Backend Issues
502 Bad Gateway
Cause: Nginx can’t reach PocketBase. Solution:SSL Certificate Issues
Cause: Let’s Encrypt certificate expired or failed to renew. Solution:GitHub Actions Deployment Failed
Cause: SSH connection failed or health check timeout. Solution:- Check GitHub Actions logs for error details
- Verify VPS is accessible:
- Verify secrets are correct (VPS_HOST, VPS_USER, VPS_SSH_KEY)
- Manually deploy and check for errors:
Frontend Issues
Build Failed on Cloudflare Pages
Cause: Dependency installation or build error. Solution:- Check build logs in Cloudflare Pages dashboard
- Verify
package.jsondependencies are correct - Test build locally:
- If using pnpm, ensure Cloudflare Pages uses the correct install command:
Environment Variables Not Working
Cause: Variables not set or incorrect scope (Production vs Preview). Solution:- Go to Cloudflare Pages → Settings → Environment variables
- Verify variables are set for the correct environment
- Re-deploy to apply changes:
CORS Errors
Cause: Frontend can’t connect to backend due to CORS policy. Solution:- Verify
PUBLIC_POCKETBASE_URLis set correctly in Cloudflare Pages - Check PocketBase CORS settings in Admin UI → Settings → CORS
- Add your frontend domain to allowed origins:
Security Checklist
Secure PocketBase admin
- Restrict admin panel access via Nginx IP whitelist
- Use strong admin password (16+ characters)
- Change default admin email from example domain
Secure VPS
- Disable root SSH login
- Use SSH keys (disable password auth)
- Enable UFW firewall (allow 22, 80, 443)
- Keep system updated (
sudo apt update && sudo apt upgrade)
Secure secrets
- Use production Cloudflare Turnstile keys (not test keys)
- Set proper
.envfile permissions (chmod 600) - Store GitHub secrets securely (VPS_SSH_KEY)
- Rotate secrets periodically
Enable HTTPS
- SSL certificate for PocketBase (Let’s Encrypt)
- SSL certificate for frontend (Cloudflare auto-provisions)
- Redirect HTTP to HTTPS in Nginx
Performance Optimization
Backend Optimization
-
Enable Nginx caching for static assets:
-
Optimize PocketBase indexes:
- Add indexes on frequently queried fields (e.g.,
slug,user) - Review slow query logs in PocketBase admin
- Add indexes on frequently queried fields (e.g.,
-
Increase VPS resources if needed:
- Monitor CPU/RAM usage:
htop - Upgrade VPS plan if consistently over 80% utilization
- Monitor CPU/RAM usage:
Frontend Optimization
Cloudflare Pages provides:- Global CDN (automatic)
- HTTP/3 support (automatic)
- Auto-minification (automatic)
- Image optimization (configure in Cloudflare dashboard)
Next Steps
You now have a fully deployed sptfy.in instance! Recommended next steps:- Set up uptime monitoring
- Configure automated backups
- Customize the frontend (logo, colors, domain)
- Add custom analytics (Plausible, Umami, etc.)
- Configuration - Advanced configuration options
- Database Setup - Manage PocketBase collections
- Installation - Review installation steps