Deployment
Deployment
Overview
| Service | Platform | Trigger |
|---|---|---|
| Frontend | Vercel | Auto on push to main |
| Backend | Render | GitHub Actions deploy hook on push to main |
| Database | Neon | Managed PostgreSQL — no deployment needed |
Database (Neon)
- Go to neon.tech → New project
- Name it
shiftwise, pick the closest region - Copy the connection string from Dashboard → Connection string:
postgresql://[USER]:[PASSWORD]@[HOST]/[DBNAME]?sslmode=require
Backend (Render)
- Go to render.com → New → Web Service
- Connect your GitHub repo
- Set these options:
- Root directory:
backend - Build command:
npm install && npx prisma generate && npm run build - Start command:
node dist/index.js
- Root directory:
-
Add environment variables:
Variable Value DATABASE_URLYour Neon connection string JWT_ACCESS_SECRETRandom 64-char hex string JWT_REFRESH_SECRETDifferent random 64-char hex string FRONTEND_URLhttps://your-app.vercel.appNODE_ENVproductionPORT3001Generate JWT secrets with:
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))" - Click Deploy
- After first deploy, run migrations from the Render shell:
npx prisma migrate deploy && npx tsx prisma/seed.ts - Go to Settings → Deploy Hook → copy the URL
- Add it as
RENDER_DEPLOY_HOOK_BACKENDin GitHub repository secrets
Note: The free tier spins down after 15 minutes of inactivity and wakes in ~30 seconds. Fine for a portfolio project.
Frontend (Vercel)
- Go to vercel.com → New Project → Import from GitHub
- Set Root Directory to
frontend -
Add environment variable:
Variable Value VITE_API_URLYour Render URL e.g. https://shiftwise-api.onrender.com - Click Deploy
Vercel redeploys automatically on every push to main via its GitHub
integration — no webhook needed.
Update CORS after deploying frontend
Once you have your Vercel URL, update FRONTEND_URL in Render:
FRONTEND_URL=https://shiftwise-app.vercel.app
CI/CD (GitHub Actions)
Workflows
.github/workflows/
├── ci.yml # Type checks + Jest tests on every push and PR
└── deploy.yml # Triggers Render deploy hook on push to main
CI workflow
Runs on every push and pull request — three jobs in order:
- Backend — type check & build —
tscmust pass - Frontend — type check & build —
vite buildmust pass - Backend — Jest tests — all 18 tests must pass (runs after build)
Deploy workflow
Runs on push to main only:
- Calls the Render deploy hook → triggers a backend redeploy
- Vercel handles the frontend automatically
Required GitHub repository secrets
| Secret | Where to get it |
|---|---|
RENDER_DEPLOY_HOOK_BACKEND |
Render → service → Settings → Deploy Hook |
DATABASE_URL |
Neon dashboard → Connection string |
JWT_ACCESS_SECRET |
Generate locally |
JWT_REFRESH_SECRET |
Generate locally |
Viewing CI results
GitHub Actions: repo → Actions tab → click any run
Vercel: vercel.com/dashboard → your project → Deployments
Render: render.com/dashboard → your service → Events