You don’t need to understand the technical details to use this feature. The configuration examples below are copy-paste ready.
Automated setup
The repository includes a setup script that creates directories, generates a gateway token, builds the Docker image, and starts the daemon. This is the recommended way to get started.Configure environment
Copy the included environment template and add your API keys:Open
.env in your editor and fill in at minimum:Run the setup script
- Creates the data directory (
~/.comis) with atraces/subdirectory - Generates a gateway authentication token (or reuses an existing one)
- Writes token and network settings to
~/.comis/.env - Creates a default
config.yamlwith gateway, logging, and memory paths - Builds the Docker image from the included
Dockerfile - Fixes data directory ownership for the container’s non-root user (UID 1000)
- Starts the
comis-daemonservice and waits for its health check to pass
Browser tool (optional)
The published image is browser-free. To use the agent browser tool, rebuild from the repo with one of three build args mirroring the bare-VPS install flags. Image-size impact in parentheses./usr/local/bin/comis-entrypoint.sh) starts Xvfb on :99 automatically when the image was built with COMIS_WITH_XVFB=1. The daemon’s findChrome() probes ~/.cloakbrowser/chromium-*/chrome first, so when the cloak binary is baked in it wins over stock Chrome with no config change.
Run the stealth image identically to the no-browser one — same volumes, same ports, same env vars:
Alternative: installer-based image
The repo also shipsDockerfile.install — a fresh Ubuntu 24.04 base that runs install.sh end-to-end inside the container. Same build args, same end state, but exercises the installer code path verbatim. Useful for CI testing or when you want strict parity with a bare-VPS deploy.
Dockerfile is the production path (multi-stage, smaller, faster). Dockerfile.install is the validation/parity path.
See agent-tools/browser for the full flag matrix, verified detection-evasion outcomes, and security model.
Optional services
The daemon is the only service that starts by default. The web dashboard and CLI are available as Docker Compose profiles.Web dashboard
Start the Nginx-served web UI on port 8080:http://localhost:8080 in your browser. The dashboard proxies API
calls and WebSocket connections to the daemon automatically.
CLI
Run one-shot CLI commands against the running daemon:127.0.0.1:4766 without extra configuration.
Stopping and updating
| Action | Command |
|---|---|
| Stop daemon | docker compose down |
| Stop web dashboard | docker compose --profile web down |
| Restart daemon | docker compose restart comis-daemon |
| Update | git pull && docker compose up -d --build |
| View logs | docker compose logs -f comis-daemon |
Deploying on a VPS
The local-machine examples above use-p 4766:4766 for convenience, which
binds the gateway to 0.0.0.0:4766 on the host. On a VPS that’s the
public internet — anyone on the network can reach the gateway. Pick one
of the two safer postures below.
Recommended: loopback bind + reverse proxy
Bind the host port to loopback only and put nginx (or Caddy/Traefik) in front to terminate TLS:docker-compose.yml:
http://127.0.0.1:4766 (HTTP) and
http://127.0.0.1:4766/ws (WebSocket). See
Operations: Reverse Proxy for full nginx /
Caddy snippets with WebSocket upgrade headers.
Acceptable: direct exposure + token auth + firewall
If you don’t want a reverse proxy, you can expose the gateway directly, but you must combine three controls:- Token auth on the gateway. The init wizard enables this by default
(
Authentication method → Token). Verify your~/.comis/config.yamlcontains agateway.tokens:section and~/.comis/.envhas aCOMIS_GATEWAY_TOKEN. - Firewall to trusted IPs only. On Ubuntu/Debian:
- TLS. Without TLS, the bearer token crosses the wire in cleartext.
Either run with
gateway.tls.certconfigured (see Configuration: TLS) or front it with a reverse proxy that does TLS for you (in which case use the recommended posture above instead).
comis status from your laptop against a remote VPS
The CLI’s comis status defaults to reading ~/.comis/config.yaml on the
machine where it runs. Copying the VPS’s config to your laptop won’t work
on its own — gateway.host: 0.0.0.0 is a bind address that the CLI
remaps to local loopback, not the VPS’s public IP.
Set COMIS_GATEWAY_URL (and the matching token) on your laptop instead:
wss:// (TLS) when the gateway is reachable over the public internet.
Use ws:// only over a trusted network (VPN, SSH tunnel).
Common issues
Setup script fails
Setup script fails
Common causes:
- Docker not running — start Docker Desktop or the Docker daemon
- Port 4766 in use — stop the other process or set
COMIS_GATEWAY_PORTin.env - Missing openssl — the script uses
openssl rand -hex 32for token generation; install it with your system package manager
Cannot access dashboard from host
Cannot access dashboard from host
Symptom:
curl http://127.0.0.1:4766/health returns “connection refused”
or “connection reset by peer” even though the container is reported healthy.Fix: Two distinct binds are involved — get them in the right place:- Host-side bind (which interface the host listens on): controlled by the left side of
-p/ Composeports:(e.g.127.0.0.1:4766:4766vs0.0.0.0:4766:4766). - Container-side bind (which interface the daemon listens on inside the container): controlled by
COMIS_GATEWAY_HOSTin.env. Must be0.0.0.0so Docker port-forwarding can reach the daemon. Setting it to127.0.0.1is what produces the “connection reset” symptom — Docker forwards into the container’seth0IP, where nothing is listening. Since 1.0.25 the image defaults to0.0.0.0; on older images set it explicitly.
- The container is running and healthy:
docker compose ps - No firewall is blocking the port
- If you mount a
config.yamlwithgateway.host: 127.0.0.1, that overrides the env var (since 1.0.25). Setgateway.host: 0.0.0.0in the mounted config or remove the entry.
Container exits immediately
Container exits immediately
Symptom: The container starts but stops within seconds.Fix: Check the logs for the error:Common causes:
- Invalid config.yaml — check YAML syntax and required fields. The daemon writes a recovery snapshot at
~/.comis/config.last-good.yaml; runcp ~/.comis/config.last-good.yaml ~/.comis/config.yamlto restore the previous-known-good config, thendocker compose restart. - Missing API key — verify the
.envfile has the correct variable name - Port already in use — another process is using port 4766 on the host
Daemon can't write to .env (`Is a directory` error)
Daemon can't write to .env (`Is a directory` error)
Symptom: Bringing up Compose without first running If
docker-setup.sh,
the daemon fails to persist credentials and you see
cannot create /home/comis/.comis/.env: Is a directory in the logs.Cause: Docker bind-mounts ${COMIS_ENV_FILE:-~/.comis/.env} into the
container. If the host path doesn’t exist, Docker silently creates it
as a directory instead of a file, then every write fails.Fix: create the file before docker compose up:.env already exists as a directory, remove it first:
rmdir ~/.comis/.env && touch ~/.comis/.env.The repo’s docker-setup.sh handles this automatically — this only
affects manual docker compose up.Next steps
Configuration Guide
Customize your agent settings, add channels, and configure advanced options.
Verify Installation
Run diagnostic commands to confirm everything is working.
Operations: Docker
Production-ready Docker deployment with multi-stage builds and security hardening.
