Compare commits
2 Commits
fix/isolat
...
feature/OR
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c1e5fff52 | ||
| d0a34249cc |
52
.env.staging.example
Normal file
52
.env.staging.example
Normal file
@@ -0,0 +1,52 @@
|
||||
# STAGING env for orchestrator-staging (port 8501).
|
||||
# Plane/Gitea tokens and sandbox project — configured in ORCH-32.
|
||||
# On Stage 1 (ORCH-31) you can copy from prod .env, changing only isolation-related keys.
|
||||
#
|
||||
# DO NOT COMMIT the real .env.staging — this file is the template only.
|
||||
# Create .env.staging on the server and fill in real values before starting staging.
|
||||
|
||||
# ── Plane ─────────────────────────────────────────────────────────────────────
|
||||
ORCH_PLANE_API_URL=http://localhost:8091
|
||||
ORCH_PLANE_API_TOKEN=<plane-api-token>
|
||||
ORCH_PLANE_WORKSPACE_SLUG=<workspace-slug>
|
||||
ORCH_PLANE_WEBHOOK_SECRET=<webhook-secret>
|
||||
|
||||
# Per-agent Plane bot tokens (authorship in Plane comments).
|
||||
# Leave empty to use ORCH_PLANE_API_TOKEN fallback.
|
||||
ORCH_PLANE_BOT_ANALYST=
|
||||
ORCH_PLANE_BOT_ARCHITECT=
|
||||
ORCH_PLANE_BOT_DEVELOPER=
|
||||
ORCH_PLANE_BOT_REVIEWER=
|
||||
ORCH_PLANE_BOT_TESTER=
|
||||
ORCH_PLANE_BOT_DEPLOYER=
|
||||
ORCH_PLANE_BOT_STREAM=
|
||||
|
||||
# ── Gitea ─────────────────────────────────────────────────────────────────────
|
||||
ORCH_GITEA_URL=http://localhost:3000
|
||||
ORCH_GITEA_PUBLIC_URL=https://git.mva154.duckdns.org
|
||||
ORCH_GITEA_TOKEN=<gitea-token>
|
||||
ORCH_GITEA_WEBHOOK_SECRET=<gitea-webhook-secret>
|
||||
|
||||
# ── Telegram ──────────────────────────────────────────────────────────────────
|
||||
ORCH_TELEGRAM_BOT_TOKEN=<telegram-bot-token>
|
||||
ORCH_TELEGRAM_CHAT_ID=<telegram-chat-id>
|
||||
|
||||
# ── Claude / repos ────────────────────────────────────────────────────────────
|
||||
ORCH_CLAUDE_BIN=/usr/bin/claude
|
||||
ORCH_REPOS_DIR=/repos
|
||||
ORCH_HOST_REPOS_DIR=/home/slin/repos
|
||||
|
||||
# ── Database (ISOLATION KEY for staging) ─────────────────────────────────────
|
||||
# The staging volume mounts ./data/staging:/app/data, so the DB physically lives
|
||||
# at ./data/staging/orchestrator.db on the host — fully isolated from prod.
|
||||
# Do NOT change this path; isolation is achieved via the volume mount, not this path.
|
||||
ORCH_DB_PATH=/app/data/orchestrator.db
|
||||
|
||||
# ── Concurrency / worker ──────────────────────────────────────────────────────
|
||||
ORCH_MAX_CONCURRENCY=1
|
||||
ORCH_QUEUE_POLL_INTERVAL=2.0
|
||||
|
||||
# ── Deploy hook ───────────────────────────────────────────────────────────────
|
||||
DEPLOY_SSH_USER=slin
|
||||
DEPLOY_SSH_HOST=127.0.0.1
|
||||
DEPLOY_HOOK_SCRIPT=/home/slin/bin/enduro-deploy-hook.sh
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,3 +5,7 @@ __pycache__/
|
||||
data/
|
||||
*.db
|
||||
.pytest_cache/
|
||||
# ORCH-31: staging env (secrets, not committed — see .env.staging.example)
|
||||
.env.staging
|
||||
# ORCH-31: staging DB data directory
|
||||
data/staging/
|
||||
|
||||
@@ -25,3 +25,39 @@ services:
|
||||
- DEPLOY_HOOK_SCRIPT=/home/slin/bin/enduro-deploy-hook.sh
|
||||
group_add:
|
||||
- "999"
|
||||
|
||||
# ORCH-31: staging instance (port 8501, isolated DB).
|
||||
# Starts ONLY with: docker compose --profile staging up -d orchestrator-staging
|
||||
# Normal "docker compose up -d" does NOT start this service.
|
||||
orchestrator-staging:
|
||||
profiles:
|
||||
- staging
|
||||
build: .
|
||||
container_name: orchestrator-staging
|
||||
restart: unless-stopped
|
||||
init: true
|
||||
network_mode: host
|
||||
command: ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8501"]
|
||||
volumes:
|
||||
- ./data/staging:/app/data
|
||||
- /home/slin/repos:/repos
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /usr/lib/node_modules/@anthropic-ai/claude-code:/opt/claude-code:ro
|
||||
- /usr/bin/node:/usr/bin/node:ro
|
||||
- /home/slin/.claude:/home/slin/.claude
|
||||
- /home/slin/.claude.json:/home/slin/.claude.json:ro
|
||||
- /home/slin/.orchestrator-ssh:/root/.ssh:ro
|
||||
env_file: .env.staging
|
||||
environment:
|
||||
- ORCH_REPOS_DIR=/repos
|
||||
- ORCH_HOST_REPOS_DIR=/home/slin/repos
|
||||
- DEPLOY_SSH_USER=slin
|
||||
- DEPLOY_SSH_HOST=127.0.0.1
|
||||
- DEPLOY_HOOK_SCRIPT=/home/slin/bin/enduro-deploy-hook.sh
|
||||
# Staging DB is isolated via ./data/staging volume mount.
|
||||
# Inside the container the path remains /app/data/orchestrator.db (same default),
|
||||
# but on the host it physically lives at ./data/staging/orchestrator.db —
|
||||
# completely separate from prod ./data/orchestrator.db.
|
||||
- ORCH_DB_PATH=/app/data/orchestrator.db
|
||||
group_add:
|
||||
- "999"
|
||||
|
||||
85
docs/STAGING.md
Normal file
85
docs/STAGING.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Staging Environment (ORCH-31)
|
||||
|
||||
Orchestrator supports a permanent **staging instance** running on port **8501** with a
|
||||
fully-isolated SQLite database. The staging instance shares the same codebase and
|
||||
Dockerfile as production but is started under the `staging` Docker Compose profile so it
|
||||
**never starts accidentally** during a normal `docker compose up -d`.
|
||||
|
||||
## Architecture
|
||||
|
||||
| | Production | Staging |
|
||||
|---|---|---|
|
||||
| Port | 8500 | 8501 |
|
||||
| Container name | `orchestrator` | `orchestrator-staging` |
|
||||
| DB (host path) | `./data/orchestrator.db` | `./data/staging/orchestrator.db` |
|
||||
| DB (container path) | `/app/data/orchestrator.db` | `/app/data/orchestrator.db` |
|
||||
| env file | `.env` | `.env.staging` |
|
||||
| Compose profile | *(default)* | `staging` |
|
||||
|
||||
DB isolation is achieved via a separate volume mount (`./data/staging:/app/data`), not by
|
||||
changing `ORCH_DB_PATH` — the container path stays identical while the host path is a
|
||||
different directory.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **`.env.staging`** — create from the template (see below). This file is **not committed**
|
||||
to the repo (it contains secrets). Copy and fill in values before first start.
|
||||
2. **`./data/staging/`** directory — created automatically on first container start.
|
||||
|
||||
### Create `.env.staging`
|
||||
|
||||
```bash
|
||||
cd /home/slin/repos/orchestrator
|
||||
cp .env.staging.example .env.staging
|
||||
# Edit .env.staging — fill in real tokens / secrets.
|
||||
# At Stage 1 (ORCH-31) you can reuse prod values; sandbox Plane project
|
||||
# and isolated Gitea webhook will be wired in ORCH-32.
|
||||
nano .env.staging
|
||||
```
|
||||
|
||||
## Starting Staging
|
||||
|
||||
```bash
|
||||
cd /home/slin/repos/orchestrator
|
||||
docker compose --profile staging up -d orchestrator-staging
|
||||
```
|
||||
|
||||
Check it is running:
|
||||
|
||||
```bash
|
||||
docker ps | grep orchestrator-staging
|
||||
curl -s http://localhost:8501/health | python3 -m json.tool
|
||||
```
|
||||
|
||||
## Stopping Staging
|
||||
|
||||
```bash
|
||||
docker compose --profile staging stop orchestrator-staging
|
||||
# or remove the container entirely:
|
||||
docker compose --profile staging down orchestrator-staging
|
||||
```
|
||||
|
||||
## Normal `up -d` does NOT start staging
|
||||
|
||||
```bash
|
||||
# This starts ONLY the prod orchestrator (port 8500). Staging is NOT affected.
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
The `profiles: [staging]` directive in `docker-compose.yml` ensures staging is
|
||||
completely invisible to commands that do not pass `--profile staging`.
|
||||
|
||||
## Logs
|
||||
|
||||
```bash
|
||||
docker logs -f orchestrator-staging
|
||||
```
|
||||
|
||||
## Roadmap
|
||||
|
||||
| Task | Description |
|
||||
|---|---|
|
||||
| **ORCH-31** *(this PR)* | Infra: compose service, .env template, gitignore, docs |
|
||||
| **ORCH-32** | Sandbox: isolated Plane project + Gitea repo for staging |
|
||||
| **ORCH-33** | Test suite running against staging endpoint |
|
||||
| **ORCH-34** | Deploy hook: promote `orchestrator:candidate` image to staging |
|
||||
Reference in New Issue
Block a user