Web Deployment¶
The Owlette dashboard is a Next.js application. This guide covers deploying to Railway (recommended) and general Node.js hosting.
Railway Deployment (Recommended)¶
Step 1: Create Railway Project¶
- Go to railway.app and sign up with GitHub
- Click "New Project" → "Deploy from GitHub repo"
- Select the Owlette repository
Step 2: Configure Service¶
- Click on your service → Settings
- Set Root Directory:
web - Set Branch:
main(production) ordev(development) - Enable "Auto-deploy on push"
The repository includes web/railway.toml with build configuration:
[build]
builder = "NIXPACKS"
buildCommand = "npm install && npm run build"
[deploy]
startCommand = "npm start"
restartPolicyType = "ON_FAILURE"
restartPolicyMaxRetries = 10
Step 3: Add Environment Variables¶
In Railway → your service → Variables tab, add all variables listed in Environment Variables.
Step 4: Deploy¶
Railway deploys automatically after variables are configured. Monitor the build in the Deployments tab.
Expected build time: 2-5 minutes.
Step 5: Configure Firebase Auth Domain¶
- Copy your Railway deployment URL
- Go to Firebase Console → Authentication → Settings → Authorized Domains
- Add your Railway URL (e.g.,
owlette-web.up.railway.app)
Required
Without this step, users cannot log in — Firebase rejects auth requests from unauthorized domains.
Step 6: Custom Domain (Optional)¶
- Railway → Settings → Networking → "Add Custom Domain"
- Add CNAME or A record as instructed
- Railway auto-provisions SSL via Let's Encrypt
- Add the custom domain to Firebase Authorized Domains too
Cron Health Checks¶
Set up the machine offline detection cron:
Step 1: Add CRON_SECRET¶
Add as CRON_SECRET in Railway Variables.
Step 2: Configure Cron Schedule¶
- Railway → your service → Settings → "Cron Schedule"
- Enter:
*/5 * * * *(every 5 minutes)
Format
Use spaces between fields: */5 * * * *. No spaces (*/5****) will fail.
Two-Branch Deployment¶
Owlette uses two branches with separate Railway deployments:
| Branch | Deployment | URL |
|---|---|---|
dev |
Development | dev.owlette.app |
main |
Production | owlette.app |
Each has its own Railway service, environment variables, and (optionally) Firebase project.
General Node.js Hosting¶
For non-Railway deployments:
Requirements:
- Node.js 18+
- All environment variables set
- Port 3000 available (or set
PORTenv var) - HTTPS for Firebase Auth (required)
Deployment Checklist¶
Pre-Deployment¶
- [ ]
npm run buildsucceeds locally - [ ]
npm testpasses - [ ]
npx tsc --noEmithas no errors - [ ] All environment variables documented
Railway Setup¶
- [ ] Repository linked
- [ ] Root directory set to
web - [ ] Branch configured
- [ ] All environment variables added
- [ ]
CRON_SECRETconfigured - [ ] Cron schedule set (
*/5 * * * *)
Post-Deployment¶
- [ ] Railway domain added to Firebase Authorized Domains
- [ ] Registration works
- [ ] Login works
- [ ] Dashboard loads and shows data
- [ ] Real-time updates working
- [ ] Custom domain configured (if applicable)
Troubleshooting¶
Build Fails¶
- Missing env var: Verify all
NEXT_PUBLIC_*variables are set - TypeScript errors: Run
npm run buildlocally first - Dependency issues: Ensure
package-lock.jsonis committed
App Crashes After Deploy¶
- Check runtime logs in Railway Deployments tab
- Look for env var validation errors (
ERROR: Missing required environment variables) - Verify Firebase config values are correct (no quotes around values)
Auth Not Working¶
- Add Railway domain to Firebase Authorized Domains
- Clear browser cache and cookies
- Check browser console for Firebase error details
Slow Performance¶
- Cold starts: Upgrade to Railway Pro (no cold starts)
- Bundle size: Run
npm run buildand check.next/staticoutput - Firestore queries: Add indexes for frequently queried fields
Cost¶
Railway Pricing¶
| Plan | Cost | Key Features |
|---|---|---|
| Hobby | $5/month | 500 hours, cold starts |
| Pro | $20/month | Unlimited, no cold starts, priority support |
Optimization¶
- Use Hobby for development, Pro for production
- Optimize bundle size for faster cold starts
- Add CDN (Cloudflare) for static assets