Overview of deployment options for ThinkCodeShip templates. Learn when to choose Cloudflare Pages, Netlify, Fly.io, or Dokploy for your application.
Deployment Overview
Deploying your application is the final step in making it available to users. This chapter provides an overview of deployment options for ThinkCodeShip templates, helping you choose the right platform for your needs.
Development Tools Setup
Before deploying, set up your development environment with modern tools:
Install mise (Version Manager)
mise manages programming language versions:
# macOS/Linux
curl https://mise.run | sh
# Add to your shell
echo 'eval "$(mise activate)"' >> ~/.bashrc
source ~/.bashrcInstall pnpm (Package Manager)
We recommend pnpm over npm for faster, more reliable installs:
# Install pnpm
curl -fsSL https://get.pnpm.io/install.sh | sh -
# Or via mise
mise use -g nodejs@latest
npm install -g pnpmWhy pnpm?
- Faster: Content-addressable storage with parallel downloads
- Disk efficient: Shared package store across projects
- Strict: Prevents phantom dependencies (accessing packages not explicitly declared)
- Reliable: Deterministic lockfile ensures reproducible builds
All frontend commands in this guide use pnpm. Replace with your preferred package manager if needed.
Deployment Architecture
ThinkCodeShip templates use a separate frontend and backend deployment model:
┌─────────────────┐ ┌─────────────────┐
│ SvelteKit │◄───────►│ Phoenix │
│ Frontend │ HTTP │ Backend │
│ (Cloudflare/ │ │ (Fly.io/ │
│ Netlify) │ │ Dokploy) │
└─────────────────┘ └─────────────────┘
│ │
│ ┌──────┴──────┐
│ │ PostgreSQL │
│ │ Database │
│ └─────────────┘
│
┌────┴────┐
│ CDN │
│ Assets │
└─────────┘Why separate deployments?
- Frontend can be served from edge locations (faster)
- Backend can scale independently
- Different platforms optimized for each layer
- Simpler maintenance and updates
Platform Comparison
Frontend Deployment
| Platform | Best For | Free Tier | Custom Domains | SSL |
|---|---|---|---|---|
| Cloudflare Pages | SvelteKit apps | Generous | Yes | Auto |
| Netlify | Static sites, JAMstack | Generous | Yes | Auto |
Note: We recommend Cloudflare Pages over Vercel because Cloudflare does not use your data for AI training.
Both platforms offer:
- Git-based deployment
- Preview deployments for PRs
- Edge network distribution
- Automatic HTTPS
- Environment variable management
Backend Deployment
| Platform | Best For | Pricing | Elixir Support | Managed DB |
|---|---|---|---|---|
| Fly.io | Elixir/Phoenix apps | Pay per usage | Native | Yes |
| Dokploy | Self-hosted Docker | Server cost | Via Docker | Self-managed |
| Render | Simple deployments | Free tier | Via Docker | Yes |
Choosing Your Deployment Strategy
Quick Start (Free)
Frontend: Cloudflare Pages or Netlify (free tier) Backend: Fly.io (free tier includes small instance) Database: Fly.io PostgreSQL (free tier)
Best for: MVPs, prototypes, side projects
Production (Paid)
Frontend: Cloudflare Pro or Netlify Pro Backend: Fly.io (scaled instances) Database: Fly.io PostgreSQL (high availability)
Best for: Production applications, business-critical systems
Self-Hosted
Frontend: Dokploy on VPS Backend: Dokploy on VPS Database: PostgreSQL on same VPS or managed
Best for: Cost optimization, data sovereignty, learning
Environment Configuration
Frontend Environment Variables
# .env.production
PUBLIC_API_URL=https://tcs-svc-9k2m.yourapp.com
PUBLIC_GRAPHQL_ENDPOINT=https://tcs-svc-9k2m.yourapp.com/graphql
PUBLIC_APP_URL=https://yourapp.comSecurity Note: The backend uses an obscure subdomain (tcs-svc-9k2m) instead of predictable names like api or backend. Attackers constantly scan for common subdomains. An unguessable name protects your backend from automated reconnaissance and significantly reduces attack volume. Always choose unique, random-looking subdomains for your services.
Backend Environment Variables
# Runtime environment
DATABASE_URL=postgres://user:pass@host:5432/db
SECRET_KEY_BASE=long-random-string
GUARDIAN_SECRET_KEY=another-long-string
FRONTEND_URL=https://yourapp.comDeployment Checklist
Before deploying any application:
Security
- Change default secrets (SECRET_KEY_BASE, GUARDIAN_SECRET_KEY)
- Enable HTTPS only
- Configure CORS properly
- Set secure cookie flags
- Review environment variables (no .env files in git)
Database
- Run migrations
- Seed initial data if needed
- Configure backups
- Set connection limits appropriately
Application
- Set production environment
- Configure logging
- Set up error tracking (Sentry, etc.)
- Verify email sending works
Monitoring
- Set up uptime monitoring
- Configure alerts
- Set up log aggregation
- Configure performance monitoring
Deployment Process
Typical Workflow
Prepare
- Run tests locally
- Update CLAUDE.md if needed
- Verify environment variables
Deploy Backend
- Push to main branch
- Run database migrations
- Verify health checks pass
Deploy Frontend
- Update API endpoint URLs
- Build and deploy
- Verify connectivity to backend
Verify
- Test critical user flows
- Check error logs
- Verify SSL certificates
Monitor
- Watch for errors
- Monitor performance
- Check user feedback
Rollback Strategy
Always have a rollback plan:
Database Migrations
- Make migrations backward-compatible when possible
- Test rollback procedures
- Keep database backups
Application Deployment
- Tag releases in git
- Keep previous version artifacts
- Know how to quickly revert
Frontend Deployment
- Both Cloudflare Pages and Netlify keep deployment history
- Can instantly rollback to previous deployment
- Preview deployments for testing
Next Steps
Choose your deployment guides:
SvelteKit Frontend:
Phoenix Backend:
General:
Start with Deploying SvelteKit to Cloudflare Pages