Skip to content

Commit 919fb86

Browse files
authored
Update preview env documentation (#516)
1 parent 37887ab commit 919fb86

1 file changed

Lines changed: 107 additions & 98 deletions

File tree

docs/roo-code-cloud/environments.mdx

Lines changed: 107 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ keywords:
99
- Services
1010
- Postgres
1111
- Redis
12+
- Detached Commands
13+
- Tool Versions
14+
- mise
1215
---
1316

1417
# Preview Environments
@@ -40,14 +43,16 @@ repositories:
4043
- name: Install
4144
run: npm install
4245
- name: Start
43-
run: npm run dev &
46+
run: npm run dev
47+
detached: true
4448

4549
- repository: myorg/backend
4650
commands:
4751
- name: Install
4852
run: npm install
4953
- name: Start
50-
run: npm run dev &
54+
run: npm run dev
55+
detached: true
5156

5257
ports:
5358
- name: WEB
@@ -100,61 +105,31 @@ You can configure up to **4 named ports** per environment.
100105

101106
## Using Environment Variables in Your Code
102107

103-
The injected environment variables let your applications find each other without hardcoded URLs.
104-
105-
### React/Vite Frontend
108+
Use the `ROO_<NAME>_HOST` variables instead of hardcoded URLs so your services can find each other in both preview and local environments:
106109

107110
```typescript
111+
// Backend: configure CORS with the injected frontend URL
112+
app.use(cors({
113+
origin: process.env.ROO_WEB_HOST || 'http://localhost:3000'
114+
}));
115+
116+
// Frontend (Vite): pass the API URL at build time
108117
// vite.config.ts
109118
export default defineConfig({
110119
define: {
111120
'import.meta.env.API_URL': JSON.stringify(process.env.ROO_API_HOST || 'http://localhost:3001')
112121
}
113122
})
114-
115-
// In your React code
116-
const response = await fetch(`${import.meta.env.API_URL}/api/users`);
117-
```
118-
119-
### Next.js Frontend
120-
121-
```typescript
122-
// next.config.js
123-
module.exports = {
124-
env: {
125-
NEXT_PUBLIC_API_URL: process.env.ROO_API_HOST || 'http://localhost:3001'
126-
}
127-
}
128-
129-
// In your code
130-
const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/users`);
131-
```
132-
133-
### Node.js/Express/Hono Backend
134-
135-
```typescript
136-
// Configure CORS to allow requests from the frontend domain
137-
app.use(cors({
138-
origin: process.env.ROO_WEB_HOST || 'http://localhost:3000'
139-
}));
140-
141-
// Or allow multiple frontends
142-
app.use(cors({
143-
origin: [
144-
process.env.ROO_WEB_HOST,
145-
process.env.ROO_ADMIN_HOST
146-
].filter(Boolean)
147-
}));
148123
```
149124

150-
### Inter-Service Communication
125+
For static site frameworks (Vite, Next.js, CRA), the API URL needs to be set at build time via command-level `env`:
151126

152-
If you have multiple backend services:
153-
154-
```typescript
155-
// In your API service, call a worker service
156-
const workerUrl = process.env.ROO_WORKER_HOST || 'http://localhost:3002';
157-
await fetch(`${workerUrl}/jobs`, { method: 'POST', body: jobData });
127+
```yaml
128+
commands:
129+
- name: Build
130+
run: npm run build
131+
env:
132+
VITE_API_URL: ${ROO_API_HOST}
158133
```
159134

160135
## Repositories
@@ -170,7 +145,9 @@ repositories:
170145
- name: Build
171146
run: npm run build
172147
- name: Start dev server
173-
run: npm run dev &
148+
run: npm run dev
149+
detached: true
150+
logfile: /tmp/frontend.log
174151
175152
- repository: myorg/backend
176153
commands:
@@ -179,7 +156,9 @@ repositories:
179156
- name: Run migrations
180157
run: npm run db:migrate
181158
- name: Start server
182-
run: npm run start &
159+
run: npm run start
160+
detached: true
161+
logfile: /tmp/backend.log
183162
```
184163

185164
### Repository Format
@@ -194,19 +173,38 @@ Each repository can have its own commands that run in order. Commands support:
194173
|-------|-------------|---------|
195174
| `name` | Display name for the command | Required |
196175
| `run` | The shell command to execute | Required |
197-
| `working_dir` | Directory to run the command in | Repository root |
176+
| `working_dir` | Relative directory to run the command in | Repository root |
177+
| `cwd` | Absolute path to run the command in | Repository root |
198178
| `env` | Command-specific environment variables | None |
199179
| `timeout` | Maximum seconds to wait | 60 |
200180
| `continue_on_error` | Keep going if command fails | false |
181+
| `detached` | Run in the background (see below) | false |
182+
| `logfile` | File path to write stdout/stderr when `detached` is true | None |
201183

202184
### Background Processes
203185

204-
To start a server that keeps running, end the command with `&`:
186+
To start a long-running process like a dev server, use `detached: true`. This runs the command in the background so subsequent commands can execute immediately:
205187

206188
```yaml
207189
commands:
208-
- name: Start server
209-
run: npm run dev &
190+
- name: Install
191+
run: npm install
192+
- name: Start dev server
193+
run: npm run dev
194+
detached: true
195+
logfile: /tmp/dev-server.log
196+
```
197+
198+
When `detached` is true, the command runs via `nohup` and the worker moves on after confirming the process started. If `logfile` is set, stdout and stderr are written to that path — useful for debugging startup issues.
199+
200+
### Automatic Tool Installation
201+
202+
If a repository contains a `.tool-versions` file (used by [mise](https://mise.jdx.dev/) / asdf), Roo Code Cloud automatically runs `mise install` after cloning. This installs the correct versions of tools like Node.js, Python, Ruby, Go, or any other runtime your project requires — before any of your setup commands execute.
203+
204+
```
205+
# .tool-versions
206+
nodejs 20.11.0
207+
python 3.12.1
210208
```
211209
212210
## Services
@@ -276,7 +274,9 @@ repositories:
276274
env:
277275
VITE_API_URL: ${ROO_API_HOST}
278276
- name: Serve
279-
run: npx serve -s dist -l 3000 &
277+
run: npx serve -s dist -l 3000
278+
detached: true
279+
logfile: /tmp/storefront.log
280280
281281
- repository: acme/api
282282
commands:
@@ -285,7 +285,9 @@ repositories:
285285
- name: Migrate
286286
run: npm run db:push
287287
- name: Start
288-
run: npm run start &
288+
run: npm run start
289+
detached: true
290+
logfile: /tmp/api.log
289291
env:
290292
ALLOWED_ORIGINS: ${ROO_WEB_HOST}
291293
@@ -294,7 +296,9 @@ repositories:
294296
- name: Install
295297
run: npm install
296298
- name: Start
297-
run: npm run start &
299+
run: npm run start
300+
detached: true
301+
logfile: /tmp/worker.log
298302
299303
ports:
300304
- name: WEB
@@ -315,75 +319,80 @@ env:
315319

316320
After the environment starts, you'll get unique URLs for each port. Visit the WEB URL to access your running application.
317321

318-
## Tips
322+
## Common Issues
319323

320-
### 1. Always Use Environment Variables for URLs
324+
### CORS Errors
321325

322-
Don't hardcode URLs between services:
326+
In a preview environment, your frontend and backend run on different domains (e.g., `https://abc123.vercel.run` and `https://def456.vercel.run`). Browsers block cross-origin requests by default, so your backend needs to explicitly allow the frontend's domain.
323327

324-
```typescript
325-
// Bad - breaks in preview environments
326-
const apiUrl = 'http://localhost:3001';
328+
Use the `ROO_WEB_HOST` variable to configure your backend's CORS policy:
327329

328-
// Good - works everywhere
329-
const apiUrl = process.env.ROO_API_HOST || 'http://localhost:3001';
330-
```
331-
332-
### 2. Configure CORS Dynamically
330+
**Express:**
333331

334332
```typescript
335-
// Bad - only works locally
336-
app.use(cors({ origin: 'http://localhost:3000' }));
333+
import cors from 'cors';
337334
338-
// Good - works in preview and locally
339335
app.use(cors({
340336
origin: process.env.ROO_WEB_HOST || 'http://localhost:3000'
341337
}));
342338
```
343339

344-
### 3. Use Build-Time Variables for Static Sites
340+
**Hono:**
345341

346-
For frameworks like Vite, CRA, or Next.js, the API URL often needs to be known at build time:
342+
```typescript
343+
import { cors } from 'hono/cors';
347344
348-
```yaml
349-
commands:
350-
- name: Build
351-
run: npm run build
352-
env:
353-
VITE_API_URL: ${ROO_API_HOST}
345+
app.use(cors({
346+
origin: process.env.ROO_WEB_HOST || 'http://localhost:3000'
347+
}));
354348
```
355349

356-
### 4. Handle Missing Variables Gracefully
357-
358-
In development, you might not have all variables set:
350+
**Fastify:**
359351

360352
```typescript
361-
const apiUrl = process.env.ROO_API_HOST;
362-
if (!apiUrl) {
363-
console.warn('ROO_API_HOST not set, using localhost');
364-
}
353+
app.register(import('@fastify/cors'), {
354+
origin: process.env.ROO_WEB_HOST || 'http://localhost:3000'
355+
});
365356
```
366357

367-
### 5. Use Consistent Naming
368-
369-
Pick a naming convention and stick with it:
358+
Then in your environment config, make sure both ports are defined so the variables get injected:
370359

371360
```yaml
372-
# Good - clear and consistent
373361
ports:
374362
- name: WEB
375363
port: 3000
376364
- name: API
377365
port: 3001
378-
- name: ADMIN
379-
port: 3002
366+
```
380367

381-
# Avoid - inconsistent naming
382-
ports:
383-
- name: frontend
384-
port: 3000
385-
- name: BACKEND_API
386-
port: 3001
387-
- name: Admin_Panel
388-
port: 3002
368+
### Managing Frontend API URLs with `.env` Files
369+
370+
Frontends typically need the API URL at build time. If your project already uses `.env` files (via dotenv, dotenvx, or framework built-ins like Vite's `.env.local`), you can write the injected `ROO_API_HOST` into a `.env` file as a setup command — no code changes needed:
371+
372+
```yaml
373+
repositories:
374+
- repository: myorg/frontend
375+
commands:
376+
- name: Configure API URL
377+
run: echo "VITE_API_URL=${ROO_API_HOST}" >> .env.local
378+
- name: Install
379+
run: npm install
380+
- name: Start
381+
run: npm run dev
382+
detached: true
389383
```
384+
385+
This works with any framework that reads `.env` files:
386+
387+
| Framework | File | Variable prefix |
388+
|-----------|------|-----------------|
389+
| Vite | `.env.local` | `VITE_` |
390+
| Next.js | `.env.local` | `NEXT_PUBLIC_` |
391+
| Create React App | `.env.local` | `REACT_APP_` |
392+
393+
This approach keeps your environment config simple and avoids modifying application code.
394+
395+
## Tips
396+
397+
- **Use `ROO_*_HOST` variables, not hardcoded URLs.** Always fall back to localhost for local dev: `process.env.ROO_API_HOST || 'http://localhost:3001'`.
398+
- **Use consistent uppercase port names.** `WEB`, `API`, `ADMIN` — not `frontend`, `BACKEND_API`, `Admin_Panel`.

0 commit comments

Comments
 (0)