Replit Production Checklist
Overview
Complete checklist for deploying Replit apps to production using Autoscale or Reserved VM deployments. Covers configuration, secrets, health checks, custom domains, rollback procedures, and monitoring.
Prerequisites
- Replit Core, Pro, or Teams plan (deployment access)
- App tested and working in Workspace
- PostgreSQL database provisioned (if needed)
- Custom domain (optional) with DNS access
Production Deployment Checklist
Phase 1: Configuration
- [ ]
.replitdeployment section configured:
[deployment]
run = ["sh", "-c", "npm start"]
build = ["sh", "-c", "npm ci --production && npm run build"]
deploymentTarget = "autoscale" # or "cloudrun" for Reserved VM
- [ ]
replit.nixincludes only required system packages (trim dev-only deps) - [ ]
NODE_ENVset to"production"in.replitenv section - [ ] Port reads from
process.env.PORT
Phase 2: Secrets
- [ ] All secrets configured in Replit Secrets tab
- [ ] Secrets sync enabled (Workspace <-> Deployment)
- [ ] No hardcoded credentials in source code
- [ ] Startup validates all required secrets:
const REQUIRED = ['DATABASE_URL', 'JWT_SECRET'];
const missing = REQUIRED.filter(k => !process.env[k]);
if (missing.length) {
console.error(`FATAL: Missing secrets: ${missing.join(', ')}`);
process.exit(1);
}
Phase 3: Health Check
- [ ]
/healthendpoint exists and checks dependencies:
app.get('/health', async (req, res) => {
const checks = {
db: false,
uptime: process.uptime(),
memory: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
};
try {
await pool.query('SELECT 1');
checks.db = true;
} catch {}
const status = checks.db ? 200 : 503;
res.status(status).json({ status: status === 200 ? 'healthy' : 'degraded', ...checks });
});
- [ ] Health endpoint does NOT expose secrets or internal paths
- [ ] Health endpoint responds within 5 seconds
Phase 4: Error Handling
- [ ] Global error handler catches uncaught exceptions:
// Never expose stack traces in production
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
console.error('Unhandled error:', err.message);
res.status(500).json({
error: process.env.NODE_ENV === 'production'
? 'Internal server error'
: err.message,
});
});
process.on('uncaughtException', (err) => {
console.error('Uncaught exception:', err.message);
process.exit(1);
});
process.on('unhandledRejection', (reason) => {
console.error('Unhandled rejection:', reason);
});
- [ ] Rate limiting on public endpoints
- [ ] Input validation on all user data (Zod, Joi, or manual)
Phase 5: Deploy
Via Replit UI:
- Click "Deploy" button in top bar
- Choose type:
- Static: Frontend-only (HTML/CSS/JS), free
- Autoscale: Scales to zero, pay per request (best for variable traffic)
- Reserved VM: Always-on, fixed cost (best for consistent traffic)
- Select machine size (0.25-8 vCPU)
- Click "Deploy"
Via .replit config (automatic on push):
[deployment]
run = ["sh", "-c", "node dist/index.js"]
build = ["sh", "-c", "npm ci --production && npm run build"]
deploymentTarget = "autoscale"
Phase 6: Custom Domain
1. Deployment Settings > Custom Domain
2. Enter domain: app.example.com
3. Add DNS record at your registrar:
CNAME: app -> your-repl-slug.replit.app
4. Wait 1-5 minutes for SSL auto-provisioning
5. Verify: curl -I https://app.example.com
For Replit-purchased domains: manage DNS directly in Replit dashboard.
Phase 7: Post-Deploy Verification
set -euo pipefail
DEPLOY_URL="https://your-app.replit.app"
# Health check
curl -sf "$DEPLOY_URL/health" | jq .
# Response time
curl -s -o /dev/null -w "HTTP %{http_code}, %{time_total}s\n" "$DEPLOY_URL/"
# Headers check
curl -sI "$DEPLOY_URL" | grep -iE "(server|content-type|x-)"
Phase 8: Rollback Plan
Replit Deployments support one-click rollback to any previous successful deployment:
- Go to Deployment Settings > History
- Find the last known-good deployment
- Click "Rollback to this version"
- Verify health endpoint after rollback
Monitoring Recommendations
| Signal | Warning | Critical | |--------|---------|----------| | Health check | 1 failure | 3 consecutive failures | | Response time (p95) | > 2s | > 5s | | Error rate | > 1% | > 5% | | Memory usage | > 75% of limit | > 90% | | Cold start (Autoscale) | > 5s | > 15s |
Error Handling
| Issue | Cause | Solution |
|-------|-------|----------|
| Deploy fails at build | Missing dependency | Check build logs, ensure npm ci works |
| 503 after deploy | App crashing on start | Check deployment logs, verify secrets |
| Cold start too slow | Heavy imports | Lazy-load non-critical modules |
| Custom domain not working | DNS not propagated | Wait or verify CNAME record |
Resources
Next Steps
For version upgrades, see replit-upgrade-migration.