Vercel + Railway is the recommended cloud-hosted deployment pattern for Timeful. The Vue 2 SPA is served from Vercel’s global CDN, the Go API runs as a Docker container on Railway, and all data lives in a free MongoDB Atlas M0 cluster. Vercel automatically proxiesDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ptshen/timeful-plus/llms.txt
Use this file to discover all available pages before exploring further.
/api/* requests to Railway so the browser only ever talks to a single origin, which keeps cookies working reliably.
Architecture
| Layer | Service | Notes |
|---|---|---|
| Frontend (Vue 2 SPA) | Vercel | Static build, /api rewrites to Railway |
| Backend (Go + Gin) | Railway | Built from Dockerfile.backend |
| Database (MongoDB) | MongoDB Atlas | Free M0 tier, hosted |
Prerequisites
Before you start, make sure you have accounts on:GitHub
Vercel
Railway
MongoDB Atlas
Deployment Steps
Set Up MongoDB Atlas
- Go to cloud.mongodb.com and create a free account.
- Click Build a Database → select the M0 FREE tier.
- Choose a cloud provider and region closest to your users, then click Create Deployment.
- Create a database user:
- Username:
timeful-admin(or your choice) - Password: click Autogenerate Secure Password and save it
- Click Create Database User
- Username:
- Configure network access:
- For testing: click Add My Current IP Address
- For production: click Add IP Address → enter
0.0.0.0/0→ Allow Access from Anywhere
- Click Finish and Close.
- Get your connection string:
- Database in the sidebar → Connect on your cluster → Drivers
- Copy the string and replace
<password>with your database user’s password
MONGO_URI in Step 3.Create Google OAuth Credentials
- Go to console.cloud.google.com.
- Create a new project (or select an existing one).
- Navigate to APIs & Services → Credentials.
- If prompted, configure the OAuth consent screen:
- User Type: External
- App name:
Timeful - Fill in your support email and developer contact, then click Save and Continue through the remaining screens.
- Click + CREATE CREDENTIALS → OAuth client ID:
- Application type: Web application
- Name:
Timeful Production
- Add placeholder Authorized JavaScript origins (you will update these in Step 7):
- Add placeholder Authorized redirect URIs:
- Click Create and save both the Client ID and Client Secret.
Deploy the Backend to Railway
- Go to railway.app and sign up with GitHub.
- Click New Project → Deploy from GitHub repo and select your Timeful repository.
- Railway detects the
railway.jsonand usesDockerfile.backendautomatically. If it does not, go to Settings → Build and set the Dockerfile path toDockerfile.backend. - Open Settings → Variables and add the following environment variables:
| Variable | Value |
|---|---|
MONGO_URI | Your Atlas connection string from Step 1 |
MONGO_DB_NAME | schej-it |
ENCRYPTION_KEY | Output of openssl rand -base64 32 |
CLIENT_ID | Google OAuth Client ID from Step 2 |
CLIENT_SECRET | Google OAuth Client Secret from Step 2 |
BASE_URL | https://your-vercel-domain.vercel.app (placeholder) |
CORS_ALLOWED_ORIGINS | https://your-vercel-domain.vercel.app (placeholder) |
SELF_HOSTED_PREMIUM | true |
- Click Deploy and wait for the build to finish.
- Go to Settings → Networking → Generate Domain.
- Copy your Railway URL (e.g.,
timeful-backend-production.up.railway.app). - Verify the backend is healthy:
Update vercel.json with Your Railway Domain
vercel.json at the root of the repository and replace the destination URL with your Railway domain:Update the Frontend Config
frontend/public/config.js (copy from config.example.js if it does not exist yet) and set your Google Client ID:googleClientId must match the CLIENT_ID you set in Railway. microsoftClientId is only needed for Outlook calendar integration.Deploy the Frontend to Vercel
- Go to vercel.com and sign in with GitHub.
- Click Add New… → Project and import your Timeful repository.
- Configure build settings:
- Framework Preset:
Other - Root Directory:
/(leave default) - Build Command:
cd frontend && npm run build - Output Directory:
frontend/dist - Install Command:
cd frontend && npm ci
- Framework Preset:
- Click Deploy.
- Once the build completes, copy your Vercel URL (e.g.,
timeful-xxxx.vercel.app).
Update Google OAuth Redirect URIs
- APIs & Services → Credentials → click your OAuth 2.0 Client ID.
- Replace the placeholder in Authorized JavaScript origins:
- Replace the placeholder in Authorized redirect URIs:
- Click Save.
Update Railway Environment Variables
BASE_URL and CORS_ALLOWED_ORIGINS values with your real Vercel URL:- Railway → your project → Variables.
- Update both variables:
Verify the Deployment
- Frontend loads — visit
https://your-vercel-url.vercel.app. - API responds — visit
https://your-vercel-url.vercel.app/api/auth/status(should return JSON). - Create an event — test the full scheduling flow without logging in.
- Google login — click Sign in with Google and complete the OAuth flow.
- Calendar integration — connect Google Calendar and verify events appear in the availability view.
Custom Domain (Optional)
- Vercel Dashboard → your project → Settings → Domains.
- Add your domain (e.g.,
timeful.app). - At your DNS registrar, add:
- Railway → Settings → Networking → Custom Domain.
- Add
api.timeful.app(or your subdomain). - At your DNS registrar, add:
vercel.jsonrewrites destination →https://api.timeful.app/api/:path*- Railway env vars:
BASE_URLandCORS_ALLOWED_ORIGINS→https://timeful.app - Google OAuth: update authorized origins and redirect URIs to use your custom domain
Environment Variables Reference
The following variables are set in Railway under Settings → Variables:| Variable | Required | Description |
|---|---|---|
MONGO_URI | Yes | MongoDB Atlas connection string |
MONGO_DB_NAME | Yes | schej-it |
ENCRYPTION_KEY | Yes | Generate with openssl rand -base64 32 |
CLIENT_ID | Yes* | Google OAuth Client ID |
CLIENT_SECRET | Yes* | Google OAuth Client Secret |
BASE_URL | Yes | Frontend URL, e.g. https://timeful.app |
CORS_ALLOWED_ORIGINS | Yes | Frontend URL — same value as BASE_URL |
MICROSOFT_CLIENT_ID | No | Azure OAuth Client ID (Outlook calendar) |
MICROSOFT_CLIENT_SECRET | No | Azure OAuth Client Secret (Outlook calendar) |
SELF_HOSTED_PREMIUM | No | true to unlock all premium features |
Troubleshooting
CORS error in the browser console
CORS error in the browser console
CORS_ALLOWED_ORIGINS in Railway matches your Vercel URL exactly — same protocol, same domain, no trailing slash.OAuth redirect mismatch error
OAuth redirect mismatch error
https://your-domain/auth. Common mismatches:- Using
http://instead ofhttps:// - A stale placeholder URL still in the Console
- A custom domain configured in Vercel but not yet added to the OAuth credentials
API calls return 502 or 504 from Railway
API calls return 502 or 504 from Railway
- Open Railway → your project → Deployments and click the latest deploy to read the build and runtime logs.
- Confirm
MONGO_URIis correct and that your Atlas cluster’s IP access list includes0.0.0.0/0. - Visit
https://YOUR_RAILWAY_URL/api/healthdirectly to check if the backend itself is up. - If the health check passes but Vercel is returning 502, confirm the
vercel.jsonrewrite destination matches your Railway domain.
Login session does not persist after OAuth
Login session does not persist after OAuth
SameSite=None; Secure. This is handled automatically when both BASE_URL and CORS_ALLOWED_ORIGINS are set to the correct https:// URLs. If login seems to succeed but the app immediately shows you as logged out, double-check that both Railway variables are set and that the backend is being accessed over HTTPS.