# Everything on one small server: the account server (relay), HTTPS (Caddy), and AnyBot itself. # Easiest: ./setup.sh (asks for the domain, account and keys, writes .env and Caddyfile, starts # everything and checks it). By hand: # 1. Point your domain at the server; copy ../../relay/Caddyfile here and put the domain in it. # 2. Put your account name and password in .env (see .env.example). # 3. docker compose up -d # 4. On the phone open https://your-domain, create the account (first time), and use it. # AI keys: set them in .env, or set ANYBOT_RESTORE_FROM_ACCOUNT=1 to start from the newest backup # your Mac made (bots, chats, routines and the keys you set there). # # 大腦: this AnyBot is the brain of the account. It keeps the bots, chats, memory and routines, # and works even while your computers sleep. On each of your computers: 設定 › 手機與帳號 › # 大腦 › 「改用它當大腦」. Those computers then show these bots, and the bots can use them as hands # (screen, files, browser), asking you first as usual. A Linux computer without a screen can be # hands too: run `anybot setup` there and pick this brain. services: relay: build: context: ../.. dockerfile: relay/Dockerfile args: { JOBS: "${ANYBOT_BUILD_JOBS:-}" } restart: unless-stopped environment: # Your public address (for the links of sites the bots publish), e.g. https://anybot.example.com ANYBOT_RELAY_PUBLIC_URL: "${ANYBOT_RELAY_PUBLIC_URL:-}" ANYBOT_RELAY_INVITE: "${ANYBOT_RELAY_INVITE:-}" # Caddy (or `tailscale serve`) is in front: the caller's address is the one it reports. # Without this every login attempt counts as coming from the proxy, and a few wrong # passwords from anyone lock that account for everyone. RELAY_TRUST_PROXY: "1" volumes: - relay-data:/data caddy: image: caddy:2 restart: unless-stopped ports: ["80:80", "443:443"] volumes: # Written by setup.sh (your domain); ../../relay/Caddyfile is the template. - ./Caddyfile:/etc/caddy/Caddyfile:ro - caddy-data:/data depends_on: [relay] anybot: build: context: ../.. dockerfile: deploy/server/Dockerfile args: { JOBS: "${ANYBOT_BUILD_JOBS:-}" } restart: unless-stopped depends_on: [relay] # A second wall for the bots' computer (optional, Linux): install gVisor on this host # (see gvisor.dev/docs "Installation" for the apt repository + `apt-get install runsc`, # then register it in /etc/docker/daemon.json: {"runtimes": {"runsc": {"path": "runsc"}}} # and `systemctl restart docker`). In AnyBot: 設定 › 電腦 › 在哪裡執行 › 容器隔離 → # 「強隔離(gVisor)」, then rebuild the computer (更新). The box gets a virtualized # kernel and Chromium's own sandbox comes back on. On a host without runsc the box won't # start — switch 容器隔離 back to 標準. environment: ANYBOT_ACCOUNT: "http://relay:8080|${ANYBOT_USER}" ANYBOT_ACCOUNT_PASSWORD: "${ANYBOT_PASSWORD}" ANYBOT_HOST_NAME: "${ANYBOT_HOST_NAME:-雲端 AnyBot}" # First start on a new server: make the account (the first one needs no invite). ANYBOT_ACCOUNT_CREATE: "1" ANYBOT_RELAY_INVITE: "${ANYBOT_RELAY_INVITE:-}" XAI_API_KEY: "${XAI_API_KEY:-}" ANTHROPIC_API_KEY: "${ANTHROPIC_API_KEY:-}" OPENAI_API_KEY: "${OPENAI_API_KEY:-}" GEMINI_API_KEY: "${GEMINI_API_KEY:-}" ANYBOT_RESTORE_FROM_ACCOUNT: "${ANYBOT_RESTORE_FROM_ACCOUNT:-}" # The bots' computer goes by its own name: a desktop AnyBot on this same machine keeps # "anybot-box" for itself (and used to pause the brain's one as idle). ANYBOT_BOX_NAME: "anybot-brain-box" # The Docker socket is not mounted here any more (a mounted socket is full control of this # host). The bots' computer is driven through the filtered proxy below, which only answers # the calls cloudbox.rs makes: containers (run/start/stop/rm/inspect/ps), exec, volumes, # images and the box image build. DOCKER_HOST is the plain `docker` CLI default, which is # what src/cloudbox.rs uses when its own docker_host setting is empty. DOCKER_HOST: "tcp://docker-socket-proxy:2375" volumes: - anybot-data:/data docker-socket-proxy: # https://github.com/Tecnativa/docker-socket-proxy: a small nginx in front of the Docker # socket with an endpoint allowlist. Keep this list minimal: adding an API here widens what # a compromised brain can do on this host (no AUTH, no SECRETS, no SWARM, no plugins). image: tecnativa/docker-socket-proxy:0.3.0 restart: unless-stopped environment: CONTAINERS: "1" # run, start, stop, rm, inspect, ps (the box's lifecycle) EXEC: "1" # docker exec: every screen step, box_exec, snapshots IMAGES: "1" # inspect/create the box image (build uploads it) BUILD: "1" # 更新/重建 builds the box image VOLUMES: "1" # anybot-box-home: inspect, create, rm (Reset/Restore) NETWORKS: "1" # inspect/attach (docker run needs the bridge network) POST: "1" GET: "1" # On a rootless-Docker host this has to be DOCKER_SOCKET=/run/user//docker.sock in .env: # setup.sh finds it and writes it (also into a kept .env). The rootful default is # /var/run/docker.sock; on a rootless host that is another daemon and the proxy answers 503. volumes: - ${DOCKER_SOCKET:-/var/run/docker.sock}:/var/run/docker.sock:ro volumes: relay-data: caddy-data: anybot-data: