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:
Lukas May
2026-03-05 12:31:57 +01:00
parent 143aad58e8
commit 3913aa2e28

View File

@@ -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