feat: install Cursor Agent CLI in image with API key auth

Bake agent into the pi user PATH; pass CURSOR_API_KEY from .env so no browser login is required.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Frank Schwenk
2026-08-01 11:50:30 +02:00
parent eb6b0d2fac
commit 063b16296c
5 changed files with 19 additions and 3 deletions
+4
View File
@@ -3,6 +3,10 @@
# OpenRouter (recommended default provider for this stack) # OpenRouter (recommended default provider for this stack)
OPENROUTER_API_KEY=sk-or-v1-replace-me OPENROUTER_API_KEY=sk-or-v1-replace-me
# Cursor Agent CLI (https://cursor.com/dashboard/api)
# https://cursor.com/docs/cli/reference/authentication
CURSOR_API_KEY=key_replace_me
# Match host user that owns the workspace mount (boka: id -u / id -g → 1002) # Match host user that owns the workspace mount (boka: id -u / id -g → 1002)
PUID=1002 PUID=1002
PGID=1002 PGID=1002
+4 -1
View File
@@ -18,7 +18,7 @@ ssh frank-schwenk.de
cd /home/frank/pi.schwenk.online cd /home/frank/pi.schwenk.online
cp .env.example .env cp .env.example .env
# edit OPENROUTER_API_KEY # edit OPENROUTER_API_KEY and CURSOR_API_KEY (https://cursor.com/dashboard/api)
# PUID/PGID = host user (frank on boka: 1002) — must match `id -u` / `id -g` # PUID/PGID = host user (frank on boka: 1002) — must match `id -u` / `id -g`
# WORKSPACE_HOST_PATH=/home/frank # WORKSPACE_HOST_PATH=/home/frank
@@ -43,6 +43,8 @@ docker compose exec web ls /workspaces/eselhoefe.de
6. Packages: Settings → Pi packages, or 6. Packages: Settings → Pi packages, or
`docker compose exec sessiond pi install npm:<package>` `docker compose exec sessiond pi install npm:<package>`
(persists in `data/pi-agent`) (persists in `data/pi-agent`)
7. Cursor CLI: `docker compose exec web agent --version`
Auth: `docker compose exec web agent status` (needs `CURSOR_API_KEY` in `.env`)
## Ops ## Ops
@@ -60,3 +62,4 @@ docker compose build --no-cache && docker compose up -d
- Middleware is referenced only (`authelia@docker`); ForwardAuth is defined on Authelia - Middleware is referenced only (`authelia@docker`); ForwardAuth is defined on Authelia
- `pi-coding-agent` pinned to `0.82.1` for current `pi-web` peer range - `pi-coding-agent` pinned to `0.82.1` for current `pi-web` peer range
- Container runs as `PUID`/`PGID` (default 1002) so bind mounts under `/home/frank` are readable - Container runs as `PUID`/`PGID` (default 1002) so bind mounts under `/home/frank` are readable
- Cursor Agent CLI (`agent`) is in the image; auth via `CURSOR_API_KEY` only (no browser login)
+7 -1
View File
@@ -41,9 +41,15 @@ ENV HOME=/home/pi \
PI_WEB_HOST=0.0.0.0 \ PI_WEB_HOST=0.0.0.0 \
PI_WEB_PORT=8504 \ PI_WEB_PORT=8504 \
PI_WEB_ALLOWED_HOSTS=pi.schwenk.online \ PI_WEB_ALLOWED_HOSTS=pi.schwenk.online \
PATH="/usr/local/bin:${PATH}" PATH="/home/pi/.local/bin:/home/pi/.cursor/bin:/usr/local/bin:${PATH}"
USER pi USER pi
# Cursor Agent CLI — auth via CURSOR_API_KEY at runtime (not baked into image)
# https://cursor.com/docs/cli/installation
RUN curl -fsSL https://cursor.com/install | bash \
&& agent --version
WORKDIR /workspaces WORKDIR /workspaces
EXPOSE 8504 EXPOSE 8504
+2 -1
View File
@@ -49,7 +49,8 @@ Fränky — single trusted user; remote control surface for agent work under `/h
- **Data:** `./data/pi-web` (PI WEB state + sessiond socket), `./data/pi-agent``/home/pi/.pi/agent` (sessions, packages, auth) - **Data:** `./data/pi-web` (PI WEB state + sessiond socket), `./data/pi-agent``/home/pi/.pi/agent` (sessions, packages, auth)
- **Workspaces:** host path via `WORKSPACE_HOST_PATH` → container `/workspaces` - **Workspaces:** host path via `WORKSPACE_HOST_PATH` → container `/workspaces`
- **UID:** `PUID`/`PGID` in `.env` must match host owner of the mount (boka frank = 1002) - **UID:** `PUID`/`PGID` in `.env` must match host owner of the mount (boka frank = 1002)
- **Secrets:** `OPENROUTER_API_KEY` in `.env` (see `.env.example`) - **Cursor CLI:** `agent` installed in image; auth via `CURSOR_API_KEY` (no browser login)
- **Secrets:** `OPENROUTER_API_KEY`, `CURSOR_API_KEY` in `.env` (see `.env.example`)
### Authelia handoff (consumed) ### Authelia handoff (consumed)
+2
View File
@@ -24,6 +24,7 @@ services:
PI_WEB_SESSIOND_SOCKET: /data/pi-web/sessiond.sock PI_WEB_SESSIOND_SOCKET: /data/pi-web/sessiond.sock
PI_CODING_AGENT_DIR: /home/pi/.pi/agent PI_CODING_AGENT_DIR: /home/pi/.pi/agent
OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-} OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-}
CURSOR_API_KEY: ${CURSOR_API_KEY:-}
volumes: volumes:
- ./data/pi-web:/data/pi-web - ./data/pi-web:/data/pi-web
- ./data/pi-agent:/home/pi/.pi/agent - ./data/pi-agent:/home/pi/.pi/agent
@@ -56,6 +57,7 @@ services:
PI_WEB_ALLOWED_HOSTS: pi.schwenk.online PI_WEB_ALLOWED_HOSTS: pi.schwenk.online
PI_CODING_AGENT_DIR: /home/pi/.pi/agent PI_CODING_AGENT_DIR: /home/pi/.pi/agent
OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-} OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-}
CURSOR_API_KEY: ${CURSOR_API_KEY:-}
volumes: volumes:
- ./data/pi-web:/data/pi-web - ./data/pi-web:/data/pi-web
- ./data/pi-agent:/home/pi/.pi/agent - ./data/pi-agent:/home/pi/.pi/agent