feat: improve dockerization #209

Merged
k9ert merged 12 commits from David/cobot:feature/dockerization into main 2026-03-08 10:40:55 +00:00
Contributor

Adds Docker support for running Cobot in a container via docker-compose, including a Dockerfile fix for file ownership, a new docker-compose.yml, .env.example and quickstart documentation for the Docker workflow. Also extends the wizard init CLI to support OpenRouter as an LLM provider option alongside PPQ and Ollama.

Adds Docker support for running Cobot in a container via docker-compose, including a Dockerfile fix for file ownership, a new docker-compose.yml, .env.example and quickstart documentation for the Docker workflow. Also extends the wizard init CLI to support OpenRouter as an LLM provider option alongside PPQ and Ollama.
- Introduced a new docker-compose.yml file to define the cobot service with volume mappings for data and workspace.
- Updated .gitignore to include Docker-related directories: data/ and workspace/.
- Modified the Dockerfile to create a non-root user 'cobot' and assign ownership of the /app directory to this user, enhancing security and ensuring proper permissions.
- Introduced a new .env.example file for environment variable configuration, including placeholders for API keys.
- Expanded the quickstart documentation to include steps for running Cobot in a Docker container, detailing environment setup and commands for interactive use.
feat: enhance LLM provider options in CLI
All checks were successful
CI / lint (pull_request) Successful in 10s
CI / test (3.11) (pull_request) Successful in 22s
CI / test (3.12) (pull_request) Successful in 23s
CI / test (3.13) (pull_request) Successful in 22s
E2E Tests / e2e (pull_request) Successful in 15s
CI / build (pull_request) Successful in 7s
d76c2357c0
- Updated the CLI to include "openrouter" as a new LLM provider alongside "ppq".
- Adjusted the configuration prompts to reflect the new provider options and their respective API settings.
- Improved default model and API base URL handling based on the selected provider.
Merge remote-tracking branch 'origin/main' into feature/dockerization
All checks were successful
CI / lint (pull_request) Successful in 9s
CI / test (3.11) (pull_request) Successful in 21s
CI / test (3.12) (pull_request) Successful in 23s
CI / test (3.13) (pull_request) Successful in 22s
E2E Tests / e2e (pull_request) Successful in 14s
CI / build (pull_request) Successful in 7s
20ed5936a0
fix: trailing newline in .gitignore + docker health check
All checks were successful
CI / lint (pull_request) Successful in 9s
CI / test (3.11) (pull_request) Successful in 20s
CI / test (3.12) (pull_request) Successful in 22s
CI / test (3.13) (pull_request) Successful in 22s
E2E Tests / e2e (pull_request) Successful in 13s
CI / build (pull_request) Successful in 7s
8e43a89c1d
- .gitignore: add missing trailing newline (POSIX compliance)
- docker-compose.yml: add simple health check (import cobot)
- Added entries for BMad-related directories: _bmad/** and .claude/commands/**.
- Retained existing entries for Docker-related directories.
Merge remote-tracking branch 'refs/remotes/origin/feature/dockerization' into feature/dockerization
All checks were successful
CI / lint (pull_request) Successful in 10s
CI / test (3.11) (pull_request) Successful in 20s
CI / test (3.12) (pull_request) Successful in 23s
CI / test (3.13) (pull_request) Successful in 22s
E2E Tests / e2e (pull_request) Successful in 14s
CI / build (pull_request) Successful in 6s
d4182a97f4
- Added entry for the _bmad-output directory to the .gitignore file.
- Retained existing entries for BMad and other relevant directories.
fix: handle PID 1 in Docker environment
All checks were successful
CI / lint (pull_request) Successful in 9s
CI / test (3.11) (pull_request) Successful in 19s
CI / test (3.12) (pull_request) Successful in 22s
CI / test (3.13) (pull_request) Successful in 24s
E2E Tests / e2e (pull_request) Successful in 20s
CI / build (pull_request) Successful in 8s
86182a10b7
- Updated the read_pid function to unlink the PID file if the process is PID 1 in a Docker container, preventing false "already running" checks.
- This change ensures proper handling of the process lifecycle within Docker environments.
David changed title from feature/dockerization to feat: improve dockerization 2026-03-06 11:25:27 +00:00
Contributor

Review: Docker + OpenRouter wizard support

Clean PR — small, focused, and the quickstart docs are well-written. Some observations:

👍 What works well

  • Dockerfile — slim base, non-root user, chown before USER cobot. Good practice.
  • docker-compose.yml — simple, correct volume mounts. The healthcheck (import cobot) is a reasonable smoke test.
  • Quickstart docs — the Docker section is clear and practical. docker compose run cobot wizard init --home for interactive setup inside the container is a nice UX.
  • OpenRouter as wizard option — maps cleanly to the existing ppq provider config with just a different api_base. No new provider abstraction needed.

⚠️ Issues

1. .env.example names the key PPQ_API_KEY for OpenRouter

PPQ_API_KEY=sk-or-v1-your-openrouter-key-here

This is confusing — someone using OpenRouter has to set a variable called PPQ_API_KEY with an OpenRouter key. The wizard correctly distinguishes the two providers, but the env var naming leaks the abstraction. Consider either:

  • Renaming to something generic like LLM_API_KEY, or
  • Adding a comment: # Works for both PPQ and OpenRouter (same config path)

2. Wizard hardcodes anthropic/claude-sonnet-4 as OpenRouter default

default_model = "anthropic/claude-sonnet-4"

This is a specific (expensive) model. For a default in a setup wizard, something cheaper like anthropic/claude-3.5-haiku or openai/gpt-4o-mini would be more beginner-friendly. Users who want Sonnet will know to type it.

3. docker-compose.yml mounts ./workspace:/workspace but Dockerfile sets COBOT_WORKSPACE=/workspace
This works, but the workspace dir isn't created in the Dockerfile. If cobot run tries to write there before any volume is mounted (e.g., running without compose), it'll fail with a permission error since the non-root user can't create /workspace. Add RUN mkdir -p /workspace && chown cobot:cobot /workspace to the Dockerfile.

4. Healthcheck doesn't verify runtime
python -c "import cobot" only checks the package is installed, not that the agent is running. For a restart: unless-stopped service, a better healthcheck would be something like cobot status --json and checking the running field, or a simple PID file check.

5. .gitignore additions look like a full rewrite, not incremental
The diff shows +10 lines but the file content is a complete .gitignore (50+ lines). Was this file new or did it replace an existing one? If it replaced an existing one, make sure nothing important was dropped. If it's new — looks comprehensive and correct.

📝 Minor

  • The wizard sets config["provider"] = "ppq" when provider == "openrouter" — this is the right internal mapping, but a comment explaining why would help future readers: # OpenRouter uses same config structure as PPQ (OpenAI-compatible API)
  • The quickstart wizard example shows a Telegram user ID 769134210 — that's a real user ID (k9ert's). Consider using a clearly fake one like 123456789 to avoid confusion.

Verdict

Good incremental improvement. The Docker workflow is clean and the OpenRouter support slots in naturally. Fix the workspace directory permissions (#3) and consider the naming confusion (#1). The rest are polish items.

## Review: Docker + OpenRouter wizard support Clean PR — small, focused, and the quickstart docs are well-written. Some observations: ### 👍 What works well - **Dockerfile** — slim base, non-root user, `chown` before `USER cobot`. Good practice. - **docker-compose.yml** — simple, correct volume mounts. The healthcheck (`import cobot`) is a reasonable smoke test. - **Quickstart docs** — the Docker section is clear and practical. `docker compose run cobot wizard init --home` for interactive setup inside the container is a nice UX. - **OpenRouter as wizard option** — maps cleanly to the existing `ppq` provider config with just a different `api_base`. No new provider abstraction needed. ### ⚠️ Issues **1. `.env.example` names the key `PPQ_API_KEY` for OpenRouter** ``` PPQ_API_KEY=sk-or-v1-your-openrouter-key-here ``` This is confusing — someone using OpenRouter has to set a variable called `PPQ_API_KEY` with an OpenRouter key. The wizard correctly distinguishes the two providers, but the env var naming leaks the abstraction. Consider either: - Renaming to something generic like `LLM_API_KEY`, or - Adding a comment: `# Works for both PPQ and OpenRouter (same config path)` **2. Wizard hardcodes `anthropic/claude-sonnet-4` as OpenRouter default** ```python default_model = "anthropic/claude-sonnet-4" ``` This is a specific (expensive) model. For a default in a setup wizard, something cheaper like `anthropic/claude-3.5-haiku` or `openai/gpt-4o-mini` would be more beginner-friendly. Users who want Sonnet will know to type it. **3. `docker-compose.yml` mounts `./workspace:/workspace` but Dockerfile sets `COBOT_WORKSPACE=/workspace`** This works, but the workspace dir isn't created in the Dockerfile. If `cobot run` tries to write there before any volume is mounted (e.g., running without compose), it'll fail with a permission error since the non-root user can't create `/workspace`. Add `RUN mkdir -p /workspace && chown cobot:cobot /workspace` to the Dockerfile. **4. Healthcheck doesn't verify runtime** `python -c "import cobot"` only checks the package is installed, not that the agent is running. For a `restart: unless-stopped` service, a better healthcheck would be something like `cobot status --json` and checking the `running` field, or a simple PID file check. **5. `.gitignore` additions look like a full rewrite, not incremental** The diff shows +10 lines but the file content is a complete `.gitignore` (50+ lines). Was this file new or did it replace an existing one? If it replaced an existing one, make sure nothing important was dropped. If it's new — looks comprehensive and correct. ### 📝 Minor - The wizard sets `config["provider"] = "ppq"` when `provider == "openrouter"` — this is the right internal mapping, but a comment explaining why would help future readers: `# OpenRouter uses same config structure as PPQ (OpenAI-compatible API)` - The quickstart wizard example shows a Telegram user ID `769134210` — that's a real user ID (k9ert's). Consider using a clearly fake one like `123456789` to avoid confusion. ### Verdict Good incremental improvement. The Docker workflow is clean and the OpenRouter support slots in naturally. Fix the workspace directory permissions (#3) and consider the naming confusion (#1). The rest are polish items.
chore: remove bmad from gitignore
All checks were successful
CI / lint (pull_request) Successful in 9s
CI / test (3.11) (pull_request) Successful in 20s
CI / test (3.12) (pull_request) Successful in 24s
CI / test (3.13) (pull_request) Successful in 22s
E2E Tests / e2e (pull_request) Successful in 14s
CI / build (pull_request) Successful in 6s
6b82d8814f
chore: update .env.example and Docker configuration
All checks were successful
CI / lint (pull_request) Successful in 9s
CI / test (3.11) (pull_request) Successful in 19s
CI / test (3.12) (pull_request) Successful in 22s
CI / test (3.13) (pull_request) Successful in 21s
E2E Tests / e2e (pull_request) Successful in 14s
CI / build (pull_request) Successful in 7s
a3f470e1d0
- Updated .env.example to clarify the usage of the LLM API key for both PPQ and OpenRouter.
- Modified docker-compose.yml health check command to use 'cobot status --json' for better status reporting.
- Enhanced Dockerfile to create a workspace directory and assign ownership to the non-root user.
- Added a comment in cli.py to indicate that OpenRouter shares the same configuration structure as PPQ.
- Updated quickstart.md with a placeholder for a sample Telegram user ID.
Author
Contributor

@k9ert can we merge this?

@k9ert can we merge this?
k9ert merged commit ae674f12ce into main 2026-03-08 10:40:55 +00:00
k9ert referenced this pull request from a commit 2026-03-08 10:40:57 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ultanio/cobot!209
No description provided.