This guide walks you through deploying both the backend and frontend to Render.com's free tier.
- GitHub account with the repository: https://github.com/MichaelJohnsonAgile/matchplay.git
- Render.com account (free - sign up at https://render.com)
- Go to https://dashboard.render.com
- Click "New +" button in the top right
- Select "Web Service"
- Click "Build and deploy from a Git repository"
- Click "Connect account" to connect GitHub (if not already connected)
- Find and select "matchplay" repository
- Click "Connect"
Fill in the following settings:
Basic Settings:
- Name:
matchplay-backend(or any name you prefer) - Region: Choose closest to you (e.g.,
Oregon (US West)) - Branch:
main - Root Directory:
backend - Runtime:
Node
Build & Deploy:
- Build Command:
npm install - Start Command:
npm start
Instance Type:
- Select "Free" (this is important!)
- PORT: Render automatically sets this, no need to add
- Click "Create Web Service" at the bottom
- Wait for deployment (2-3 minutes)
- Once deployed, you'll see a URL like:
https://matchplay-backend.onrender.com
Click on the URL and add /health to test:
https://matchplay-backend.onrender.com/health
You should see:
{"status":"ok","timestamp":"2025-11-24T..."}IMPORTANT: Copy your backend URL - you'll need it for the frontend!
Before deploying the frontend, we need to update it to point to your Render backend.
The frontend needs to know where your backend is hosted. We'll set this up with an environment variable.
- Go back to Render Dashboard
- Click "New +" again
- Select "Static Site"
- Select "matchplay" repository again
- Click "Connect"
Fill in the following settings:
Basic Settings:
- Name:
matchplay(ormatchplay-frontend) - Branch:
main - Root Directory:
frontend
Build Settings:
- Build Command:
npm install && npm run build - Publish Directory:
dist
Click "Advanced" and add environment variable:
- Key:
VITE_API_URL - Value:
https://matchplay-backend.onrender.com(use YOUR backend URL from Part 1)
- Click "Create Static Site"
- Wait for build and deployment (2-4 minutes)
- Once deployed, you'll get a URL like:
https://matchplay.onrender.com
Note: The frontend/public/_redirects file handles SPA routing so page refreshes work correctly.
We need to update the frontend code to use the Render backend URL.
Change this line:
const API_BASE_URL = 'http://localhost:3001/api'To:
const API_BASE_URL = import.meta.env.VITE_API_URL
? `${import.meta.env.VITE_API_URL}/api`
: 'http://localhost:3001/api'This allows the app to:
- Use Render backend URL in production
- Use localhost when developing locally
git add .
git commit -m "feat: add environment variable support for API URL (agent)"
git push origin mainRender will automatically redeploy both services when you push!
Without a database, all data is stored in memory and will be lost when:
- The backend service restarts
- The backend sleeps after 15 minutes of inactivity
- You redeploy the backend
Adding PostgreSQL gives you persistent data storage.
- Go to Render Dashboard
- Click "New +" → "PostgreSQL"
- Configure:
- Name:
matchplay-data - Database:
matchplay - Region: Same as your backend (important!)
- Instance Type: Free
- Name:
- Click "Create Database"
- Wait 1-2 minutes for provisioning
- Once created, scroll down to "Connections" section
- Copy the Internal Database URL (starts with
postgresql://) - It will look like:
postgresql://matchplay_user:xxxxx@dpg-xxxxx-a/matchplay
- Go to your Backend Web Service (matchplay-backend)
- Click "Environment" tab on the left
- Click "Add Environment Variable"
- Add:
- Key:
DATABASE_URL - Value: Paste the Internal Database URL you copied
- Key:
- Click "Save Changes"
- Backend will automatically redeploy
After backend redeploys (watch the logs):
Option A: Via Render Shell (Recommended)
- Go to your backend service
- Click "Shell" tab
- Run:
npm run db:init
- You should see: ✅ Database schema created successfully
Option B: Via Local Connection
cd backend
$env:DATABASE_URL="your-external-database-url-here"
npm run db:init- Check backend logs for:
✅ Database connection established - Test API:
https://matchplay-backend.onrender.com/api/athletes - Should see 12 sample athletes
📚 For detailed database setup, see: backend/DATABASE_SETUP.md
- Open your frontend URL:
https://matchplay.onrender.com - Try creating a game day
- Add some athletes
- Generate matches
- Refresh the page - data should persist!
Backend Sleep Time:
- Free tier backend sleeps after 15 minutes of inactivity
- First request after sleep takes ~30 seconds to wake up
- Subsequent requests are fast
To Keep Backend Awake (Optional): You can use a free service like UptimeRobot to ping your backend every 10 minutes:
- Sign up at https://uptimerobot.com (free)
- Add monitor for
https://matchplay-backend.onrender.com/health - Set interval to 5 minutes
After deployment, save these URLs:
Frontend: https://matchplay.onrender.com
Backend: https://matchplay-backend.onrender.com
Backend Health Check: https://matchplay-backend.onrender.com/health
Database: Accessible via Internal URL (in Render dashboard)
This happens when the static site doesn't redirect all routes to index.html.
Solution: Make sure frontend/public/_redirects file exists with:
/* /index.html 200
After adding this file:
- Commit and push to GitHub
- Render will automatically redeploy
- Page refreshes should now work
- Check the backend URL in Render environment variables
- Verify backend is running: visit
/healthendpoint - Check browser console for CORS errors
See detailed troubleshooting in: RENDER_TROUBLESHOOTING.md
- Check Render logs in the dashboard
- Verify
package.jsonhas correct start script - Make sure
backendfolder has all dependencies - If using database, verify
DATABASE_URLis set correctly
- Verify
DATABASE_URLis the Internal URL (not External) - Check database is active in Render dashboard
- Ensure backend and database are in same region
- Check backend logs for connection errors
- Try running
npm run db:initif tables missing
- Check build logs in Render dashboard
- Verify
package.jsonandpackage-lock.jsonare committed - Make sure root directory is set correctly
Current Setup: $0/month
- Backend: Free tier (sleeps after 15 min)
- Frontend: Free tier (always on)
- Database: Free tier PostgreSQL (persistent storage)
Database Limits (Free Tier):
- 1 GB storage
- 1 GB RAM
- 90 days of automatic backups
- Suitable for small to medium apps
Your app is now set up for continuous deployment!
Every time you push to main branch:
- Render automatically detects the changes
- Rebuilds and redeploys affected services
- Your app updates automatically
- Test the deployed application thoroughly
- Share the URL with your pickleball group
- Consider setting up UptimeRobot to prevent backend sleep
- Monitor database usage in Render dashboard
- Set up custom domains (optional, requires paid tier)
- Database Setup Details: backend/DATABASE_SETUP.md
- Database Module README: backend/database/README.md
- Backend README: backend/README.md
- Frontend README: frontend/README.md
Need help? Check Render logs in the dashboard or ask for assistance!