Bar Assistant Docker Compose 部署指南

Ubuntu 24.04 上用 Docker Compose 部署 Bar Assistant v6.10.1 四服务栈(API+Salt Rim+Redis+Meilisearch):端口与网络规划、compose 全文、首建与初始化 663 配方、重启持久化实测、升级回滚、等价 docker run 与五条排障实录。

Bar AssistantBar AssistantDocker Compose自托管Redis 数据库MeiliSearch2026/11/01

Bar Assistant Docker Compose 部署指南

目标:在一台 Ubuntu 24.04 LTS 服务器上,用 Docker Compose 从零部署 Bar Assistant v6.10.1 完整四服务栈(API + Salt Rim 前端 + Redis + Meilisearch),完成首次初始化(注册、建吧、导入 500+ 官方配方数据包),并沉淀持久化验证、升级流程与真实踩坑记录。本文全部命令与回显均为 2026-11-01 实机执行原文。

一、环境信息

项目值
操作系统Ubuntu 24.04 LTS(x86_64)
Docker29.9.2, build a82e528(docker --version 实测)
ComposeDocker Compose version v5.6.1(docker compose version 实测)
API 服务ghcr.io/karlomikus/barassistant:6.10.1(2026-10-29 发布的最新稳定版,版本溯源见 《Bar Assistant 介绍与选型指南》)
前端服务ghcr.io/karlomikus/salt-rim:5.9.0
缓存redis:7-alpine
搜索getmeili/meilisearch:v1.50
宿主机端口Web 8134、API 8135、Meilisearch 8132(Redis 不对外)
私有网络bar-assistant-v6.10.1-net,子网 10.89.60.0/24
持久卷bar_data(API 存储)、meilisearch_data(索引)

二、架构与端口规划

Bar Assistant 是 API-first 产品:barassistant 镜像只提供 REST API(内置 nginx + php-fpm,监听 8080),官方 Web 界面是独立的 salt-rim 镜像(构建期把 API 地址烧进静态产物)。两者之外还需要 Redis(缓存/会话/队列/指标)与 Meilisearch(全文搜索)。四者组在一个自定义 bridge 网络上:

浏览器 ── :8134 ──> salt-rim(静态前端,JS 直连 ↓)
浏览器/curl ── :8135 ──> bar-assistant API(:8080)
                              │ 同网络服务名互访
                              ├── redis:6379(CACHE/SESSION)
                              └── meilisearch:7700(SCOUT)
运维/脚本 ── :8132 ──> meilisearch:7700(可选对外)

端口从 8128–8152 规划段中取空闲者(ss -ltn 实查本例取 8132/8134/8135);网络固定 10.89.60.0/24 避免与其他栈冲突。

三、镜像与版本锁定(关键前置)

官方 README 明示:镜像没有 latest 标签,必须显式指定版本 tag(2026-11-01 实查):

  • barassistant/server:v6.10.1——精确版本;v6.10——最近补丁;v6——最近次版本;dev——开发版(官方不建议生产)
  • GitHub Container Registry 等价路径:ghcr.io/karlomikus/barassistant,本例用 ghcr.io/karlomikus/barassistant:6.10.1
  • 前端:ghcr.io/karlomikus/salt-rim:5.9.0

拉取验证(实测):

docker pull ghcr.io/karlomikus/barassistant:6.10.1
docker pull ghcr.io/karlomikus/salt-rim:5.9.0
docker pull getmeili/meilisearch:v1.50
docker pull redis:7-alpine

四、准备目录与 .env

mkdir -p /opt/bar-assistant && cd /opt/bar-assistant

.env(compose 变量注入,实测文件全文):

# Bar Assistant v6.10.1 部署实验 .env
MEILI_MASTER_KEY=masterKey-make-it-long-for-security
MEILISEARCH_URL=http://localhost:8132
API_URL=http://localhost:8135

三处注意:

  1. MEILI_MASTER_KEY 生产环境务必换成长随机串(Meilisearch 要求 ≥16 字节)。
  2. API_URL 是浏览器可达的 API 地址(前端 JS 与 Salt Rim 构建参数都引用它),不是容器内网地址。
  3. MEILISEARCH_URL 给前端做即时搜索用,同样必须是浏览器可达地址。

五、docker-compose.yml 全文

实测在跑的完整文件(name: 显式项目名,防止多栈目录同名互删):

name: bar-assistant-v6.10.1-stack

volumes:
  bar_data:
  meilisearch_data:

services:
  meilisearch:
    image: getmeili/meilisearch:v1.50
    container_name: bar-assistant-v6.10.1-search
    environment:
      - MEILI_NO_ANALYTICS=true
      - MEILI_MASTER_KEY=$MEILI_MASTER_KEY
      - MEILI_ENV=production
    restart: unless-stopped
    volumes:
      - meilisearch_data:/meili_data
    ports:
      - "8132:7700"
    networks:
      - bar-net

  redis:
    image: redis:7-alpine
    container_name: bar-assistant-v6.10.1-cache
    environment:
      - ALLOW_EMPTY_PASSWORD=yes
    restart: unless-stopped
    networks:
      - bar-net

  bar-assistant:
    image: ghcr.io/karlomikus/barassistant:6.10.1
    container_name: bar-assistant-v6.10.1-api
    depends_on:
      - meilisearch
      - redis
    environment:
      - APP_URL=$API_URL
      - MEILISEARCH_KEY=$MEILI_MASTER_KEY
      - MEILISEARCH_HOST=http://meilisearch:7700
      - REDIS_HOST=redis
      - CACHE_DRIVER=redis
      - SESSION_DRIVER=redis
      - ALLOW_REGISTRATION=true
      - METRICS_ENABLED=true
      - METRICS_ALLOWED_IPS=10.89.60.1
    restart: unless-stopped
    ports:
      - "8135:8080"
    volumes:
      - bar_data:/var/www/cocktails/storage/bar-assistant
    networks:
      - bar-net

  salt-rim:
    image: ghcr.io/karlomikus/salt-rim:5.9.0
    container_name: bar-assistant-v6.10.1-web
    depends_on:
      - bar-assistant
    environment:
      - API_URL=$API_URL
      - MEILISEARCH_URL=$MEILISEARCH_URL
    restart: unless-stopped
    ports:
      - "8134:8080"
    networks:
      - bar-net

networks:
  bar-net:
    name: bar-assistant-v6.10.1-net
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.60.0/24

要点:

  • 数据只落一个卷:API 的 SQLite 库、图片、导出包全部在 /var/www/cocktails/storage/bar-assistant,挂到 bar_data 即完成核心持久化;Meilisearch 索引可重建(有 bar:refresh-search 命令),但仍建议挂卷省启动时间。
  • MEILISEARCH_HOST 用服务名(容器内网),MEILI_MASTER_KEY 与 MEILISEARCH_KEY 必须一致。
  • API 镜像自带健康检查(php-fpm-healthcheck || exit 1,间隔 3s、启动宽限 40s、重试 3 次,docker inspect 实查)。

六、启动栈(实测回显)

docker compose up -d
 Network bar-assistant-v6.10.1-net Creating
 Network bar-assistant-v6.10.1-net Created
 Container bar-assistant-v6.10.1-search Creating
 Container bar-assistant-v6.10.1-cache Creating
 Container bar-assistant-v6.10.1-search Created
 Container bar-assistant-v6.10.1-cache Created
 Container bar-assistant-v6.10.1-api Creating
 Container bar-assistant-v6.10.1-api Created
 Container bar-assistant-v6.10.1-web Creating
 Container bar-assistant-v6.10.1-web Created
 Container bar-assistant-v6.10.1-cache Starting
 Container bar-assistant-v6.10.1-search Starting
 Container bar-assistant-v6.10.1-cache Started
 Container bar-assistant-v6.10.1-search Started
 Container bar-assistant-v6.10.1-api Starting
 Container bar-assistant-v6.10.1-api Started
 Container bar-assistant-v6.10.1-web Starting
 Container bar-assistant-v6.10.1-web Started

约 30 秒后状态(实测):

docker compose ps
NAME                           IMAGE                                    COMMAND                  SERVICE         CREATED          STATUS                    PORTS
bar-assistant-v6.10.1-api      ghcr.io/karlomikus/barassistant:6.10.1   "docker-php-serversi…"   bar-assistant   24 minutes ago   Up 14 minutes (healthy)   8443/tcp, 9000/tcp, 0.0.0.0:8135->8080/tcp, [::]:8135->8080/tcp
bar-assistant-v6.10.1-cache    redis:7-alpine                           "docker-entrypoint.s…"   redis           42 minutes ago   Up 42 minutes             6379/tcp
bar-assistant-v6.10.1-search   getmeili/meilisearch:v1.50               "tini -- /bin/sh -c …"   meilisearch     42 minutes ago   Up 42 minutes             0.0.0.0:8132->7700/tcp, [::]:8132->7700/tcp
bar-assistant-v6.10.1-web      ghcr.io/karlomikus/salt-rim:5.9.0        "/docker-entrypoint.…"   salt-rim        42 minutes ago   Up 42 minutes             0.0.0.0:8134->8080/tcp, [::]:8134->8080/tcp

API 服务启动日志(实测,docker compose logs bar-assistant):

bar-assistant-v6.10.1-api  |  🍸 Check our managed service at https://barassistant.app/ 🍸
bar-assistant-v6.10.1-api  |  [BAR-ASSISTANT] Bar Assistant API ready [listening on port: 8080]
bar-assistant-v6.10.1-api  | ✅ NGINX + PHP-FPM is running correctly.

免认证版本端点复核(实测):

curl -s http://127.0.0.1:8135/api/server/version
{"data":{"version":"v6.10.1","latest_version":"v6.10.1","is_latest":true,"type":"production","search_host":"http:\/\/meilisearch:7700","search_version":"1.50.0","is_password_login_enabled":true,"is_ai_enabled":false,"is_ai_image_enabled":false}}

前端与搜索健康(实测):

curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8134/   # → 200
curl -s http://127.0.0.1:8132/health                               # → {"status":"available"}

七、首次初始化(注册 → 建吧 → 导入数据包)

Salt Rim 打开 http://<服务器>:8134 注册即可;这里用 API 全流程(也是无 GUI 服务器的标准做法)。示例账号 admin / q1w2e3r4。

1. 注册用户(实测 HTTP 201,空响应体):

curl -s -o /dev/null -w "HTTP:%{http_code}\n" -X POST http://127.0.0.1:8135/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"name":"admin","email":"admin@example.com","password":"q1w2e3r4","password_confirmation":"q1w2e3r4"}'

2. 登录取 token(实测;Sanctum 令牌格式 ID|随机串,后续所有请求带 Authorization: Bearer <token>):

curl -s -X POST http://127.0.0.1:8135/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@example.com","password":"q1w2e3r4"}'
{"data":{"token":"1|XzZfLUwJppfgBB8BTniRjKpjuqfOoLAELCsB1ynjd6dfdca4"}}

3. 创建吧台(实测 HTTP 201;注意后续所有吧相关端点必须带请求头 Bar-Assistant-Bar-Id: 1):

curl -s -o /dev/null -w "HTTP:%{http_code}\n" -X POST http://127.0.0.1:8135/api/bars \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"name":"Home Bar"}'

4. 同步官方配方数据包(实测 HTTP 204,约 0.5 秒返回,后台异步导入 663 条鸡尾酒并自动建 Meilisearch 索引):

curl -s -o /dev/null -w "HTTP:%{http_code}\n" -X POST http://127.0.0.1:8135/api/bars/1/sync-datapack \
  -H "Authorization: Bearer $TOKEN" -H "Bar-Assistant-Bar-Id: 1"

5. 验证数据量(实测 meta.total 663、分页 27 页,首条 1934 Cosmo):

curl -s "http://127.0.0.1:8135/api/cocktails" \
  -H "Authorization: Bearer $TOKEN" -H "Bar-Assistant-Bar-Id: 1"

回显 meta 节选(照抄):

'meta': {'current_page': 1, 'from': 1, 'last_page': 27, ..., 'per_page': 25, 'to': 25, 'total': 663, ...}
first: {'id': 510, 'name': '1934 Cosmo', 'slug': '1934-cosmo-1', 'abv': 21.33}

原料库同步到位(实测 GET /api/ingredients → total: 296)。

八、持久化验证(重启不丢数据)

docker compose restart bar-assistant
 Container bar-assistant-v6.10.1-api Restarting
 Container bar-assistant-v6.10.1-api Started

重启后配方总量不减(实测 "total":665——含初始化后新增的 2 条测试配方,SQLite 全在 bar_data 卷内):

curl -s "http://127.0.0.1:8135/api/cocktails?per_page=1" -H "Authorization: Bearer $TOKEN" -H "Bar-Assistant-Bar-Id: 1" | grep -o '"total":[0-9]*'
"total":665

卷归属(实测 docker volume ls | grep bar):

local     bar-assistant-v6101-stack_bar_data
local     bar-assistant-v6101-stack_meilisearch_data

九、升级与回滚

升级(示例 v6.10.1 → 未来 v6.10.x):

sed -i 's/barassistant:6.10.1/barassistant:6.10/' docker-compose.yml   # 或直接改精确 tag
docker compose pull bar-assistant
docker compose up -d bar-assistant

镜像无 latest 的设计让「回滚」等于「改回旧 tag 再 up」,SQLite 结构由 Laravel migration 在启动时自动升级;跨大版本(v5→v6)官方文档要求先备份——升级前跑一次全量备份(命令见《Bar Assistant 6.10.1 常用 CLI/API 命令详解》的 bar:full-backup 节)。

十、等价 docker run(单服务参考)

Compose 的 bar-assistant 服务展开等价于:

docker run -d --name bar-assistant-v6.10.1-api \
  -p 8135:8080 \
  -e APP_URL=http://localhost:8135 \
  -e MEILISEARCH_KEY=masterKey-make-it-long-for-security \
  -e MEILISEARCH_HOST=http://meilisearch:7700 \
  -e REDIS_HOST=redis \
  -e CACHE_DRIVER=redis -e SESSION_DRIVER=redis \
  -e ALLOW_REGISTRATION=true \
  -v bar_data:/var/www/cocktails/storage/bar-assistant \
  --network bar-assistant-v6.10.1-net \
  --restart unless-stopped \
  ghcr.io/karlomikus/barassistant:6.10.1

四服务手工 docker run 需自行保证网络与启动顺序,生产建议直接用上面的 compose 文件。

十一、排障实录(全部真实踩坑)

1. metrics 端点 403:METRICS_ALLOWED_IPS 不认 IPv6 本机回环。 启用 METRICS_ENABLED=true 后从服务器本机 curl http://127.0.0.1:8135/api/metrics,日志出现(实测):

[2026-11-01 11:11:10] production.WARNING: Denied IP address ::1 metrics endpoint access

原因:请求经宿主机转发落到 IPv6 ::1,而白名单只写了 IPv4 网关。修复:METRICS_ALLOWED_IPS 同时列入 Prometheus 抓取源的真实 IPv4(本例 10.89.60.1,即 Docker 网络网关),或加 ::1。改后 curl 返回完整 Prometheus 文本(bar_assistant_api_active_bars_total 1 等)。

2. 卷名与项目名不一致的困惑。 compose 声明 name: bar-assistant-v6.10.1-stack,但 docker volume ls 显示卷前缀是 bar-assistant-v6101-stack——Compose 会把项目名中的 . 规范化删除。按卷名做备份脚本时以 docker volume ls 实际输出为准,别拿 YAML 里的项目名硬拼。

3. 镜像没有 latest 标签。 docker pull ghcr.io/karlomikus/barassistant:latest 会失败(官方 README 明示无 latest)。必须显式 tag;CI 里用 v6 可自动吃次版本更新,锁 6.10.1 则完全可复现。

4. Meilisearch master key 直连 API 的安全提示。 compose 里把 MEILI_MASTER_KEY 同时给了 API,官方为此专门提供 php artisan bar:setup-meilisearch 命令生成受限 scoped key 并回写 ENV(详见 CLI 篇),生产环境建议执行一次并轮换 master key。

5. 端口占用。 起栈前 ss -ltn | grep 81 确认 8132/8134/8135 空闲(本规划段已占 8129/8130/8132/8134-8138 为既有取证栈,换机部署时按同法重新选段)。

十二、日常运维速查

docker compose ps                        # 状态(api 应显示 healthy)
docker compose logs -f bar-assistant     # API 日志(stderr 通道)
docker compose restart bar-assistant     # 改 ENV 后重启 API
docker compose down                      # 停栈(保留卷)
docker compose down -v                   # 连卷删(清库重来,慎用)
docker compose pull && docker compose up -d   # 按 tag 规则更新

十三、系列导航

  • 选型认知:《Bar Assistant 介绍与选型指南》
  • 配置项逐项详解:《Bar Assistant 6.10.1 配置参数详解》
  • CLI 与 API 实操:《Bar Assistant 6.10.1 常用 CLI/API 命令详解》
Bar Assistant Docker Compose 部署指南 - Quzuo