Deployment Guide¶
This guide covers deploying Diskover to Railway and Render.
Table of Contents¶
Prerequisites¶
Before deploying, ensure you have:
- ✅ A GitHub repository with your code
- ✅ An account on Railway or Render
- ✅ (Optional) S3 or Backblaze B2 account for storage
Railway Deployment¶
Railway is recommended for its simplicity and automatic environment variable injection.
Step 1: Create Project¶
- Go to railway.app
- Click "New Project"
- Select "Deploy from GitHub repo"
- Authorize Railway to access your repository
- Select your
diskover-apprepository
Step 2: Add PostgreSQL Database¶
- In your Railway project, click "+ New"
- Select "Database" → "PostgreSQL"
- Railway will provision a database and create connection variables
Step 3: Deploy Backend¶
- Click "+ New" → "GitHub Repo"
- Select your repository
- Configure the service:
- Name:
diskover-backend - Root Directory:
backend - Add environment variables (Settings → Variables):
# Database (reference Railway's PostgreSQL variables)
DB_HOST=${{Postgres.PGHOST}}
DB_PORT=${{Postgres.PGPORT}}
DB_USER=${{Postgres.PGUSER}}
DB_PASSWORD=${{Postgres.PGPASSWORD}}
DB_NAME=${{Postgres.PGDATABASE}}
DB_SSLMODE=require
# Server
SERVER_PORT=8080
SERVER_HOST=0.0.0.0
# App
APP_VERSION=v1.0.0
- Railway will auto-detect the Dockerfile and deploy
- Once deployed, note your backend URL (Settings → Networking → Generate Domain)
Step 4: Deploy Frontend¶
- Click "+ New" → "GitHub Repo"
- Select your repository again
- Configure the service:
- Name:
diskover-frontend - Root Directory:
frontend - Build Command:
npm install && npm run build -
Start Command:
npx serve -s dist -p $PORT -
Add environment variable:
-
Generate a domain (Settings → Networking → Generate Domain)
Step 5: Update Frontend API URL¶
Once backend is deployed, update the frontend's VITE_API_BASE_URL to point to your backend domain.
Render Deployment¶
Option A: Using Blueprint (Recommended)¶
- Go to render.com
- Click "New +" → "Blueprint"
- Connect your GitHub repository
- Render will read
render.yamland create all services - Review and approve the configuration
- Fill in any required environment variables (storage credentials if needed)
- Click "Apply"
Render will: - Create a PostgreSQL database - Deploy the backend service - Deploy the frontend static site - Wire everything together automatically
Option B: Manual Deployment¶
1. Create PostgreSQL Database¶
- Click "New +" → "PostgreSQL"
- Configure:
- Name:
diskover-db - Database:
diskover - User:
diskover - Region: Choose closest to you
- Plan: Free (for testing) or Starter (for production)
- Click "Create Database"
- Copy the Internal Database URL from the database info page
2. Deploy Backend¶
- Click "New +" → "Web Service"
- Connect your GitHub repository
- Configure:
- Name:
diskover-backend - Region: Same as database
- Root Directory:
backend - Environment:
Docker - Dockerfile Path:
backend/Dockerfile -
Docker Build Context Directory:
backend -
Add environment variables from the Internal Database URL:
Parse: postgresql://user:password@host:5432/database
DB_HOST=<host-from-internal-url>
DB_PORT=5432
DB_USER=<user-from-internal-url>
DB_PASSWORD=<password-from-internal-url>
DB_NAME=<database-from-internal-url>
DB_SSLMODE=require
SERVER_PORT=8080
SERVER_HOST=0.0.0.0
APP_VERSION=v1.0.0
- Set Health Check Path:
/health - Click "Create Web Service"
- Note your backend URL once deployed
3. Deploy Frontend¶
- Click "New +" → "Static Site"
- Connect your repository
- Configure:
- Name:
diskover-frontend - Root Directory:
frontend - Build Command:
npm install && npm run build -
Publish Directory:
dist -
Add environment variable:
-
Click "Create Static Site"
Post-Deployment¶
1. Verify Backend Health¶
curl https://your-backend-url.railway.app/health
# or
curl https://your-backend-url.onrender.com/health
Expected response:
2. Check Database Migrations¶
Migrations run automatically on backend startup. Check logs to verify:
Railway: Click on backend service → Logs Render: Click on backend service → Logs tab
Look for:
Running migrations...
Applied migration: 001_initial_schema.sql
Applied migration: 002_seed_data.sql
...
Migrations completed successfully
3. Test Frontend¶
- Visit your frontend URL
- Verify it loads correctly
- Test API calls to backend
4. Set Up Custom Domain (Optional)¶
Railway¶
- Go to backend service → Settings → Networking
- Click "Custom Domain" and add your domain
- Add DNS records as instructed
- Repeat for frontend service
Render¶
- Go to service → Settings → Custom Domain
- Add your domain
- Configure DNS records as instructed
Environment Variables Reference¶
Required Backend Variables¶
| Variable | Description | Example |
|---|---|---|
DB_HOST |
Database hostname | dpg-xxx.oregon-postgres.render.com |
DB_PORT |
Database port | 5432 |
DB_USER |
Database user | diskover |
DB_PASSWORD |
Database password | secure-password |
DB_NAME |
Database name | diskover |
DB_SSLMODE |
SSL mode | require (production), disable (dev) |
SERVER_PORT |
Backend port | 8080 |
SERVER_HOST |
Backend host | 0.0.0.0 |
CLERK_SECRET_KEY |
Clerk authentication secret key | sk_test_... |
S3 Storage Variables (Required for Asset Upload)¶
| Variable | Description | Example |
|---|---|---|
S3_ENDPOINT |
S3-compatible endpoint URL | https://bucket.railway.app |
S3_REGION |
AWS region | us-east-1 |
S3_BUCKET |
Bucket name | diskover-assets |
S3_ACCESS_KEY_ID |
Access key ID | your_access_key |
S3_SECRET_ACCESS_KEY |
Secret access key | your_secret_key |
S3_USE_PATH_STYLE |
Use path-style URLs | true (Railway/MinIO), false (AWS) |
S3 Provider Notes:
- Railway Object Storage: Set S3_USE_PATH_STYLE=true
- AWS S3: Set S3_USE_PATH_STYLE=false
- MinIO: Set S3_USE_PATH_STYLE=true
- Backblaze B2: Set S3_USE_PATH_STYLE=true
Required Frontend Variables¶
| Variable | Description | Example |
|---|---|---|
VITE_API_BASE_URL |
Backend API URL | https://diskover-backend.railway.app |
VITE_CLERK_PUBLISHABLE_KEY |
Clerk publishable key for frontend | pk_test_... |
Troubleshooting¶
Backend Won't Start¶
Check Logs: Look for error messages in the service logs.
Common issues:
- ❌ Database connection failed: Verify all DB_* environment variables
- ❌ Port binding failed: Ensure SERVER_HOST=0.0.0.0 and SERVER_PORT=8080
- ❌ Migration failed: Check database permissions
Frontend Can't Connect to Backend¶
- Verify
VITE_API_BASE_URLis set correctly - Check backend is running and healthy:
curl <backend-url>/health - Check CORS settings in backend (should allow your frontend domain)
- Check browser console for errors
Database Connection Issues¶
On Render: - Use Internal Database URL for backend connections (faster, free) - Never use External URL (requires paid plan)
On Railway:
- Use variable references: ${{Postgres.PGHOST}}
- Don't hardcode connection strings
Migrations Not Running¶
Check logs for migration errors. Common issues: - Database user lacks permissions - Migration files not copied to Docker image (check Dockerfile) - Previous migration failed partially
Solution: Check backend/Dockerfile line 29 ensures migrations are copied:
Storage Issues¶
If using S3/Backblaze B2:
1. Verify all STORAGE_* variables are set
2. Check bucket permissions (public read for downloads)
3. For Backblaze: Ensure STORAGE_FORCE_PATH_STYLE=true
4. Test with a simple upload endpoint
SSL Certificate Errors¶
Both Railway and Render provide free SSL certificates. If you see errors:
- Wait a few minutes after deployment
- Try accessing via https:// (not http://)
- Check custom domain DNS records
Cost Estimates¶
Railway (Hobby Plan - $5/month)¶
- PostgreSQL: Included
- Backend: Included (500 hours/month)
- Frontend: Included
- Total: $5/month + usage overages
Render (Free Tier)¶
- PostgreSQL: Free (90 days), then $7/month
- Backend: Free (spins down after 15 min inactivity)
- Frontend: Free
- Total: Free for 90 days, then $7/month
Note: Render's free tier has spin-down delays (30-60s on first request).
Next Steps¶
- ✅ Deploy to Railway or Render
- ✅ Verify health endpoints
- ✅ Test full application flow
- ✅ Set up monitoring (Sentry, LogRocket, etc.)
- ✅ Configure custom domain
- ✅ Set up CI/CD for automatic deployments
- ✅ Configure environment-specific settings