From 6962ae89665d8cc387503c6bbc8cda5694f88f0c Mon Sep 17 00:00:00 2001 From: Abdullah-Al-Sami Date: Fri, 9 Oct 2026 14:31:29 +0600 Subject: [PATCH] docs(deployment): add Dokploy Compose setup --- README.md | 2 + compose.dokploy.yml | 66 ++++++++++++++++++++++++++++++++ deployment/dokploy.env.example | 22 +++++++++++ docs/DOKPLOY.md | 69 ++++++++++++++++++++++++++++++++++ docs/SETUP.md | 7 ++++ 5 files changed, 166 insertions(+) create mode 100644 compose.dokploy.yml create mode 100644 deployment/dokploy.env.example create mode 100644 docs/DOKPLOY.md diff --git a/README.md b/README.md index 8d00e323..55ba338c 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,8 @@ Do not run `copilotkit onboard` in this folder. OpenDots already contains its Co See [Setup](docs/SETUP.md) for configuration, Slack, calls, the browser service, and Docker. +To deploy with Dokploy, follow the [Dokploy setup guide](docs/DOKPLOY.md). + ## Data and privacy Conversation messages, tool calls, and run events are persisted in the configured Intelligence deployment. The hosted setup sends them to CopilotKit's cloud; the local evaluation setup uses Intelligence on your machine. OpenDots has no standalone SQLite conversation store. SQLite stores pages, workspace metadata, and thread bindings separately. diff --git a/compose.dokploy.yml b/compose.dokploy.yml new file mode 100644 index 00000000..ababe9e6 --- /dev/null +++ b/compose.dokploy.yml @@ -0,0 +1,66 @@ +# Dokploy: select this file in a Docker Compose service (not Docker Stack). +# Add a domain for service "app", container port 4310, in Dokploy's Domains tab. +services: + app: + build: + context: . + dockerfile: Dockerfile + target: app + expose: + - '4310' + environment: + NODE_ENV: production + HOST: 0.0.0.0 + PORT: '4310' + DATABASE_PATH: /data/opendots.sqlite + OWNER_TOKEN: ${OWNER_TOKEN:?Set a random OWNER_TOKEN of at least 24 characters in Dokploy} + APP_ORIGIN: ${APP_ORIGIN:?Set your exact HTTPS origin in Dokploy, without a trailing slash} + OWNER_ID: ${OWNER_ID:-opendots-owner} + CPK_INTELLIGENCE_API_KEY: ${CPK_INTELLIGENCE_API_KEY:-} + INTELLIGENCE_API_KEY: ${INTELLIGENCE_API_KEY:-} + CPK_TELEMETRY_ID: ${CPK_TELEMETRY_ID:-} + INTELLIGENCE_API_URL: ${INTELLIGENCE_API_URL:-} + INTELLIGENCE_GATEWAY_WS_URL: ${INTELLIGENCE_GATEWAY_WS_URL:-} + INTELLIGENCE_WS_URL: ${INTELLIGENCE_WS_URL:-} + OPENAI_API_KEY: ${OPENAI_API_KEY:-} + OPENAI_BASE_URL: ${OPENAI_BASE_URL:-https://api.openai.com/v1} + OPENAI_MODEL: ${OPENAI_MODEL:-} + WEB_SEARCH_PROVIDER: ${WEB_SEARCH_PROVIDER:-parallel} + PARALLEL_API_KEY: ${PARALLEL_API_KEY:-} + VOICE_API_KEY: ${VOICE_API_KEY:-} + VOICE_MODEL: ${VOICE_MODEL:-} + VOICE_NAME: ${VOICE_NAME:-marin} + SLACK_CHANNEL_NAME: ${SLACK_CHANNEL_NAME:-} + SLACK_TEAM_ID: ${SLACK_TEAM_ID:-} + SLACK_USER_IDS: ${SLACK_USER_IDS:-} + SLACK_DOT_ID: ${SLACK_DOT_ID:-} + COMPUTER_SUPERVISOR_URL: ${COMPUTER_SUPERVISOR_URL:-} + COMPUTER_SUPERVISOR_TOKEN: ${COMPUTER_SUPERVISOR_TOKEN:-} + COMPUTER_TOKEN: ${COMPUTER_TOKEN:-} + COMPUTER_NAMESPACE: ${COMPUTER_NAMESPACE:-opendots} + DO_NOT_TRACK: ${DO_NOT_TRACK:-0} + COPILOTKIT_TELEMETRY_DISABLED: ${COPILOTKIT_TELEMETRY_DISABLED:-false} + COPILOTKIT_TELEMETRY_SAMPLE_RATE: ${COPILOTKIT_TELEMETRY_SAMPLE_RATE:-1} + volumes: + - opendots-data:/data + init: true + restart: unless-stopped + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + healthcheck: + test: + [ + 'CMD', + 'node', + '-e', + "fetch('http://127.0.0.1:4310/').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))", + ] + interval: 30s + timeout: 10s + start_period: 30s + retries: 3 + +volumes: + opendots-data: diff --git a/deployment/dokploy.env.example b/deployment/dokploy.env.example new file mode 100644 index 00000000..85085f70 --- /dev/null +++ b/deployment/dokploy.env.example @@ -0,0 +1,22 @@ +# Paste into Dokploy's Environment tab and replace the two required values. +# These are placeholders. Do not commit real credentials. +APP_ORIGIN=https://dots.your-domain.com +OWNER_TOKEN=REPLACE_WITH_A_RANDOM_SECRET_OF_AT_LEAST_24_CHARACTERS +OWNER_ID=opendots-owner + +# AI chat: select a CopilotKit Intelligence project, then add its project key. +# Keep the CLI-generated telemetry ID with its corresponding project key. +CPK_INTELLIGENCE_API_KEY= +CPK_TELEMETRY_ID= +OPENAI_API_KEY= +OPENAI_MODEL= +OPENAI_BASE_URL=https://api.openai.com/v1 + +# Optional voice calls: a Realtime-capable key and model are required. +VOICE_API_KEY= +VOICE_MODEL= +VOICE_NAME=marin + +# Public-web research defaults to Parallel; no key needed for light use. +WEB_SEARCH_PROVIDER=parallel +PARALLEL_API_KEY= diff --git a/docs/DOKPLOY.md b/docs/DOKPLOY.md new file mode 100644 index 00000000..f558fd87 --- /dev/null +++ b/docs/DOKPLOY.md @@ -0,0 +1,69 @@ +# Deploy OpenDots with Dokploy + +OpenDots includes `compose.dokploy.yml` for a single-owner Dokploy deployment. +It builds the **app** Docker stage, serves port **4310**, and persists pages and +workspace settings in the `opendots-data` named volume. Dokploy routes your HTTPS +domain to the container; there is no host port mapping to configure. + +## First deployment + +1. In your Dokploy project, create a **Docker Compose** service. Choose Compose, + not Docker Stack: this configuration builds from source. +2. Choose GitHub as the source, select your OpenDots repository and branch, + and set Compose path **compose.dokploy.yml**. If your connected GitHub source + limits repository access, include your repository in its allowed repositories. +3. In **Environment**, paste `deployment/dokploy.env.example`. Replace + `APP_ORIGIN` with your exact public origin, such as `https://dots.example.com`, + without a path or trailing slash. Replace `OWNER_TOKEN` with a random secret + of at least 24 characters; it is the token you use to unlock the app. + Generate one locally with: + + ```sh + node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))" + ``` + +4. Point the domain's DNS record to your server. In Dokploy's **Domains** tab, + add that same hostname, select service **app**, container port **4310**, + path **/**, and enable HTTPS with Let's Encrypt. Use **Preview Compose** + to inspect Dokploy's generated routing settings. +5. Click **Deploy**. Open the domain and enter your `OWNER_TOKEN`. Until AI + credentials are supplied, Spaces, pages and Dot preferences work in setup mode. + +After this initial configuration, use **Deploy** for subsequent deployments. +You can enable Dokploy Auto Deploy if you want pushes to trigger deployment. + +## Enable AI chat + +In your local OpenDots folder, run: + +```sh +npx copilotkit@latest login +npx copilotkit@latest project select +``` + +The CLI writes `CPK_INTELLIGENCE_API_KEY` and its `CPK_TELEMETRY_ID` to your local +`.env`. Copy those values into Dokploy's **Environment** tab, then add +`OPENAI_API_KEY` and `OPENAI_MODEL` for your chosen model provider. Save and deploy +again. Keep secrets in Dokploy's environment settings; never commit `.env`. +Do not run `copilotkit onboard`: OpenDots already includes the integration. + +Chat stores its conversation history in CopilotKit Intelligence. The named volume +stores pages, workspace configuration and thread bindings. Back up both layers; +keep the Dokploy service/project name stable to retain its volume, and do not +delete that volume when updating the application. + +Voice, Slack and per-Dot computers need their own service configuration. See +`docs/SETUP.md` and `docs/COMPUTERS.md`. This deployment uses the default Parallel +research provider; the optional browser worker is not part of this Compose file. + +## Verification and references + +Successful startup logs include `OpenDots template listening on http://0.0.0.0:4310`. +The container health check verifies the web server responds; confirm AI chat +separately after configuring its credentials. + +- [Dokploy Docker Compose](https://docs.dokploy.com/docs/core/docker-compose) +- [Dokploy Compose domain routing](https://docs.dokploy.com/docs/core/docker-compose/domains) + +Deployment and connected AI responses require your Dokploy configuration and +account credentials. Verify chat separately from the container health check. diff --git a/docs/SETUP.md b/docs/SETUP.md index 274b3151..b2dfc325 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -179,6 +179,13 @@ docker compose down For remote hosting, configure an HTTPS reverse proxy and the matching `APP_ORIGIN`. See [Security](../SECURITY.md) for the template's deployment boundary. +### Dokploy + +For deployment through Dokploy, use `compose.dokploy.yml` and follow the +[Dokploy setup guide](DOKPLOY.md). It selects the application Docker stage, keeps +workspace data in a named volume, and uses Dokploy's domain routing to serve port 4310. Set `OWNER_TOKEN` and the exact HTTPS `APP_ORIGIN` in Dokploy's Environment +tab before deploying; add Intelligence and model credentials to enable chat. + ## Automatic Learning OpenDots connects [CopilotKit Automatic Learning](https://docs.copilotkit.ai/learning)