Dokploy

Arche

Arche is a self-hosted AI workspace platform that spawns per-user OpenCode coding containers backed by a shared Knowledge Base. Requires the `arche-internal` external Docker network and `/opt/arche/{kb-content,kb-config,users}` directories on the host before deploy. Images are linux/amd64 by default; override `ARCHE_WEB_IMAGE` and `ARCHE_WORKSPACE_IMAGE` to the `-arm64` tag variants for ARM64 hosts.

Arche logo

Configuration

version: "3.8"

# Arche — AI workspace platform that spawns per-user OpenCode containers
# via a Docker socket proxy.
#
# PRE-REQUISITES (run once on the VPS before deploying):
#   mkdir -p /opt/arche/kb-content /opt/arche/kb-config /opt/arche/users
#
# Optional (only needed to seed the Knowledge Base):
#   git init --bare --initial-branch=main /opt/arche/kb-content
#   git init --bare --initial-branch=main /opt/arche/kb-config
#
# POST-DEPLOY (set in Dokploy → Environment, then redeploy):
#   1. Deploy this template once. Dokploy auto-creates a network for the
#      compose stack.
#   2. SSH into the host and find the network name:
#        docker network ls --format '{{.Name}}' | grep arche
#      It looks like `<stack-name>_default` or similar.
#   3. Add the env var OPENCODE_NETWORK=<that-network-name> and redeploy.
#      Without it, spawned user workspaces will fail to start.
#
# IMAGE ARCHITECTURE:
#   Default tags target linux/amd64. For ARM64 hosts (Apple Silicon,
#   Ampere, Graviton), override both images to the `-arm64` variants in
#   Dokploy → Environment:
#     ARCHE_WEB_IMAGE=ghcr.io/peaberry-studio/arche/web:latest-arm64
#     ARCHE_WORKSPACE_IMAGE=ghcr.io/peaberry-studio/arche/workspace:latest-arm64

services:
  web:
    image: ${ARCHE_WEB_IMAGE:-ghcr.io/peaberry-studio/arche/web:latest}
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
      docker-socket-proxy:
        condition: service_started
    environment:
      ARCHE_DOMAIN: ${ARCHE_DOMAIN}
      DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/arche?schema=public

      ARCHE_SESSION_PEPPER: ${ARCHE_SESSION_PEPPER}
      ARCHE_ENCRYPTION_KEY: ${ARCHE_ENCRYPTION_KEY}
      ARCHE_INTERNAL_TOKEN: ${ARCHE_INTERNAL_TOKEN}
      ARCHE_GATEWAY_TOKEN_SECRET: ${ARCHE_GATEWAY_TOKEN_SECRET}
      ARCHE_CONNECTOR_OAUTH_STATE_SECRET: ${ARCHE_CONNECTOR_OAUTH_STATE_SECRET}

      ARCHE_GATEWAY_TOKEN_TTL_SECONDS: "86400"
      ARCHE_GATEWAY_BASE_URL: http://web:3000
      ARCHE_PUBLIC_BASE_URL: https://${ARCHE_DOMAIN}
      ARCHE_SESSION_TTL_DAYS: "7"
      ARCHE_COOKIE_SECURE: "true"

      ARCHE_SEED_ADMIN_EMAIL: ${ARCHE_SEED_ADMIN_EMAIL}
      ARCHE_SEED_ADMIN_PASSWORD: ${ARCHE_SEED_ADMIN_PASSWORD}
      ARCHE_SEED_ADMIN_SLUG: ${ARCHE_SEED_ADMIN_SLUG:-admin}

      CONTAINER_PROXY_HOST: docker-socket-proxy
      CONTAINER_PROXY_PORT: "2375"
      OPENCODE_IMAGE: ${ARCHE_WORKSPACE_IMAGE:-ghcr.io/peaberry-studio/arche/workspace:latest}
      OPENCODE_NETWORK: ${OPENCODE_NETWORK}

      KB_CONTENT_HOST_PATH: /opt/arche/kb-content
      KB_CONFIG_HOST_PATH: /opt/arche/kb-config
      ARCHE_USERS_PATH: /opt/arche/users
    expose:
      - "3000"
    volumes:
      - /opt/arche/kb-content:/kb-content
      - /opt/arche/kb-config:/kb-config
      - /opt/arche/users:/opt/arche/users

  postgres:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_DB: arche
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  docker-socket-proxy:
    image: ghcr.io/tecnativa/docker-socket-proxy:master
    restart: unless-stopped
    environment:
      CONTAINERS: 1
      NETWORKS: 1
      IMAGES: 1
      INFO: 1
      POST: 1
      VOLUMES: 1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

volumes:
  postgres_data:
[variables]
main_domain = "${domain}"
postgres_password = "${password:32}"
session_pepper = "${base64:32}"
encryption_key = "${base64:32}"
internal_token = "${base64:32}"
gateway_token_secret = "${base64:32}"
connector_oauth_state_secret = "${base64:32}"
seed_admin_email = "${email}"
seed_admin_password = "${password:16}"

[config]
env = [
  "ARCHE_DOMAIN=${main_domain}",
  "POSTGRES_PASSWORD=${postgres_password}",
  "ARCHE_SESSION_PEPPER=${session_pepper}",
  "ARCHE_ENCRYPTION_KEY=${encryption_key}",
  "ARCHE_INTERNAL_TOKEN=${internal_token}",
  "ARCHE_GATEWAY_TOKEN_SECRET=${gateway_token_secret}",
  "ARCHE_CONNECTOR_OAUTH_STATE_SECRET=${connector_oauth_state_secret}",
  "ARCHE_SEED_ADMIN_EMAIL=${seed_admin_email}",
  "ARCHE_SEED_ADMIN_PASSWORD=${seed_admin_password}",
  "ARCHE_SEED_ADMIN_SLUG=admin",
  "ARCHE_WEB_IMAGE=ghcr.io/peaberry-studio/arche/web:latest",
  "ARCHE_WORKSPACE_IMAGE=ghcr.io/peaberry-studio/arche/workspace:latest",
  "OPENCODE_NETWORK=",
]
mounts = []

[[config.domains]]
serviceName = "web"
port = 3000
host = "${main_domain}"

Base64

To import this template in Dokploy: create a Compose service → AdvancedBase64 import and paste the content below:

ewogICJjb21wb3NlIjogInZlcnNpb246IFwiMy44XCJcblxuIyBBcmNoZSDigJQgQUkgd29ya3NwYWNlIHBsYXRmb3JtIHRoYXQgc3Bhd25zIHBlci11c2VyIE9wZW5Db2RlIGNvbnRhaW5lcnNcbiMgdmlhIGEgRG9ja2VyIHNvY2tldCBwcm94eS5cbiNcbiMgUFJFLVJFUVVJU0lURVMgKHJ1biBvbmNlIG9uIHRoZSBWUFMgYmVmb3JlIGRlcGxveWluZyk6XG4jICAgbWtkaXIgLXAgL29wdC9hcmNoZS9rYi1jb250ZW50IC9vcHQvYXJjaGUva2ItY29uZmlnIC9vcHQvYXJjaGUvdXNlcnNcbiNcbiMgT3B0aW9uYWwgKG9ubHkgbmVlZGVkIHRvIHNlZWQgdGhlIEtub3dsZWRnZSBCYXNlKTpcbiMgICBnaXQgaW5pdCAtLWJhcmUgLS1pbml0aWFsLWJyYW5jaD1tYWluIC9vcHQvYXJjaGUva2ItY29udGVudFxuIyAgIGdpdCBpbml0IC0tYmFyZSAtLWluaXRpYWwtYnJhbmNoPW1haW4gL29wdC9hcmNoZS9rYi1jb25maWdcbiNcbiMgUE9TVC1ERVBMT1kgKHNldCBpbiBEb2twbG95IOKGkiBFbnZpcm9ubWVudCwgdGhlbiByZWRlcGxveSk6XG4jICAgMS4gRGVwbG95IHRoaXMgdGVtcGxhdGUgb25jZS4gRG9rcGxveSBhdXRvLWNyZWF0ZXMgYSBuZXR3b3JrIGZvciB0aGVcbiMgICAgICBjb21wb3NlIHN0YWNrLlxuIyAgIDIuIFNTSCBpbnRvIHRoZSBob3N0IGFuZCBmaW5kIHRoZSBuZXR3b3JrIG5hbWU6XG4jICAgICAgICBkb2NrZXIgbmV0d29yayBscyAtLWZvcm1hdCAne3suTmFtZX19JyB8IGdyZXAgYXJjaGVcbiMgICAgICBJdCBsb29rcyBsaWtlIGA8c3RhY2stbmFtZT5fZGVmYXVsdGAgb3Igc2ltaWxhci5cbiMgICAzLiBBZGQgdGhlIGVudiB2YXIgT1BFTkNPREVfTkVUV09SSz08dGhhdC1uZXR3b3JrLW5hbWU+IGFuZCByZWRlcGxveS5cbiMgICAgICBXaXRob3V0IGl0LCBzcGF3bmVkIHVzZXIgd29ya3NwYWNlcyB3aWxsIGZhaWwgdG8gc3RhcnQuXG4jXG4jIElNQUdFIEFSQ0hJVEVDVFVSRTpcbiMgICBEZWZhdWx0IHRhZ3MgdGFyZ2V0IGxpbnV4L2FtZDY0LiBGb3IgQVJNNjQgaG9zdHMgKEFwcGxlIFNpbGljb24sXG4jICAgQW1wZXJlLCBHcmF2aXRvbiksIG92ZXJyaWRlIGJvdGggaW1hZ2VzIHRvIHRoZSBgLWFybTY0YCB2YXJpYW50cyBpblxuIyAgIERva3Bsb3kg4oaSIEVudmlyb25tZW50OlxuIyAgICAgQVJDSEVfV0VCX0lNQUdFPWdoY3IuaW8vcGVhYmVycnktc3R1ZGlvL2FyY2hlL3dlYjpsYXRlc3QtYXJtNjRcbiMgICAgIEFSQ0hFX1dPUktTUEFDRV9JTUFHRT1naGNyLmlvL3BlYWJlcnJ5LXN0dWRpby9hcmNoZS93b3Jrc3BhY2U6bGF0ZXN0LWFybTY0XG5cbnNlcnZpY2VzOlxuICB3ZWI6XG4gICAgaW1hZ2U6ICR7QVJDSEVfV0VCX0lNQUdFOi1naGNyLmlvL3BlYWJlcnJ5LXN0dWRpby9hcmNoZS93ZWI6bGF0ZXN0fVxuICAgIHJlc3RhcnQ6IHVubGVzcy1zdG9wcGVkXG4gICAgZGVwZW5kc19vbjpcbiAgICAgIHBvc3RncmVzOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeVxuICAgICAgZG9ja2VyLXNvY2tldC1wcm94eTpcbiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX3N0YXJ0ZWRcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIEFSQ0hFX0RPTUFJTjogJHtBUkNIRV9ET01BSU59XG4gICAgICBEQVRBQkFTRV9VUkw6IHBvc3RncmVzcWw6Ly9wb3N0Z3Jlczoke1BPU1RHUkVTX1BBU1NXT1JEfUBwb3N0Z3Jlczo1NDMyL2FyY2hlP3NjaGVtYT1wdWJsaWNcblxuICAgICAgQVJDSEVfU0VTU0lPTl9QRVBQRVI6ICR7QVJDSEVfU0VTU0lPTl9QRVBQRVJ9XG4gICAgICBBUkNIRV9FTkNSWVBUSU9OX0tFWTogJHtBUkNIRV9FTkNSWVBUSU9OX0tFWX1cbiAgICAgIEFSQ0hFX0lOVEVSTkFMX1RPS0VOOiAke0FSQ0hFX0lOVEVSTkFMX1RPS0VOfVxuICAgICAgQVJDSEVfR0FURVdBWV9UT0tFTl9TRUNSRVQ6ICR7QVJDSEVfR0FURVdBWV9UT0tFTl9TRUNSRVR9XG4gICAgICBBUkNIRV9DT05ORUNUT1JfT0FVVEhfU1RBVEVfU0VDUkVUOiAke0FSQ0hFX0NPTk5FQ1RPUl9PQVVUSF9TVEFURV9TRUNSRVR9XG5cbiAgICAgIEFSQ0hFX0dBVEVXQVlfVE9LRU5fVFRMX1NFQ09ORFM6IFwiODY0MDBcIlxuICAgICAgQVJDSEVfR0FURVdBWV9CQVNFX1VSTDogaHR0cDovL3dlYjozMDAwXG4gICAgICBBUkNIRV9QVUJMSUNfQkFTRV9VUkw6IGh0dHBzOi8vJHtBUkNIRV9ET01BSU59XG4gICAgICBBUkNIRV9TRVNTSU9OX1RUTF9EQVlTOiBcIjdcIlxuICAgICAgQVJDSEVfQ09PS0lFX1NFQ1VSRTogXCJ0cnVlXCJcblxuICAgICAgQVJDSEVfU0VFRF9BRE1JTl9FTUFJTDogJHtBUkNIRV9TRUVEX0FETUlOX0VNQUlMfVxuICAgICAgQVJDSEVfU0VFRF9BRE1JTl9QQVNTV09SRDogJHtBUkNIRV9TRUVEX0FETUlOX1BBU1NXT1JEfVxuICAgICAgQVJDSEVfU0VFRF9BRE1JTl9TTFVHOiAke0FSQ0hFX1NFRURfQURNSU5fU0xVRzotYWRtaW59XG5cbiAgICAgIENPTlRBSU5FUl9QUk9YWV9IT1NUOiBkb2NrZXItc29ja2V0LXByb3h5XG4gICAgICBDT05UQUlORVJfUFJPWFlfUE9SVDogXCIyMzc1XCJcbiAgICAgIE9QRU5DT0RFX0lNQUdFOiAke0FSQ0hFX1dPUktTUEFDRV9JTUFHRTotZ2hjci5pby9wZWFiZXJyeS1zdHVkaW8vYXJjaGUvd29ya3NwYWNlOmxhdGVzdH1cbiAgICAgIE9QRU5DT0RFX05FVFdPUks6ICR7T1BFTkNPREVfTkVUV09SS31cblxuICAgICAgS0JfQ09OVEVOVF9IT1NUX1BBVEg6IC9vcHQvYXJjaGUva2ItY29udGVudFxuICAgICAgS0JfQ09ORklHX0hPU1RfUEFUSDogL29wdC9hcmNoZS9rYi1jb25maWdcbiAgICAgIEFSQ0hFX1VTRVJTX1BBVEg6IC9vcHQvYXJjaGUvdXNlcnNcbiAgICBleHBvc2U6XG4gICAgICAtIFwiMzAwMFwiXG4gICAgdm9sdW1lczpcbiAgICAgIC0gL29wdC9hcmNoZS9rYi1jb250ZW50Oi9rYi1jb250ZW50XG4gICAgICAtIC9vcHQvYXJjaGUva2ItY29uZmlnOi9rYi1jb25maWdcbiAgICAgIC0gL29wdC9hcmNoZS91c2Vyczovb3B0L2FyY2hlL3VzZXJzXG5cbiAgcG9zdGdyZXM6XG4gICAgaW1hZ2U6IHBvc3RncmVzOjE2XG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIFBPU1RHUkVTX0RCOiBhcmNoZVxuICAgICAgUE9TVEdSRVNfVVNFUjogcG9zdGdyZXNcbiAgICAgIFBPU1RHUkVTX1BBU1NXT1JEOiAke1BPU1RHUkVTX1BBU1NXT1JEfVxuICAgIHZvbHVtZXM6XG4gICAgICAtIHBvc3RncmVzX2RhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhXG4gICAgaGVhbHRoY2hlY2s6XG4gICAgICB0ZXN0OiBbXCJDTUQtU0hFTExcIiwgXCJwZ19pc3JlYWR5IC1VIHBvc3RncmVzXCJdXG4gICAgICBpbnRlcnZhbDogMTBzXG4gICAgICB0aW1lb3V0OiA1c1xuICAgICAgcmV0cmllczogNVxuXG4gIGRvY2tlci1zb2NrZXQtcHJveHk6XG4gICAgaW1hZ2U6IGdoY3IuaW8vdGVjbmF0aXZhL2RvY2tlci1zb2NrZXQtcHJveHk6bWFzdGVyXG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIENPTlRBSU5FUlM6IDFcbiAgICAgIE5FVFdPUktTOiAxXG4gICAgICBJTUFHRVM6IDFcbiAgICAgIElORk86IDFcbiAgICAgIFBPU1Q6IDFcbiAgICAgIFZPTFVNRVM6IDFcbiAgICB2b2x1bWVzOlxuICAgICAgLSAvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jazpyb1xuXG52b2x1bWVzOlxuICBwb3N0Z3Jlc19kYXRhOlxuIiwKICAiY29uZmlnIjogIlt2YXJpYWJsZXNdXG5tYWluX2RvbWFpbiA9IFwiJHtkb21haW59XCJcbnBvc3RncmVzX3Bhc3N3b3JkID0gXCIke3Bhc3N3b3JkOjMyfVwiXG5zZXNzaW9uX3BlcHBlciA9IFwiJHtiYXNlNjQ6MzJ9XCJcbmVuY3J5cHRpb25fa2V5ID0gXCIke2Jhc2U2NDozMn1cIlxuaW50ZXJuYWxfdG9rZW4gPSBcIiR7YmFzZTY0OjMyfVwiXG5nYXRld2F5X3Rva2VuX3NlY3JldCA9IFwiJHtiYXNlNjQ6MzJ9XCJcbmNvbm5lY3Rvcl9vYXV0aF9zdGF0ZV9zZWNyZXQgPSBcIiR7YmFzZTY0OjMyfVwiXG5zZWVkX2FkbWluX2VtYWlsID0gXCIke2VtYWlsfVwiXG5zZWVkX2FkbWluX3Bhc3N3b3JkID0gXCIke3Bhc3N3b3JkOjE2fVwiXG5cbltjb25maWddXG5lbnYgPSBbXG4gIFwiQVJDSEVfRE9NQUlOPSR7bWFpbl9kb21haW59XCIsXG4gIFwiUE9TVEdSRVNfUEFTU1dPUkQ9JHtwb3N0Z3Jlc19wYXNzd29yZH1cIixcbiAgXCJBUkNIRV9TRVNTSU9OX1BFUFBFUj0ke3Nlc3Npb25fcGVwcGVyfVwiLFxuICBcIkFSQ0hFX0VOQ1JZUFRJT05fS0VZPSR7ZW5jcnlwdGlvbl9rZXl9XCIsXG4gIFwiQVJDSEVfSU5URVJOQUxfVE9LRU49JHtpbnRlcm5hbF90b2tlbn1cIixcbiAgXCJBUkNIRV9HQVRFV0FZX1RPS0VOX1NFQ1JFVD0ke2dhdGV3YXlfdG9rZW5fc2VjcmV0fVwiLFxuICBcIkFSQ0hFX0NPTk5FQ1RPUl9PQVVUSF9TVEFURV9TRUNSRVQ9JHtjb25uZWN0b3Jfb2F1dGhfc3RhdGVfc2VjcmV0fVwiLFxuICBcIkFSQ0hFX1NFRURfQURNSU5fRU1BSUw9JHtzZWVkX2FkbWluX2VtYWlsfVwiLFxuICBcIkFSQ0hFX1NFRURfQURNSU5fUEFTU1dPUkQ9JHtzZWVkX2FkbWluX3Bhc3N3b3JkfVwiLFxuICBcIkFSQ0hFX1NFRURfQURNSU5fU0xVRz1hZG1pblwiLFxuICBcIkFSQ0hFX1dFQl9JTUFHRT1naGNyLmlvL3BlYWJlcnJ5LXN0dWRpby9hcmNoZS93ZWI6bGF0ZXN0XCIsXG4gIFwiQVJDSEVfV09SS1NQQUNFX0lNQUdFPWdoY3IuaW8vcGVhYmVycnktc3R1ZGlvL2FyY2hlL3dvcmtzcGFjZTpsYXRlc3RcIixcbiAgXCJPUEVOQ09ERV9ORVRXT1JLPVwiLFxuXVxubW91bnRzID0gW11cblxuW1tjb25maWcuZG9tYWluc11dXG5zZXJ2aWNlTmFtZSA9IFwid2ViXCJcbnBvcnQgPSAzMDAwXG5ob3N0ID0gXCIke21haW5fZG9tYWlufVwiXG4iCn0=

Tags

ai, coding, workspace, self-hosted, llm


Version: latest

On this page