使用 Docker 部署

July 26, 2026 · View on GitHub

完成本页后,Bot、PostgreSQL 和网页控制台会由 Docker Compose 启动。适合希望用官方镜像部署、无需修改源码的使用者。

::: tip 不要 git clone 整仓。镜像内已有代码;本机只需 compose 文件与配置。

依赖:Docker。先确认 Compose 可用:

docker compose version

:::

看到版本信息后,可以继续部署。

1. 创建部署目录并下载所需文件

创建一个空的部署目录,并下载三个所需文件:

mkdir -p ~/pallas-deploy/pallas-bot/config \
         ~/pallas-deploy/pallas-bot/data \
         ~/pallas-deploy/pallas-bot/resource/voices
cd ~/pallas-deploy

BASE=https://raw.githubusercontent.com/PallasBot/Pallas-Bot/main
curl -fsSL -o docker-compose.yml "$BASE/docker-compose.yml"
curl -fsSL -o pallas-bot/config/pallas.toml "$BASE/config/pallas.example.toml"
curl -fsSL -o pallas-bot/config/compose.env "$BASE/config/compose.env.example"

::: tip Windows 可用 Docker Desktop 自带的终端。没有 curl 时,用浏览器打开上面三个 URL,把内容存到对应路径即可。

注意:pallas-bot/config/pallas.toml 必须是文件,不能是目录。 :::

目录中已有 docker-compose.ymlpallas-bot/config/pallas.tomlpallas-bot/config/compose.env 后,文件已准备完成。

2. 让 Bot 与数据库使用相同配置

编辑 pallas-bot/config/pallas.toml

[bootstrap]
host = "0.0.0.0"
port = 8088
superusers = ["你的QQ号"]
db_backend = "postgresql"

[bootstrap.postgres]
host = "postgres"
port = 5432
user = "pallas"
password = "pallas"
db = "PallasBot"

compose.env 里的 PG_USER / PG_PASSWORD / PG_DB 与上面保持一致(默认已对齐)。

::: warning host 填 Compose 服务名 postgres,不要填 127.0.0.1(容器内指不到库)。 :::

保存后,Bot 和 PostgreSQL 会使用同一组数据库连接信息。

3. 启动服务并确认可访问

docker compose --env-file ./pallas-bot/config/compose.env up -d

首次启动会拉取镜像并初始化数据库,控制台初始密码会出现在 Bot 日志中。接着检查状态:

docker compose --env-file ./pallas-bot/config/compose.env ps
curl -s http://127.0.0.1:8088/pallas/api/health
docker compose --env-file ./pallas-bot/config/compose.env logs pallasbot | head -80

docker compose ps 显示服务运行,健康检查可访问且日志没有启动错误时,说明服务已启动。浏览器打开 http://127.0.0.1:8088/pallas/,使用日志里的控制台密码登录。

接下来:登录控制台并连接 QQ

先在 网页控制台 登录并完成首次设置。然后打开 http://<主机>:8088/pallas/protocol,用同一密码登录 → 新建 NapCat → 扫码。群里发 牛牛帮助,应能出图。

完整说明见 连接 QQ

日常命令

docker compose --env-file ./pallas-bot/config/compose.env logs -f pallasbot
docker compose --env-file ./pallas-bot/config/compose.env restart pallasbot
docker compose --env-file ./pallas-bot/config/compose.env pull
docker compose --env-file ./pallas-bot/config/compose.env up -d
docker compose --env-file ./pallas-bot/config/compose.env down

::: details 全栈(Bot + PG + Redis + Ollama + AI) 仓库根目录只提供默认 docker-compose.yml(Bot + PostgreSQL)。需要 AI Runtime / Ollama 时,将下面 YAML 另存为部署目录中的 docker-compose.full.yml,再启动。

准备目录与 pallas.toml / compose.env 与上文相同;另建 pallas-bot-ai/logs[bootstrap.postgres].hostpostgres

# Bot + PostgreSQL + Redis + Ollama + AI Runtime
# 启动: docker compose -f docker-compose.full.yml --env-file ./pallas-bot/config/compose.env up -d
# 可选预拉模型: 追加 --profile pull-models
# GPU: 再叠加下文 docker-compose.full.gpu.yml

name: pallas-full

services:
  pallasbot:
    container_name: pallasbot
    image: pallasbot/pallas-bot:latest
    restart: always
    ports:
      - "${BOT_PORT:-8088}:${BOT_LISTEN_PORT:-8088}"
    environment:
      TZ: Asia/Shanghai
      ENVIRONMENT: prod
      APP_MODULE: bot:app
      MAX_WORKERS: 1
      PORT: ${BOT_LISTEN_PORT:-8088}
      DB_BACKEND: postgresql
      PG_HOST: postgres
      PG_PORT: "5432"
      PG_USER: ${PG_USER:-pallas}
      PG_PASSWORD: ${PG_PASSWORD:-pallas}
      PG_DB: ${PG_DB:-PallasBot}
      AI_SERVER_HOST: pallasbot-ai
      AI_SERVER_PORT: "9099"
      LLM_CHAT_ENABLED: "true"
    networks:
      - pallas-full
    volumes:
      - ./pallas-bot/resource/voices:/app/resource/voices
      - ./pallas-bot/config/pallas.toml:/app/config/pallas.toml
      - ./pallas-bot/data:/app/data
      - ./pallas-bot/local/plugins:/app/local/plugins
      - ./pallas-bot-ai/logs:/ai-logs:ro
    depends_on:
      postgres:
        condition: service_healthy
      pallasbot-ai:
        condition: service_healthy
      redis:
        condition: service_healthy

  postgres:
    container_name: pallasbot_postgres
    image: postgres:16-alpine
    restart: always
    command:
      - postgres
      - -c
      - shared_preload_libraries=pg_stat_statements
      - -c
      - track_io_timing=on
      - -c
      - idle_in_transaction_session_timeout=15s
    environment:
      TZ: Asia/Shanghai
      POSTGRES_USER: ${PG_USER:-pallas}
      POSTGRES_PASSWORD: ${PG_PASSWORD:-pallas}
      POSTGRES_DB: ${PG_DB:-PallasBot}
    networks:
      - pallas-full
    volumes:
      - ./postgres/data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 15s

  redis:
    image: redis:7-alpine
    container_name: pallas-full-redis
    command: redis-server --appendonly yes
    networks:
      - pallas-full
    volumes:
      - redis_data:/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 5s

  ollama:
    image: ollama/ollama:latest
    container_name: pallas-full-ollama
    networks:
      - pallas-full
    volumes:
      - ollama_data:/root/.ollama
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "ollama list || exit 1"]
      interval: 15s
      timeout: 10s
      retries: 10
      start_period: 30s

  ollama-init:
    profiles: ["pull-models"]
    image: ollama/ollama:latest
    container_name: pallas-full-ollama-init
    networks:
      - pallas-full
    volumes:
      - ollama_data:/root/.ollama
    environment:
      OLLAMA_MODEL: ${LLM_MODEL:-qwen2.5:7b}
      OLLAMA_CATEGORIZER_MODEL: ${LLM_CATEGORIZER_MODEL:-qwen2.5:0.5b}
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        until wget -q -O- http://ollama:11434/api/tags >/dev/null 2>&1; do sleep 2; done
        ollama pull "$${OLLAMA_MODEL:-qwen2.5:7b}"
        ollama pull "$${OLLAMA_CATEGORIZER_MODEL:-qwen2.5:0.5b}"
    depends_on:
      ollama:
        condition: service_healthy
    restart: "no"

  pallasbot-ai:
    image: ${PALLAS_AI_IMAGE:-pallasbot/pallas-bot-ai:slim}
    container_name: pallasbot-ai
    ports:
      - "${AI_SERVER_PORT:-9099}:9099"
    environment:
      TZ: Asia/Shanghai
      REDIS_URL: redis://redis:6379/0
      LLM_SESSION_BACKEND: redis
      CALLBACK_HOST: pallasbot
      CALLBACK_PORT: ${BOT_LISTEN_PORT:-8088}
      LLM_CHAT_ENABLED: "true"
      LLM_PROVIDER_MODE: ${LLM_PROVIDER_MODE:-local_only}
      LLM_BACKEND_URL: http://ollama:11434
      LLM_MODEL: ${LLM_MODEL:-qwen2.5:7b}
      LLM_CATEGORIZER_MODEL: ${LLM_CATEGORIZER_MODEL:-qwen2.5:0.5b}
      LLM_AUTO_START: "false"
      CELERY_TASK_PACKAGES: llm
      AI_ENABLE_MEDIA_WORKER: "0"
      PALLAS_AI_API_TOKEN: ${PALLAS_AI_API_TOKEN:-}
    networks:
      - pallas-full
    volumes:
      - ./pallas-bot-ai/logs:/server/logs
    depends_on:
      redis:
        condition: service_healthy
      ollama:
        condition: service_healthy
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9099/health"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 120s

networks:
  pallas-full:

volumes:
  redis_data:
  ollama_data:
docker compose -f docker-compose.full.yml --env-file ./pallas-bot/config/compose.env up -d
# 可选预拉 Ollama 模型: 追加 --profile pull-models

默认 AI 镜像为 pallasbot/pallas-bot-ai:slim,仅供媒体任务与遗留 RWKV 使用,不预拉模型。Bot 容器通过 AI_SERVER_HOST=pallasbot-ai 连接已启用的 AI 服务。LLM 聊天默认走 Bot 内核 Provider,不必依赖 9099。始终验收 8088;启用 AI Runtime 时再验收 9099

BOT_PORT = 宿主机访问端口;BOT_LISTEN_PORT = 容器内监听(默认皆 8088)。AI 回调走 BOT_LISTEN_PORT,只改宿主机端口时勿动它。

有 NVIDIA GPU 且需唱歌/TTS 时,在 compose.envPALLAS_AI_IMAGE=pallasbot/pallas-bot-ai:latest,并将下面内容另存为 docker-compose.full.gpu.yml 后叠加:

# GPU 覆盖层(需 NVIDIA container toolkit)
# docker compose -f docker-compose.full.yml -f docker-compose.full.gpu.yml \
#   --env-file ./pallas-bot/config/compose.env up -d

services:
  ollama:
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    healthcheck:
      test: ["CMD-SHELL", "ollama list >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1"]
      interval: 5m
      timeout: 15s
      retries: 2
      start_period: 60s

:::

::: details MongoDB(3.x 升级沿用) pallas.tomldb_backend = "mongodb" 并填写 [bootstrap.mongo],然后:

docker compose --env-file ./pallas-bot/config/compose.env --profile mongo up -d

根目录 compose 默认只起 PostgreSQL;Mongo 需显式加 --profile mongo。 :::

::: details 备份与防火墙

  • 备份:./pallas-bot/data/pallas.toml./postgres/data(或 ./mongo/data
  • 防火墙:仅对可信 IP 开放 8088;公网请加 HTTPS :::

::: details 自建镜像与 extras 官方镜像偏单进程用途。自行 docker build 时可用 --build-arg PALLAS_UV_EXTRAS=perf(PG 驱动已在主依赖)。国内拉基础镜像失败可用 BASE_IMAGE 换镜像站前缀。 :::

::: details 多进程分片 官方根目录 Compose 面向单进程。源码部署优先 ./scripts/run_sharded_bot.sh(见 分片部署)。若坚持用 Docker,可将下面示例另存为 docker-compose.shard.yml(hub + 2 worker;按需复制 worker 段并改端口 / PALLAS_SHARD_ID)。协议端反向 WS 须连 worker 端口(8090+),不是 hub 8088。pallas.toml[env] 可设 REDIS_URL=redis://redis:6379/0,或依赖下方环境变量。

name: pallas-bot-shard

x-pallas-common: &pallas-common
  image: pallasbot/pallas-bot:latest
  restart: always
  environment: &pallas-env
    TZ: Asia/Shanghai
    ENVIRONMENT: prod
    MAX_WORKERS: 1
    PALLAS_SHARD_ENABLED: "true"
    PG_HOST: postgres
    PG_PORT: "5432"
    REDIS_URL: redis://redis:6379/0
  volumes: &pallas-volumes
    - ./pallas-bot/resource/voices:/app/resource/voices
    - ./pallas-bot/config/pallas.toml:/app/config/pallas.toml
    - ./pallas-bot/data:/app/data
    - ./pallas-bot/local/plugins:/app/local/plugins
  networks:
    - pallasbot
  depends_on:
    postgres:
      condition: service_healthy
    redis:
      condition: service_healthy

services:
  pallas-hub:
    <<: *pallas-common
    container_name: pallas-hub
    ports:
      - "8088:8088"
    environment:
      <<: *pallas-env
      APP_MODULE: bot_hub:app
      PALLAS_BOT_ROLE: hub
      PORT: "8088"
      PALLAS_SHARD_WORKER_BASE_PORT: "8090"
      PALLAS_SHARD_BOTS_PER: "5"

  pallas-worker-0:
    <<: *pallas-common
    container_name: pallas-worker-0
    ports:
      - "8090:8090"
    environment:
      <<: *pallas-env
      APP_MODULE: bot_worker:app
      PALLAS_BOT_ROLE: worker
      PALLAS_SHARD_ID: "0"
      PORT: "8090"

  pallas-worker-1:
    <<: *pallas-common
    container_name: pallas-worker-1
    ports:
      - "8091:8091"
    environment:
      <<: *pallas-env
      APP_MODULE: bot_worker:app
      PALLAS_BOT_ROLE: worker
      PALLAS_SHARD_ID: "1"
      PORT: "8091"

  postgres:
    container_name: pallasbot_postgres
    image: postgres:16-alpine
    restart: always
    environment:
      TZ: Asia/Shanghai
      POSTGRES_USER: ${PG_USER:-pallas}
      POSTGRES_PASSWORD: ${PG_PASSWORD:-pallas}
      POSTGRES_DB: ${PG_DB:-PallasBot}
    networks:
      - pallasbot
    volumes:
      - ./postgres/data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 15s

  redis:
    container_name: pallasbot_redis
    image: redis:7-alpine
    restart: always
    command: ["redis-server", "--appendonly", "yes"]
    networks:
      - pallasbot
    volumes:
      - ./redis/data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5
      start_period: 5s

networks:
  pallasbot:
docker compose -f docker-compose.shard.yml --env-file ./pallas-bot/config/compose.env up -d

:::

排障

::: details pallas.toml ... not a directory 宿主机路径被建成了目录。删掉后重新下载为文件up。 :::

::: details database "PallasBot" does not exist 旧数据卷库名与当前 PG_DB 不一致。对齐库名,或清空 ./postgres/data 后重建(会丢数据)。见 FAQ。 :::

::: details help 样式路径不存在 勿把空 resource 整目录挂到 /app/resource;只挂 voices(与官方 compose 一致)。 :::

::: details project name must not be empty 仓库 compose 已设 name: pallas-bot。仍报错时用 docker compose -p pallas-bot ...,或避免特殊字符目录名。 :::