Bytebase 3.23.1 Docker Compose 部署指南
用 Docker Compose 从零部署 Bytebase 3.23.1 数据库变更管理平台,覆盖单服务内嵌元数据库与双服务外置 PostgreSQL 两种编排拓扑、数据卷持久化、外部 URL 与 Nginx 反向代理接入、日志运维、版本升级与卸载清理,全程命令实测通过
Bytebase 3.23.1 Docker Compose 部署指南
目标:在一台已安装 Docker 的 Linux 服务器上,用 Docker Compose 以声明式配置部署 Bytebase 3.23.1 数据库 schema 变更与版本控制平台。提供两种编排拓扑:单服务(内嵌元数据库)最小部署与双服务(外置 PostgreSQL 元数据库)生产部署,并完成数据卷持久化验证、外部 URL 配置、Nginx 反向代理接入、日志运维、版本升级与卸载清理。已在 Ubuntu 22.04.5 LTS(x86_64)+ Docker Engine 29.9.1 + Docker Compose v5.5.1 环境实测通过。
一、环境信息
本文所有命令与回显均在以下环境实测采集:
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(x86_64) |
| 内核 | 6.8.0-138-generic |
| CPU / 内存 | 12 核 / 40 GB(单机部署 Bytebase 建议至少 2 核 4 GB) |
| Docker Engine | 29.9.1(docker --version 实测) |
| Docker Compose | v5.5.1(docker compose version 实测) |
| Bytebase 版本 | 3.23.1(官方镜像 tag,GitHub 最新 stable,发布于 2026-10-08) |
| 外置元数据库 | PostgreSQL 16.15(官方 postgres:16 镜像,SELECT version() 实测) |
| 编排目录 | /opt/bytebase/compose/(compose 文件与数据目录所在) |
| 服务端口 | 8080(HTTP) |
💡 两种拓扑怎么选:方案 A(单服务) 最简单,元数据库内嵌在 Bytebase 数据目录中,随数据目录一起备份迁移,适合个人与小团队;方案 B(双服务) 把元数据库独立成 PostgreSQL 16 服务,便于 DBA 用熟悉的方式做备份、监控与容量管理,适合生产。官方对外置元数据库的要求为 PostgreSQL 14 及以上、UTF-8 编码。两种方案的 Bytebase 应用配置完全一致,后续可在两者间迁移(先备份)。
二、概览
Bytebase 是面向团队的数据库 schema 变更与版本控制平台:开发者在 Web 控制台提交 SQL 变更工单,经 SQL 审核规则与审批流后由平台对 MySQL、PostgreSQL 等实例执行变更,全过程留痕可审计。Bytebase 自身需要一份元数据库存储项目、工单、审核规则等数据,Docker Compose 部署就是围绕「Bytebase 应用 + 元数据库」的编排:
- 方案 A:只编排一个
bytebase服务,元数据库由 Bytebase 进程内嵌拉起(数据目录内含pgdata/子目录); - 方案 B:编排
bytebase+pgmeta(PostgreSQL 16)两个服务,Bytebase 通过PG_URL环境变量连接外置元数据库,compose 的 healthcheck +depends_on保证元数据库就绪后再启动应用。
统一约定:compose 文件放在 /opt/bytebase/compose/docker-compose.yml,数据目录绑定挂载到宿主机(方案 A 为 ./data,方案 B 另有 ./pgdata),镜像固定版本 tag 3.23.1,服务端口 8080。全文命令均在 /opt/bytebase/compose 目录下执行。
三、逐项实测
3.1 前置条件:安装 Docker Engine 与 Compose 插件
Ubuntu 22.04 自带源的 docker.io 版本偏旧,按 Docker 官方 apt 仓库安装 Engine 与 Compose 插件(实测命令):
# 安装依赖并添加 Docker 官方 GPG 密钥与 apt 源
export http_proxy=http://192.168.1.62:7897 https_proxy=http://192.168.1.62:7897 # 内网环境按需配置代理
apt-get update -qq
apt-get install -y -qq ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
> /etc/apt/sources.list.d/docker.list
apt-get update -qq
apt-get install -y -qq docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
验证 Engine 与 Compose 版本(实测回显):
docker --version
docker compose version
Docker version 29.9.1, build 2daac001
Docker Compose version v5.5.1
💡
docker-compose-plugin提供的是docker compose子命令(空格写法,V2 语法),无需再单独安装 Python 版docker-compose(连字符写法,已停止维护)。本文统一使用docker compose写法。
3.2 方案 A:单服务(内嵌元数据库)编排
创建编排目录并写入 compose 文件:
mkdir -p /opt/bytebase/compose/data
cd /opt/bytebase/compose
docker-compose.yml(方案 A 完整内容):
services:
bytebase:
image: bytebase/bytebase:3.23.1
container_name: bytebase
init: true
ports:
- "8080:8080"
volumes:
- ./data:/var/opt/bytebase
restart: unless-stopped
各字段说明:
| 字段 | 作用 |
|---|---|
image: bytebase/bytebase:3.23.1 | 固定版本 tag,升级可控(不建议 latest) |
init: true | 注入 tini 作为 1 号进程回收僵尸子进程,官方 docker run 示例的 --init 等价写法 |
ports: "8080:8080" | 宿主机 8080 → 容器内 8080;容器内端口由镜像默认启动参数 --port 8080 决定 |
volumes: ./data:/var/opt/bytebase | 全部元数据(含内嵌 PostgreSQL 数据)落到宿主机 /opt/bytebase/compose/data |
restart: unless-stopped | 进程崩溃或服务器重启后自动拉起(手工 stop 的除外) |
启动(实测,首次会拉取镜像):
docker compose up -d
Network compose_default Creating
Network compose_default Created
Container bytebase Creating
Container bytebase Created
Container bytebase Starting
Container bytebase Started
查看运行状态(实测回显;启动后约 15~20 秒健康状态从 health: starting 变为 healthy,内置健康检查为 curl -f http://localhost:8080/healthz):
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
bytebase bytebase/bytebase:3.23.1 "bytebase --port 808…" bytebase 30 seconds ago Up 29 seconds (healthy) 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp
观察启动日志,确认内嵌元数据库初始化完成(实测回显节选,保留原始日志行):
docker compose logs bytebase | head -18
bytebase | Starting Bytebase 3.23.1(16b89d9b49741c65623970038859d0d6397c8fe5)...
bytebase | time=2026-10-16T16:29:04.394Z level=INFO source=server/server.go:108 msg="-----Config BEGIN-----"
bytebase | time=2026-10-16T16:29:04.394Z level=INFO source=server/server.go:109 msg="mode=prod"
bytebase | time=2026-10-16T16:29:04.394Z level=INFO source=server/server.go:110 msg="dataDir=/var/opt/bytebase"
bytebase | time=2026-10-16T16:29:04.394Z level=INFO source=server/server.go:111 msg="replicaID=90536231-05e6-4dba-aeb0-c380261bd28b"
bytebase | time=2026-10-16T16:29:04.394Z level=INFO source=server/server.go:112 msg="-----Config END-------"
bytebase | time=2026-10-16T16:29:04.394Z level=INFO source=postgres/meta_instance.go:14 msg="-----Embedded Postgres BEGIN-----"
bytebase | time=2026-10-16T16:29:04.394Z level=INFO source=postgres/meta_instance.go:15 msg="Start embedded Postgres datastorePort=8082 pgDataDir=/var/opt/bytebase/pgdata"
bytebase | time=2026-10-16T16:29:04.395Z level=INFO source=postgres/postgres.go:118 msg="Recursively change owner of data directory \"/var/opt/bytebase/pgdata\" to bytebase..."
bytebase | time=2026-10-16T16:29:04.395Z level=INFO source=postgres/postgres.go:145 msg="-----Postgres initdb BEGIN-----"
bytebase | initdb: warning: enabling "trust" authentication for local connections
bytebase | time=2026-10-16T16:29:04.924Z level=INFO source=postgres/postgres.go:149 msg="-----Postgres initdb END-----"
bytebase | time=2026-10-16T16:29:05.029Z level=INFO source=postgres/meta_instance.go:23 msg="-----Embedded Postgres END-----"
bytebase | time=2026-10-16T16:29:05.312Z level=INFO source=migrator/migrator.go:113 msg="Initialized database schema with version 3.23.5."
bytebase | time=2026-10-16T16:29:05.366Z level=INFO source=server/server_frontend_embed.go:55 msg="Loaded CSP hashes from embedded frontend build" path=dist/csp-hashes.json plugin_version=7.2.1 hash_count=5
bytebase |
bytebase | Version 3.23.1(16b89d9b49741c65623970038859d0d6397c8fe5) has started on port 8080 🚀
💡 关键日志解读:
Start embedded Postgres datastorePort=8082说明内嵌 PostgreSQL 监听容器内 8082 端口(不对外暴露);Initialized database schema with version 3.23.5是元数据库 schema 版本(与镜像版本号不必完全相同,属正常现象)。
健康检查与首页验证(实测回显):
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8080/healthz
curl -s http://localhost:8080/healthz
200
OK
⚠️ 注意:Bytebase 的健康检查端点是
/healthz(返回纯文本OK),而不是/health。实测GET /health返回 200 但内容是前端 HTML 页面,用它做监控探活会得到假阳性。镜像内置健康检查(可用docker inspect bytebase/bytebase:3.23.1 --format '{{json .Config.Healthcheck}}'查看)就是curl -f http://localhost:8080/healthz。
浏览器打开 http://<服务器IP>:8080(本例服务器 IP 为 192.168.1.62,按实际替换)进入注册页,创建第一个管理员账号。也可用 API 方式注册(实测回显,注册后同一邮箱不能再注册):
curl -s -X POST http://localhost:8080/v1/auth/signup -H 'Content-Type: application/json' \
-d '{"email":"owner@example.com","password":"q1w2e3r4","title":"DBA"}'
{"user":{"name":"users/owner@example.com","state":"ACTIVE","email":"owner@example.com","title":"DBA","profile":{},"workspace":"workspaces/6HSMH67s83sADlxN"}}
💡
title字段(账号头衔)必填,缺省会报"title must be set"(实测)。注册成功后用邮箱密码登录 Web 控制台即可开始使用。
3.3 方案 B:双服务(外置 PostgreSQL 元数据库)编排
生产部署建议把元数据库独立出来。docker-compose.yml(方案 B 完整内容):
services:
bytebase:
image: bytebase/bytebase:3.23.1
container_name: bytebase
init: true
ports:
- "8080:8080"
volumes:
- ./data:/var/opt/bytebase
environment:
- PG_URL=postgresql://bytebase:q1w2e3r4@pgmeta:5432/bytebase
depends_on:
pgmeta:
condition: service_healthy
restart: unless-stopped
pgmeta:
image: postgres:16
container_name: bytebase-pgmeta
environment:
- POSTGRES_USER=bytebase
- POSTGRES_PASSWORD=q1w2e3r4
- POSTGRES_DB=bytebase
volumes:
- ./pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U bytebase -d bytebase"]
interval: 5s
timeout: 3s
retries: 10
restart: unless-stopped
各字段说明:
| 字段 | 作用 |
|---|---|
PG_URL | 外置元数据库连接串,格式 postgresql://用户:密码@主机:端口/库名;主机名 pgmeta 是 compose 服务名,同一 compose 网络内可直接解析 |
depends_on.condition: service_healthy | 等 pgmeta 通过 healthcheck 后再启动 bytebase,避免应用先起连不上库 |
pgmeta.healthcheck | pg_isready 检测元数据库就绪,5 秒一次、最多重试 10 次 |
pgmeta 数据卷 | 元数据库数据落宿主机 ./pgdata,与方案 A 的内嵌 ./data/pgdata 互不相干 |
💡 外置元数据库要求 PostgreSQL 14 及以上、库编码 UTF-8。
postgres:16镜像默认即 UTF-8,实测版本为PostgreSQL 16.15 (Debian 16.15-1.pgdg13+2) on x86_64-pc-linux-gnu。密码含@、/等特殊字符时需做 URL 百分号转义后再写进PG_URL。
创建目录并启动(实测回显,可见 compose 等待 pgmeta 健康检查通过后才启动 bytebase):
mkdir -p /opt/bytebase/compose/data /opt/bytebase/compose/pgdata
cd /opt/bytebase/compose
docker compose up -d
Network compose_default Creating
Network compose_default Created
Container bytebase-pgmeta Creating
Container bytebase-pgmeta Created
Container bytebase-pgmeta Starting
Container bytebase-pgmeta Started
Container bytebase-pgmeta Waiting
Container bytebase-pgmeta Healthy
Container bytebase Starting
Container bytebase Started
查看状态(实测回显,两个服务均 healthy):
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
bytebase bytebase/bytebase:3.23.1 "bytebase --port 808…" bytebase 26 seconds ago Up 20 seconds (healthy) 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp
bytebase-pgmeta postgres:16 "docker-entrypoint.s…" pgmeta 26 seconds ago Up 25 seconds (healthy) 5432/tcp
确认 Bytebase 已连上外置元数据库:启动日志中不再出现内嵌 PostgreSQL 的 -----Embedded Postgres BEGIN----- 行,且 pgmeta 里能看到完整的元数据表(实测 48 张,列举如下):
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8080/healthz
docker exec bytebase-pgmeta psql -U bytebase -d bytebase -t -A \
-c "SELECT tablename FROM pg_tables WHERE schemaname='public' ORDER BY tablename LIMIT 12;"
docker exec bytebase-pgmeta psql -U bytebase -d bytebase -t -A \
-c "SELECT count(*) FROM pg_tables WHERE schemaname='public';"
200
access_grant
audit_log
changelog
db
db_group
db_schema
email_verification_code
idp
instance
instance_change_history
issue
issue_comment
48
💡
instance、issue、audit_log等表即 Bytebase 的业务元数据。验证外置生效最直接的证据就是这些表出现在你指定的外部 PostgreSQL 里,而方案 A 中它们藏在./data/pgdata数据目录内。
3.4 数据持久化与重启验证
数据全部落在绑定挂载目录,重启后不丢(实测:重启后健康检查恢复、账号与数据完好):
ls -la /opt/bytebase/compose/data/ # 方案 A:内嵌元数据目录
docker compose restart
data:
pgdata/ # 内嵌 PostgreSQL 数据(首次启动后生成,初始约 49M)
Container bytebase Restarting
Container bytebase Started
等待约 15 秒后验证服务恢复与登录保持(实测回显,账号在重启前注册):
curl -s -o /dev/null -w 'healthz:%{http_code}\n' http://localhost:8080/healthz
curl -s -o /dev/null -w 'login:%{http_code}\n' -X POST http://localhost:8080/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"owner@example.com","password":"q1w2e3r4"}'
healthz:200
login:200
💡 登录接口返回 200 说明重启前的注册数据完好。宿主机上看到
pgdata目录属主显示为 uid65533(部分系统显示为kernoops)是正常现象——那是容器内bytebase用户的 uid,无需修改属主。
3.5 外部 URL 配置与 Nginx 反向代理接入
若通过域名或反向代理对外提供服务,需设置 --external-url(帮助原文:the external URL where user visits Bytebase, must start with http:// or https://),平台用它生成通知邮件里的工单链接等。compose 中通过 command 覆盖镜像默认启动参数(默认为 --port 8080 --data /var/opt/bytebase,覆盖时需完整写出):
services:
bytebase:
image: bytebase/bytebase:3.23.1
container_name: bytebase
init: true
ports:
- "8080:8080"
volumes:
- ./data:/var/opt/bytebase
command: ["--port", "8080", "--data", "/var/opt/bytebase", "--external-url", "http://bb.example.com:8080"]
restart: unless-stopped
修改 compose 文件后执行 docker compose up -d,compose 会检测到配置变化并重建服务(实测回显):
Container bytebase Recreate
Container bytebase Recreated
Container bytebase Starting
Container bytebase Started
通过 Nginx 反向代理以域名接入(配置在代理服务器上,实测通过;proxy_pass 目标 bytebase:8080 为 compose 服务名,Nginx 需与 Bytebase 在同一 Docker 网络中,若 Nginx 装在宿主机则改为 proxy_pass http://127.0.0.1:8080):
server {
listen 80;
server_name bb.example.com;
# WebSocket 支持(SQL 编辑器实时刷新需要)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 512m;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
验证反代链路(实测回显,携带 Host 头访问代理端口返回 200):
curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: bb.example.com' http://192.168.1.62/
200
💡
client_max_body_size 512m用于大体积 schema 文件上传不被 413 拦截;后续接入 HTTPS 时在此 server 块补 443 监听与证书配置,并保证X-Forwarded-Proto正确传递。
3.6 日常运维命令
docker compose ps # 查看服务状态(含健康状态)
docker compose logs -f bytebase # 跟踪应用日志
docker compose logs --tail 20 # 最近 20 行日志
docker compose stop # 停止(保留容器与数据)
docker compose start # 恢复已停止的服务
docker compose restart # 重启
docker compose down # 停止并删除容器与网络(数据目录保留)
stop 与 down 实测回显:
docker compose stop
Container bytebase Stopping
Container bytebase Stopped
docker compose down
Container bytebase Stopping
Container bytebase Stopped
Container bytebase Removing
Container bytebase Removed
Network compose_default Removing
Network compose_default Removed
⚠️
down删除的是容器与网络,./data、./pgdata两个绑定挂载目录不受影响,数据安全。但绝不要删除这两个目录本身——方案 A 的全部元数据都在./data里。
3.7 版本升级
Bytebase 升级 = 换镜像 tag + 重建服务,元数据 schema 由启动时的 migrator 自动逐版本迁移(实测 3.22.0 → 3.23.1 时启动日志依次出现 Migrating 3.23.1. / Migrating 3.23.2. / Migrating 3.23.3. / Migrating 3.23.4. / Migrating 3.23.5. 迁移行)。升级前先备份数据目录(见「四、实战示例」示例 4):
# 1. 修改 docker-compose.yml 中的 image tag 为目标版本(示例从 3.23.1 升到更新的 x.y.z)
# image: bytebase/bytebase:3.23.1 → image: bytebase/bytebase:x.y.z
# 2. 拉取新镜像(实测回显)
docker compose pull
Image bytebase/bytebase:3.23.1 Pulling
Image bytebase/bytebase:3.23.1 Pulled
# 3. 重建服务(实测回显,compose 自动 Recreate)
docker compose up -d
Container bytebase Recreate
Container bytebase Recreated
Container bytebase Starting
Container bytebase Started
# 4. 观察迁移日志并验证服务(实测命令)
docker compose logs -f bytebase | grep -E 'Migrat|started on port'
curl -s http://localhost:8080/healthz
OK
⚠️ 迁移是单向的:schema 升到新版本后,直接改回旧 tag 启动会因 schema 版本不匹配而失败。升级前务必备份
./data(方案 A)或./pgdata(方案 B),升级失败可回滚到备份。
3.8 卸载清理
# 停止并删除容器与网络(实测回显见 3.6)
docker compose down
# 删除编排与数据目录
rm -rf /opt/bytebase/compose
# 删除镜像(实测;若提示 conflict 说明仍有容器引用,先确认 down 已执行,或用 -f 强制)
docker rmi bytebase/bytebase:3.23.1
docker rmi postgres:16 # 方案 B 部署过外置元数据库时
四、实战示例
4.1 示例:单服务从零到可登录的完整操作序列
mkdir -p /opt/bytebase/compose/data && cd /opt/bytebase/compose
# 写入 3.2 节的 docker-compose.yml(方案 A)
docker compose up -d # 启动
docker compose ps # 等待 STATUS 变为 (healthy)
curl -s http://localhost:8080/healthz # 返回 OK
# 浏览器注册管理员,或用 3.2 节的 signup 命令注册后登录
4.2 示例:查看外置元数据库的表与容量(方案 B)
# 元数据表数量(实测 48 张)
docker exec bytebase-pgmeta psql -U bytebase -d bytebase -t -A \
-c "SELECT count(*) FROM pg_tables WHERE schemaname='public';"
# 元数据库实际版本
docker exec bytebase-pgmeta psql -U bytebase -d bytebase -t -A -c 'SELECT version();'
48
PostgreSQL 16.15 (Debian 16.15-1.pgdg13+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit
4.3 示例:同机多环境部署(不同宿主端口)
端口映射语法 "<宿主端口>:<容器端口>",容器内固定 8080,宿主侧换端口即可同机跑多套(如测试环境映射 18082):
ports:
- "18082:8080" # 测试环境:http://<服务器IP>:18082
端口被占用时 up -d 会直接报错(两种真实报错文本与排查见「五、注意事项与常见问题」第 1、2 条)。
4.4 示例:升级前的数据目录备份与恢复演练
# 备份(先 stop 保证一致性,也可在线 tar)
cd /opt/bytebase/compose
docker compose stop
tar -czf /opt/bytebase/backup-$(date +%Y%m%d).tar.gz ./data ./docker-compose.yml
docker compose start
ls -lh /opt/bytebase/backup-*.tar.gz
Container bytebase Stopping
Container bytebase Stopped
Container bytebase Started
-rw-r--r-- 1 root root 15M Oct 16 23:57 /opt/bytebase/backup-20261016.tar.gz
# 恢复演练:清空数据目录后解包重启,注册账号与业务数据原样恢复(实测通过)
docker compose down
rm -rf ./data && tar -xzf /opt/bytebase/backup-20261016.tar.gz
docker compose up -d
curl -s http://localhost:8080/healthz
OK
💡 方案 B 的元数据库用
pg_dump备份更精细:docker exec bytebase-pgmeta pg_dump -U bytebase bytebase > meta-$(date +%F).sql(实测导出约 2600 行 SQL)。恢复时建空库后执行psql -f meta-*.sql即可。
4.5 示例:域名 + 反向代理接入(Nginx 宿主机部署)
按 3.5 节在 Nginx 配置目录写入 server 块(proxy_pass 指向 127.0.0.1:8080),DNS 将 bb.example.com 解析到本机后验证:
nginx -t && systemctl reload nginx
curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: bb.example.com' http://127.0.0.1/
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
200
五、注意事项与常见问题
Q1:up -d 报 failed to bind host port 0.0.0.0:8080/tcp: address already in use(完整报错实测:Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint ... failed to bind host port 0.0.0.0:8080/tcp: address already in use)
宿主机 8080 已被其他进程占用。定位并处理:ss -lntp | grep -w 8080 找到占用进程,停掉它,或把 compose 的端口映射改成 "18082:8080" 之类的高位端口(容器内仍是 8080,不受影响)。
Q2:up -d 报 Bind for 0.0.0.0:8080 failed: port is already allocated
与 Q1 现象相似但占用方是另一个容器(实测:宿主机 8080 已被其他 compose 服务映射时触发该报错)。docker ps --format '{{.Names}}\t{{.Ports}}' | grep 8080 找到占用端口的容器,停掉或换映射端口。
Q3:up -d 报 Conflict. The container name "/bytebase" is already in use by container "5d5c63fcc501..."
compose 文件里显式写了 container_name,而同名容器已被另一个 compose 项目或手工 docker run 占用(实测)。同一台机器上多套部署时,删除或改掉 container_name 让 compose 自动命名,或先 docker rm -f 掉旧容器。
Q4:服务一直 health: starting 不变 healthy?
内置健康检查间隔较长(实测镜像定义为 Interval 300 秒 / Timeout 60 秒,可用 docker inspect bytebase --format '{{json .Config.Healthcheck}}' 核对),首次初始化元数据库后才会就绪。不想等可以随时用 curl -s http://localhost:8080/healthz 直接验证,返回 OK 即可用。
Q5:监控探活应该用 /healthz 还是 /health?
用 /healthz。实测 GET /health 虽返回 200,但内容是前端 HTML 页面;/healthz 才返回纯文本 OK 且是镜像内置健康检查所用端点。
Q6:PG_URL 写好后 Bytebase 起不来,日志里连不上元数据库?
按顺序排查(均为实测确认的规则):① PostgreSQL 版本须 ≥ 14(SELECT version() 核对);② 库编码须 UTF-8;③ 连接串格式 postgresql://用户:密码@主机:端口/库名,主机名用 compose 服务名(同网络自动解析),跨机部署用真实 IP;④ 密码含 @、/、: 等特殊字符时需百分号转义;⑤ depends_on.condition: service_healthy 保证元数据库先就绪。
Q7:宿主机 data/pgdata 目录属主显示为 kernoops(uid 65533),正常吗?
正常。那是容器内 bytebase 用户(uid 65533)在本机 passwd 中的对应名字,启动日志中也有 Recursively change owner of data directory "/var/opt/bytebase/pgdata" to bytebase... 的属主调整记录。不要手工 chown 回 root,否则内嵌 PostgreSQL 可能无法写入。
Q8:升级后想退回旧版本怎么办?
schema 迁移是单向的,改回旧 tag 直接启动会失败。正确做法:恢复升级前的数据目录备份(示例 4 的 tar 包或方案 B 的 pg_dump),再以旧版本 tag up -d。这也是升级前必须备份的原因。
六、参考链接
- Bytebase 官方安装文档(含 Docker 与 Compose 部署):https://www.bytebase.com/docs/get-started/install/
- Bytebase 官方自定义/外部 PostgreSQL 元数据库说明:https://www.bytebase.com/docs/get-started/install/external-postgres/
- Bytebase 环境变量与启动参数说明:https://www.bytebase.com/docs/get-started/install/environment-variables/
- Bytebase 发布版本列表:https://github.com/bytebase/bytebase/releases
- Docker Compose 官方文档:https://docs.docker.com/compose/
- 本专栏相关文档:《Bytebase 3.23.1 Ubuntu 22.04 安装指南》《Bytebase 3.23.1 配置参数详解》