docs: Add setup guide for preview deployments
Add a clear "Setting Up Preview Deployments" section with prerequisites, quick start, multi-service example, config reference table, dev mode instructions, healthcheck docs, and auto-start explanation. Remove duplicate config example from the old Configuration section.
This commit is contained in:
208
docs/preview.md
208
docs/preview.md
@@ -14,6 +14,152 @@ Two modes:
|
||||
|
||||
**Key design decision: No database table.** Docker IS the source of truth. Instead of persisting rows, we query Docker directly via compose project names, container labels, and `docker compose` CLI commands.
|
||||
|
||||
## Setting Up Preview Deployments for a Project
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Docker** installed and running (`docker --version` / `docker compose version`)
|
||||
- **Project registered** in Codewalkers (`cw project add` or via the UI)
|
||||
- **Browser**: Chrome or Firefox recommended. Safari requires manual `/etc/hosts` entries for `*.localhost` subdomains.
|
||||
|
||||
### Quick Start
|
||||
|
||||
1. **Add a `.cw-preview.yml`** to your project root. This tells Codewalkers how to build and run your app:
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
port: 3000
|
||||
```
|
||||
|
||||
That's it for a single-service app with a Dockerfile. Run:
|
||||
|
||||
```sh
|
||||
cw preview start --initiative <id> --project <id> --branch <branch>
|
||||
```
|
||||
|
||||
Open the URL printed in the output (e.g. `http://abc123.localhost:9100`).
|
||||
|
||||
### Don't Have a `.cw-preview.yml`?
|
||||
|
||||
The config reader auto-discovers in this order:
|
||||
|
||||
1. **`.cw-preview.yml`** — full control (recommended)
|
||||
2. **`docker-compose.yml` / `compose.yml`** — uses your existing compose file
|
||||
3. **`Dockerfile`** — builds a single `app` service on port 3000
|
||||
|
||||
If your project already has a Dockerfile or compose file, previews work out of the box with zero config.
|
||||
|
||||
### Multi-Service Example
|
||||
|
||||
A typical full-stack app with frontend, backend, and database:
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
services:
|
||||
frontend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: apps/web/Dockerfile
|
||||
port: 3000
|
||||
route: / # serves the root path
|
||||
healthcheck:
|
||||
path: /
|
||||
interval: 5s
|
||||
retries: 10
|
||||
env:
|
||||
VITE_API_URL: /api
|
||||
dev: # optional: used in dev mode
|
||||
image: node:20-alpine
|
||||
command: npm run dev -- --host 0.0.0.0
|
||||
workdir: /app
|
||||
|
||||
backend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: packages/api/Dockerfile
|
||||
port: 8080
|
||||
route: /api # proxied under /api/*
|
||||
healthcheck:
|
||||
path: /health
|
||||
env:
|
||||
DATABASE_URL: postgres://db:5432/app
|
||||
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
port: 5432
|
||||
internal: true # not exposed through the proxy
|
||||
env:
|
||||
POSTGRES_PASSWORD: preview
|
||||
```
|
||||
|
||||
Requests to `http://<id>.localhost:9100/` hit `frontend:3000`, requests to `/api/*` hit `backend:8080`, and `db` is only reachable by other services.
|
||||
|
||||
### Config Reference
|
||||
|
||||
Each service in `.cw-preview.yml` supports:
|
||||
|
||||
| Field | Required | Description |
|
||||
|-------|----------|-------------|
|
||||
| `build` | yes* | Build context — string (`"."`) or object (`{context, dockerfile}`) |
|
||||
| `image` | yes* | Docker image to pull (e.g. `postgres:16-alpine`) |
|
||||
| `port` | yes** | Container port the service listens on |
|
||||
| `route` | no | URL path prefix for gateway routing (default: `/`) |
|
||||
| `internal` | no | If `true`, not exposed through the proxy (e.g. databases) |
|
||||
| `healthcheck` | no | `{path, interval?, retries?}` — polled before marking ready |
|
||||
| `env` | no | Environment variables passed to the container |
|
||||
| `volumes` | no | Additional volume mounts |
|
||||
| `dev` | no | Dev mode overrides: `{image, command?, workdir?}` |
|
||||
|
||||
\* Provide either `build` or `image`, not both.
|
||||
\** Required unless `internal: true`.
|
||||
|
||||
### Dev Mode
|
||||
|
||||
Dev mode skips the Docker build and instead mounts your source code into a container running a dev server. Useful for hot reload during active development.
|
||||
|
||||
To use dev mode, add a `dev` section to the service:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
port: 3000
|
||||
dev:
|
||||
image: node:20-alpine # base image with your runtime
|
||||
command: npm run dev -- --host 0.0.0.0 # dev server command
|
||||
workdir: /app # where source is mounted
|
||||
```
|
||||
|
||||
Start with:
|
||||
|
||||
```sh
|
||||
cw preview start --initiative <id> --project <id> --branch <branch> --mode dev
|
||||
```
|
||||
|
||||
The project directory is mounted at `workdir` (default `/app`). An anonymous volume is created for `node_modules` to prevent host/container conflicts.
|
||||
|
||||
### Healthchecks
|
||||
|
||||
If a service has a `healthcheck`, the preview waits for it to respond with HTTP 200 before reporting ready. Without a healthcheck, the service is considered ready as soon as the container starts.
|
||||
|
||||
```yaml
|
||||
healthcheck:
|
||||
path: /health # required: endpoint to poll
|
||||
interval: 5s # optional: time between checks (default: 5s)
|
||||
retries: 10 # optional: max attempts before failing (default: 10)
|
||||
```
|
||||
|
||||
### Auto-Start on Review
|
||||
|
||||
When a phase transitions to `pending_review`, a preview is automatically started if:
|
||||
- The initiative has exactly one registered project
|
||||
- The project has a discoverable config (`.cw-preview.yml`, compose file, or Dockerfile)
|
||||
|
||||
No manual `cw preview start` needed — just push your branch and move the phase to review.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
@@ -118,65 +264,13 @@ All preview containers get `cw.*` labels for metadata retrieval:
|
||||
- **`internal`** — per-preview bridge network for inter-service communication
|
||||
- Public services join both networks; internal services (e.g. databases) only join `internal`
|
||||
|
||||
## Configuration
|
||||
## Config Discovery
|
||||
|
||||
Preview configuration is discovered from the project directory in this order:
|
||||
See [Setting Up Preview Deployments](#setting-up-preview-deployments-for-a-project) above for the full config reference. Discovery order:
|
||||
|
||||
### 1. `.cw-preview.yml` (explicit CW config)
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
services:
|
||||
frontend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: apps/web/Dockerfile
|
||||
port: 3000
|
||||
route: /
|
||||
healthcheck:
|
||||
path: /
|
||||
interval: 5s
|
||||
retries: 10
|
||||
env:
|
||||
VITE_API_URL: /api
|
||||
dev:
|
||||
image: node:20-alpine
|
||||
command: npm run dev -- --host 0.0.0.0
|
||||
workdir: /app
|
||||
|
||||
backend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: packages/api/Dockerfile
|
||||
port: 8080
|
||||
route: /api
|
||||
healthcheck:
|
||||
path: /health
|
||||
env:
|
||||
DATABASE_URL: postgres://db:5432/app
|
||||
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
port: 5432
|
||||
internal: true # not exposed through proxy
|
||||
env:
|
||||
POSTGRES_PASSWORD: preview
|
||||
```
|
||||
|
||||
The `dev` section is optional per service. When present and mode is `dev`:
|
||||
- `image` (required) — Docker image to run
|
||||
- `command` — override entrypoint
|
||||
- `workdir` — container working directory (default `/app`)
|
||||
|
||||
In dev mode, the project directory is volume-mounted into the container and `node_modules` gets an anonymous volume to prevent host overwrite.
|
||||
|
||||
### 2. `docker-compose.yml` / `compose.yml` (existing compose passthrough)
|
||||
|
||||
If found, the existing compose file is used with gateway network injection.
|
||||
|
||||
### 3. `Dockerfile` (single-service fallback)
|
||||
|
||||
If only a Dockerfile exists, creates a single `app` service building from `.` with port 3000.
|
||||
1. **`.cw-preview.yml`** — explicit CW preview config (recommended)
|
||||
2. **`docker-compose.yml` / `compose.yml`** — existing compose file with gateway network injection
|
||||
3. **`Dockerfile`** — single-service fallback (builds from `.`, assumes port 3000)
|
||||
|
||||
## Module Files
|
||||
|
||||
|
||||
Reference in New Issue
Block a user