Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Use this as a **discoverability** pass for the **[ROADMAP.md](../ROADMAP.md)** s
|------|---------|
| [quickstart/](quickstart/) | Minimal workspace used by `flightdeck-quickstart-verify`. |
| [ci/](ci/README.md) | Policy gate script, sample policy YAML, GitHub Actions job snippets. |
| [deploy/](deploy/README.md) | Dockerfile and compose for `flightdeck serve`. |
| [deploy/](deploy/README.md) | Dockerfile and compose for `flightdeck serve`; optional **Railway** (`railway.toml`). |
| [integration/](integration/README.md) | Sample event emitter for HTTP ingest. |
| [integration/adoption/](integration/adoption/README.md) | OpenAI, Anthropic, LangChain, Agents SDK, CrewAI-style totals, Temporal labels → `RunEvent`. |
| [fleet/](fleet/README.md) | Multi-workspace naming, optional catalog path, approval workflow notes. |
Expand Down
3 changes: 2 additions & 1 deletion examples/deploy/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ RUN chmod +x /entrypoint.sh

EXPOSE 8765

# Respect PORT at runtime (e.g. Railway); default matches local Compose.
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8765/health').read()"
CMD python -c "import os,urllib.request; p=os.environ.get('PORT','8765'); urllib.request.urlopen(f'http://127.0.0.1:{p}/health').read()"

ENTRYPOINT ["/entrypoint.sh"]
25 changes: 24 additions & 1 deletion examples/deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Build (from this directory):
docker build -t flightdeck-serve:local .
```

The image installs **`flightdeck-ai`** from PyPI and runs **`flightdeck serve`** on **`0.0.0.0:8765`** inside the container.
The image installs **`flightdeck-ai`** from PyPI and runs **`flightdeck serve`** on **`0.0.0.0`** using port **`8765`** by default. On platforms that set **`PORT`** (for example **Railway**), **`entrypoint.sh`** binds to **`$PORT`** instead.

**`entrypoint.sh`** creates a default **`flightdeck.yaml`** in `/workspace` on first start (`flightdeck init`) if the mounted volume is empty.

Expand Down Expand Up @@ -40,6 +40,29 @@ Inside the Compose stack, **`exec`** into the running container with **`/workspa

Set **`FLIGHTDECK_LOCAL_API_TOKEN`** in your environment before `docker compose up` (or in an `.env` file beside `docker-compose.yml`). Clients must send **`Authorization: Bearer …`** for **ledger writes**: **`POST /v1/promote*`**, **`POST /v1/rollback`**, and **`POST /v1/events`**. With no token configured, those routes accept only **loopback** callers. **`POST /v1/diff`** stays unauthenticated (read-only); still treat network placement as a trust boundary.

## Railway

[Railway](https://railway.app/) often suits **small demos**; pricing and free allowances change — confirm **[Railway pricing](https://railway.com/pricing)** before relying on **`$0/month`** long term.

### Deploy from this repo

1. Create a **new project** → **Deploy from GitHub** (or **`railway init`** / **`railway link`** with the [CLI](https://docs.railway.app/guides/cli)).
2. Set the service **root directory** to **`examples/deploy`** so Railway builds **`Dockerfile`** and picks up **`railway.toml`** (config-as-code).
If the dashboard root cannot be a subdirectory, set [**`RAILWAY_DOCKERFILE_PATH`**](https://docs.railway.app/guides/dockerfiles) (service variable) to **`examples/deploy/Dockerfile`** and point **config as code** at **`examples/deploy/railway.toml`** per [config-as-code](https://docs.railway.app/guides/config-as-code).
3. **Networking:** enable **Public Networking** and **Generate Domain** (HTTPS). Railway routes traffic to the **`PORT`** your process listens on; **`entrypoint.sh`** uses **`PORT`** automatically.
4. **Variables (recommended for any public URL):** add **`FLIGHTDECK_LOCAL_API_TOKEN`** (random secret). The stock PyPI image does **not** embed that token in the browser bundle — use **read-only UI** (`VITE_FLIGHTDECK_UI_READ_ONLY=true` in a **custom image build**) or rebuild static assets with **`VITE_FLIGHTDECK_LOCAL_API_TOKEN`** so the UI can authenticate when **`read_auth`** is bearer-gated — see **`docs/web-ui.md`** and **[SECURITY.md](../../SECURITY.md)**.
5. **Persistent SQLite (optional):** add a [Railway volume](https://docs.railway.app/guides/volumes) mounted at **`/workspace`** so redeploys keep **`.flightdeck/`**. Without a volume, the ledger may reset when the container is recreated.

CLI sketch (from **`examples/deploy`** after **`railway link`**):

```bash
railway login
cd examples/deploy
railway variable set FLIGHTDECK_LOCAL_API_TOKEN="$(openssl rand -hex 24)"
railway up
railway domain # generate .railway.app URL if needed
```

## Helm (optional single-replica chart)

A minimal chart lives under **`chart/flightdeck/`**. It runs one replica of **`flightdeck serve`** with an **`emptyDir`** workspace (ephemeral); for a persistent ledger, replace the volume in **`templates/deployment.yaml`** with a PVC or mount your own image init.
Expand Down
4 changes: 3 additions & 1 deletion examples/deploy/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ cd /workspace
if [ ! -f flightdeck.yaml ]; then
flightdeck init
fi
exec flightdeck serve --host 0.0.0.0 --port 8765 "$@"
# Railway (and some PaaS) inject PORT; local Compose defaults to 8765 via Dockerfile EXPOSE.
FD_PORT="${PORT:-8765}"
exec flightdeck serve --host 0.0.0.0 --port "$FD_PORT" "$@"
14 changes: 14 additions & 0 deletions examples/deploy/railway.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Railway config-as-code for FlightDeck reference image.
# Deploy with repo root directory set to `examples/deploy` (GitHub integration),
# or run `railway up` from this directory after `railway link`.
#
# Docs: https://docs.railway.app/guides/config-as-code

[build]
builder = "DOCKERFILE"
dockerfilePath = "Dockerfile"

[deploy]
healthcheckPath = "/health"
healthcheckTimeout = 300
restartPolicyType = "ON_FAILURE"
Loading