|
| 1 | +# 🚀 Deployment Guide — Render (Backend) + Vercel (Frontend) |
| 2 | + |
| 3 | +This guide walks you through deploying a self-hosted instance of **urBackend** from scratch using **free-tier** cloud services — no Docker required. |
| 4 | + |
| 5 | +| Layer | Platform | Cost | |
| 6 | +| :--- | :--- | :--- | |
| 7 | +| Node.js API | [Render](https://render.com) | Free tier | |
| 8 | +| MongoDB | [MongoDB Atlas](https://www.mongodb.com/atlas) | Free (M0 cluster) | |
| 9 | +| Redis | [Redis Cloud (redis.io)](https://redis.io/try-free/) | Free tier | |
| 10 | +| React/Vite dashboard | [Vercel](https://vercel.com) | Free tier | |
| 11 | + |
| 12 | +--- |
| 13 | + |
| 14 | +## 📋 Table of Contents |
| 15 | + |
| 16 | +1. [Prerequisites](#1-prerequisites) |
| 17 | +2. [Set up MongoDB Atlas](#2-set-up-mongodb-atlas) |
| 18 | +3. [Set up Redis Cloud](#3-set-up-redis-cloud) |
| 19 | +4. [Deploy the Backend to Render](#4-deploy-the-backend-to-render) |
| 20 | +5. [Deploy the Frontend to Vercel](#5-deploy-the-frontend-to-vercel) |
| 21 | +6. [Link the Frontend to the Backend](#6-link-the-frontend-to-the-backend) |
| 22 | +7. [Verify your deployment](#7-verify-your-deployment) |
| 23 | + |
| 24 | +--- |
| 25 | + |
| 26 | +## 1. Prerequisites |
| 27 | + |
| 28 | +Before you start, make sure you have: |
| 29 | + |
| 30 | +- A [GitHub](https://github.com) account with a fork of this repository. |
| 31 | +- A [MongoDB Atlas](https://www.mongodb.com/atlas) account (free). |
| 32 | +- A [Redis Cloud](https://redis.io/try-free/) account (free). |
| 33 | +- A [Render](https://render.com) account (free). |
| 34 | +- A [Vercel](https://vercel.com) account (free). |
| 35 | + |
| 36 | +> **Tip:** You only need to complete steps 2 and 3 once — the same Atlas cluster and Redis Cloud database can be reused across multiple deployments. |
| 37 | +
|
| 38 | +--- |
| 39 | + |
| 40 | +## 2. Set up MongoDB Atlas |
| 41 | + |
| 42 | +1. Go to [cloud.mongodb.com](https://cloud.mongodb.com) and sign in. |
| 43 | +2. Click **"Build a Database"** → choose the **Free (M0)** shared tier. |
| 44 | +3. Select a cloud provider and region closest to your Render deployment region. |
| 45 | +4. Enter a cluster name (e.g. `urbackend`) and click **"Create"**. |
| 46 | +5. Under **Security → Database Access**, create a database user: |
| 47 | + - Username: `urbackend-user` |
| 48 | + - Password: generate a strong password and **copy it**. |
| 49 | + - Role: **"Read and write to any database"**. |
| 50 | +6. Under **Security → Network Access**, click **"Add IP Address"** and add the outbound IP addresses of your Render service. |
| 51 | + |
| 52 | + > To find these IPs: open your Render service → **Info** tab → **Outbound IPs**. Render exposes a set of static outbound IPs per service; add each one individually in Atlas. |
| 53 | +
|
| 54 | +7. Go to **Database → Connect** → **"Drivers"** and copy the **connection string**. It looks like: |
| 55 | + |
| 56 | + ``` |
| 57 | + mongodb+srv://urbackend-user:<password>@urbackend.xxxxx.mongodb.net/?retryWrites=true&w=majority |
| 58 | + ``` |
| 59 | + |
| 60 | + Replace `<password>` with the password you copied in step 5, and append the database name before the query string: |
| 61 | + |
| 62 | + ``` |
| 63 | + mongodb+srv://urbackend-user:<password>@urbackend.xxxxx.mongodb.net/urbackend?retryWrites=true&w=majority |
| 64 | + ``` |
| 65 | + |
| 66 | + **Save this URL** — you will need it in step 4. |
| 67 | + |
| 68 | +--- |
| 69 | + |
| 70 | +## 3. Set up Redis Cloud |
| 71 | + |
| 72 | +1. Go to [redis.io/try-free](https://redis.io/try-free/) and sign up for a free account. |
| 73 | +2. After logging in, click **"New database"**. |
| 74 | +3. Choose the **Free** plan, then enter a database name (e.g. `urbackend-redis`) and select the cloud provider and region closest to your Render deployment. |
| 75 | +4. Click **"Create database"**. |
| 76 | +5. Once the database is created, open it and scroll to the **"Security"** section to note the **host**, **port**, **username** (`default`), and **password**. |
| 77 | +6. Construct the Redis URL in this format: |
| 78 | + |
| 79 | + ``` |
| 80 | + rediss://default:<password>@<host>:<port> |
| 81 | + ``` |
| 82 | + |
| 83 | + **Save this URL** — you will need it in step 4. |
| 84 | + |
| 85 | +--- |
| 86 | + |
| 87 | +## 4. Deploy the Backend to Render |
| 88 | + |
| 89 | +### 4.1 Create a new Web Service |
| 90 | + |
| 91 | +1. Go to [dashboard.render.com](https://dashboard.render.com) and click **"New +"** → **"Web Service"**. |
| 92 | +2. Connect your GitHub account and select your fork of `urBackend`. |
| 93 | +3. Fill in the service settings: |
| 94 | + |
| 95 | + | Setting | Value | |
| 96 | + | :--- | :--- | |
| 97 | + | **Name** | `urbackend-api` (or any name you prefer) | |
| 98 | + | **Region** | Choose the region closest to your Atlas & Redis Cloud region | |
| 99 | + | **Branch** | `main` | |
| 100 | + | **Root Directory** | `backend` | |
| 101 | + | **Runtime** | `Node` | |
| 102 | + | **Build Command** | `npm install` | |
| 103 | + | **Start Command** | `npm start` | |
| 104 | + | **Instance Type** | Free | |
| 105 | + |
| 106 | +4. Click **"Advanced"** to expand the environment variable section. |
| 107 | + |
| 108 | +### 4.2 Configure environment variables |
| 109 | + |
| 110 | +Add **each** of the following environment variables one by one using the **"Add Environment Variable"** button: |
| 111 | + |
| 112 | +```env |
| 113 | +# Server |
| 114 | +PORT=1234 |
| 115 | +NODE_ENV=production |
| 116 | +
|
| 117 | +# Database & Cache |
| 118 | +MONGO_URL=<your MongoDB Atlas connection string from step 2> |
| 119 | +REDIS_URL=<your Redis Cloud URL from step 3> |
| 120 | +
|
| 121 | +# Authentication — generate strong random strings (min 32 chars) |
| 122 | +JWT_SECRET=<at_least_32_random_characters> |
| 123 | +ENCRYPTION_KEY=<exactly_32_character_string> |
| 124 | +API_KEY_SALT=<random_string_for_api_key_hashing> |
| 125 | +
|
| 126 | +# External Storage (Supabase) — required for file uploads |
| 127 | +SUPABASE_URL=https://your-project.supabase.co |
| 128 | +SUPABASE_KEY=your-supabase-anon-key |
| 129 | +
|
| 130 | +# Email (Resend) — required for OTP / email verification |
| 131 | +RESEND_API_KEY=re_your_resend_api_key |
| 132 | +EMAIL_FROM=onboarding@resend.dev |
| 133 | +
|
| 134 | +# Frontend URL — update after deploying the frontend (step 5) |
| 135 | +FRONTEND_URL=https://your-frontend.vercel.app |
| 136 | +``` |
| 137 | + |
| 138 | +> **Security note:** Never commit real secrets to your repository. Always use the Render environment variable panel or a secrets manager. |
| 139 | +
|
| 140 | +> **Generating secrets:** You can run `node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"` locally to generate a strong random string for `JWT_SECRET`, `ENCRYPTION_KEY`, and `API_KEY_SALT`. |
| 141 | +
|
| 142 | +### 4.3 Deploy |
| 143 | + |
| 144 | +1. Click **"Create Web Service"**. |
| 145 | +2. Render will pull your code, run `npm install`, and start the server. The first deploy usually takes 2–3 minutes. |
| 146 | +3. Once the status shows **"Live"**, copy the service URL — it looks like: |
| 147 | + |
| 148 | + ``` |
| 149 | + https://urbackend-api.onrender.com |
| 150 | + ``` |
| 151 | + |
| 152 | + **Save this URL** — you will need it when deploying the frontend. |
| 153 | + |
| 154 | +### 4.4 Verify the backend |
| 155 | + |
| 156 | +Open your browser (or use `curl`) and visit: |
| 157 | + |
| 158 | +``` |
| 159 | +https://urbackend-api.onrender.com/health |
| 160 | +``` |
| 161 | + |
| 162 | +You should see a `200 OK` response confirming the API is running. |
| 163 | + |
| 164 | +> **Free tier cold starts:** Render's free tier spins down services after 15 minutes of inactivity. The first request after a cold start may take 30–60 seconds. |
| 165 | +
|
| 166 | +--- |
| 167 | + |
| 168 | +## 5. Deploy the Frontend to Vercel |
| 169 | + |
| 170 | +### 5.1 Import the project |
| 171 | + |
| 172 | +1. Go to [vercel.com/new](https://vercel.com/new) and sign in with GitHub. |
| 173 | +2. Click **"Add New… → Project"** and import your fork of `urBackend`. |
| 174 | +3. In the project configuration screen: |
| 175 | + |
| 176 | + | Setting | Value | |
| 177 | + | :--- | :--- | |
| 178 | + | **Root Directory** | `frontend` | |
| 179 | + | **Framework Preset** | Vite (auto-detected) | |
| 180 | + | **Build Command** | `npm run build` (default) | |
| 181 | + | **Output Directory** | `dist` (default) | |
| 182 | + |
| 183 | +### 5.2 Configure the environment variable |
| 184 | + |
| 185 | +Under **"Environment Variables"**, add: |
| 186 | + |
| 187 | +```env |
| 188 | +VITE_API_URL=https://urbackend-api.onrender.com |
| 189 | +``` |
| 190 | + |
| 191 | +Replace the value with the actual Render service URL you copied in step 4.3. |
| 192 | + |
| 193 | +> This variable tells the React app where your backend API lives. Without it, the frontend will default to `http://localhost:1234` and will not work in production. |
| 194 | +
|
| 195 | +### 5.3 Deploy |
| 196 | + |
| 197 | +1. Click **"Deploy"**. |
| 198 | +2. Vercel will install dependencies and build the Vite project. This usually takes under a minute. |
| 199 | +3. Once the deployment is complete, Vercel will give you a URL like: |
| 200 | + |
| 201 | + ``` |
| 202 | + https://ur-backend.vercel.app |
| 203 | + ``` |
| 204 | + |
| 205 | +--- |
| 206 | + |
| 207 | +## 6. Link the Frontend to the Backend |
| 208 | + |
| 209 | +After the frontend is deployed, you must go back to Render and update the `FRONTEND_URL` environment variable: |
| 210 | + |
| 211 | +1. In the [Render dashboard](https://dashboard.render.com), open your `urbackend-api` service. |
| 212 | +2. Go to **"Environment"** and update: |
| 213 | + |
| 214 | + ```env |
| 215 | + FRONTEND_URL=https://ur-backend.vercel.app |
| 216 | + ``` |
| 217 | + |
| 218 | +3. Click **"Save Changes"**. Render will automatically redeploy the backend with the updated CORS origin. |
| 219 | + |
| 220 | +--- |
| 221 | + |
| 222 | +## 7. Verify your deployment |
| 223 | + |
| 224 | +1. Open your Vercel frontend URL in the browser. |
| 225 | +2. Create a new account and log in — this exercises the Auth API against your live backend. |
| 226 | +3. Create a project and insert a document — this confirms the MongoDB Atlas connection is working. |
| 227 | +4. Check the Render logs (**Logs** tab on the service page) if anything is not working. |
| 228 | + |
| 229 | +### Common issues |
| 230 | + |
| 231 | +| Symptom | Likely cause | Fix | |
| 232 | +| :--- | :--- | :--- | |
| 233 | +| Frontend shows network error | `VITE_API_URL` is wrong or missing | Re-deploy frontend with correct env var | |
| 234 | +| Backend returns 500 on any request | `MONGO_URL` is wrong | Check Atlas connection string & network access rules | |
| 235 | +| Login emails not arriving | `RESEND_API_KEY` is missing/invalid | Add a valid key from [resend.com](https://resend.com) | |
| 236 | +| File uploads fail | `SUPABASE_URL` / `SUPABASE_KEY` missing | Add valid Supabase credentials | |
| 237 | +| Frontend CORS errors | `FRONTEND_URL` not updated on backend | Update and redeploy the Render service | |
| 238 | + |
| 239 | +--- |
| 240 | + |
| 241 | +## 🔁 Re-deploying after code changes |
| 242 | + |
| 243 | +- **Render** automatically redeploys when you push to the `main` branch of your GitHub fork (if auto-deploy is enabled in the Render dashboard). |
| 244 | +- **Vercel** automatically redeploys on every push and even creates preview deployments for pull requests. |
| 245 | + |
| 246 | +--- |
| 247 | + |
| 248 | +## 📚 Further reading |
| 249 | + |
| 250 | +- [MongoDB Atlas documentation](https://www.mongodb.com/docs/atlas/) |
| 251 | +- [Redis Cloud documentation](https://redis.io/docs/latest/operate/rc/) |
| 252 | +- [Render Web Services documentation](https://docs.render.com/web-services) |
| 253 | +- [Vercel deployment documentation](https://vercel.com/docs/deployments/overview) |
| 254 | +- [urBackend Contributing Guide](CONTRIBUTING.md) |
0 commit comments