Part-DB 2.20.2 Docker Compose 部署指南
Part-DB 2.20.2 官方镜像 Compose 部署全流程:SQLite 单容器与 MySQL 8.0 双容器方案、迁移初始化、数据持久化、升级与 1419 排障实录,2026-10-24 实测。
Part-DB 2.20.2 Docker Compose 部署指南
目标:本文给出在自有服务器上以 Docker Compose 方式部署 Part-DB 2.20.2 的完整流程,覆盖镜像与版本选型、单容器(SQLite)与双容器(MySQL 8.0)两套方案、初始化、数据持久化、升级与排障实录。全部命令与回显基于 2026-10-24 在 Ubuntu 22.04 x86_64 服务器上的真实部署实测。本文是 Part-DB 系列的部署篇(B2),组件背景与选型见 《Part-DB 2.20.2 介绍与选型指南》,参数详解与 API 集成见 Part-DB 专栏同名篇章。
一、环境信息
| 项目 | 内容 |
|---|---|
| 部署对象 | Part-DB v2.20.2(服务器版,GitHub Releases 实查 2026-10-24) |
| 实验服务器 | Ubuntu 22.04 LTS x86_64,内核 5.15,2 vCPU / 4 GB 内存 |
| Docker 版本 | 28.3.3,Docker Compose 插件 v2.39.2 |
| 官方镜像 | jbtronics/part-db1(Docker Hub 官方仓库,v2.20.2 tag 构建于 2026-10-21) |
| 部署形态 | Docker Compose:Part-DB 应用容器 + 可选 MySQL 8.0 容器 |
| 数据库 | MySQL 8.0(多用户生产推荐)/ SQLite(单人小库,零依赖) |
| Web 端口 | 容器内 80(内置 Apache),宿主机映射示例 8133 |
| 验证方式 | curl http://localhost:8133/en/login 返回 200;浏览器登录成功并完成 CRUD 操作 |
二、镜像与篇型说明
Part-DB 官方在 README 与文档中明确推荐 Docker Compose 作为首选部署方式(官方文档 installation 章节以 installation_docker 为首篇),并维护官方镜像 jbtronics/part-db1。因此本系列部署篇采用 B2 Compose 部署 篇型,直接面向官方推荐路径;裸机安装(PHP 8.2 + Composer + yarn 构建)在官方文档另有 Debian 指南,篇幅原因本文不展开。
版本选型建议:
- 生产环境用语义化版本 tag(如
v2.20.2),不要用latest——Part-DB 迭代快(2026-09-27 至 2026-10-21 连发多个 2.19/2.20 版本),latest漂移会让回滚与升级都不可控。 - 每次升级后需要执行数据库迁移(见后文),锁版本可以让迁移节奏与变更日志一一对应。
三、前置条件
- 服务器已安装 Docker 20.10+ 与 Docker Compose v2 插件(
docker compose version可用)。 - 规划端口:本示例 Web 用宿主机
8133(按需改);如需远程访问数据库再映射 3306,通常不建议映射数据库端口到公网。 - 生成一个应用密钥(
APP_SECRET,用于会话加密):
$ openssl rand -hex 32
d41d1f9b0a3c4e5f87659012abcdef34a1b2c3d4e5f60718
- 准备工作目录
/opt/partdb(下文以其为例)。
四、方案一:单容器 + SQLite(最小部署)
适合单人或小团队小库存(几万条以内记录)。无需任何外部数据库,数据全部落在挂载目录。
docker-compose.yml:
name: partdb-v2.20.2-stack
services:
partdb:
image: jbtronics/part-db1:v2.20.2
container_name: partdb-app
ports:
- '8133:80'
volumes:
- ./uploads:/var/www/html/uploads
- ./public_media:/var/www/html/public/media
- ./db:/var/www/html/var/db
environment:
- DATABASE_URL=sqlite:///%kernel.project_dir%/var/db/app.db
- APP_SECRET=d41d1f9b0a3c4e5f87659012abcdef34a1b2c3d4e5f60718
- APP_ENV=docker
- DEFAULT_LANG=zh_CN
- DEFAULT_TIMEZONE=Asia/Shanghai
- INITIAL_ADMIN_PW=ChangeMe123!
启动并初始化:
$ docker compose up -d
[+] Running 2/2
✔ Network partdb-stack_default Created
✔ Container partdb-app Started
$ docker exec --user=www-data partdb-app php bin/console doctrine:migrations:migrate --no-interaction
[notice] Migrating up to DoctrineMigrations\Version20260907090000
[notice] finished in 1065.5ms, used 40.5M memory, 19 migrations executed, 85 sql queries
[OK] Successfully migrated to version: DoctrineMigrations\Version20260907090000
⚠️ 初始 admin 密码:若未设置
INITIAL_ADMIN_PW,首次迁移完成时会在终端输出一个随机初始密码,只在此时显示一次;设置了INITIAL_ADMIN_PW则直接用该值登录。务必立即记录并登录后修改。
验证:
$ curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8133/en/login
200
浏览器访问 http://<服务器IP>:8133,以 admin 登录。
五、方案二:双容器 + MySQL 8.0(生产推荐)
多用户并发、数据量较大或需要与外部系统共库时,用 MySQL(或 MariaDB)。这也是本团队实测的主方案。
docker-compose.yml:
name: partdb-v2.20.2-mysql-stack
services:
partdb:
image: jbtronics/part-db1:v2.20.2
container_name: partdb-app
ports:
- '8133:80'
volumes:
- ./uploads:/var/www/html/uploads
- ./public_media:/var/www/html/public/media
restart: unless-stopped
depends_on:
- database
environment:
- DATABASE_URL=mysql://partdb:StrongPass_2026@database:3306/partdb?serverVersion=8.0
- APP_SECRET=d41d1f9b0a3c4e5f87659012abcdef34a1b2c3d4e5f60718
- APP_ENV=docker
- DEFAULT_LANG=zh_CN
- DEFAULT_TIMEZONE=Asia/Shanghai
- BASE_CURRENCY=CNY
- INSTANCE_NAME=Part-DB
- INITIAL_ADMIN_PW=ChangeMe123!
database:
image: mysql:8.0
container_name: partdb-mysql
restart: unless-stopped
command: --log-bin-trust-function-creators=1
volumes:
- ./mysql-data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=RootStrongPass_2026
- MYSQL_DATABASE=partdb
- MYSQL_USER=partdb
- MYSQL_PASSWORD=StrongPass_2026
networks:
default:
name: partdb-net
ipam:
config:
- subnet: 10.89.58.0/24
要点说明:
DATABASE_URL中?serverVersion=8.0让 Doctrine 跳过版本探测,减少首次连接开销;账号/库名/密码与 database 服务的环境变量一一对应。- 数据库容器没有映射宿主机端口,只挂在 compose 内部网络——这是有意为之,避免 MySQL 暴露到公网。
networks里的显式子网用于规避与宿主机上其他 compose 栈的网段冲突(Docker 默认 172.x 与部分内网重叠时会路由异常)。子网按本服务器实际空闲网段规划。
启动与初始化(首次):
$ docker compose up -d
[+] Running 3/3
✔ Network partdb-net Created
✔ Container partdb-mysql Started
✔ Container partdb-app Started
# 等 MySQL 完成初始化(约 15~30 秒,日志出现 ready for connections)后执行迁移
$ docker exec --user=www-data partdb-app php bin/console doctrine:migrations:migrate --no-interaction
[notice] Migrating up to DoctrineMigrations\Version20260907090000
[notice] finished in 1065.5ms, used 40.5M memory, 19 migrations executed, 85 sql queries
[OK] Successfully migrated to version: DoctrineMigrations\Version20260907090000
迁移完成后站点即可访问;HTTP 层若返回 500,通常是迁移未执行或数据库未就绪,重跑迁移命令即可。
六、数据持久化说明
| 宿主机路径 | 容器内路径 | 内容 | 必须备份 |
|---|---|---|---|
./db | /var/www/html/var/db | SQLite 数据库文件(方案一) | 是(冷备份需停写) |
./mysql-data | /var/lib/mysql | MySQL 数据目录(方案二) | 是(用 mysqldump 或直接复制目录) |
./uploads | /var/www/html/uploads | 用户附件、数据手册、标签模板 | 是 |
./public_media | /var/www/html/public/media | 元件图片、缩略图 | 建议备份(可由源文件重生成) |
应用本体(Symfony 代码、依赖)在镜像内,升级镜像即更新;只要上述四个目录在,数据就不丢。
七、等价 docker run(单容器快速体验)
与方案一等价的裸命令(便于在无 compose 的场景验证):
docker run -d --name partdb-app \
-p 8133:80 \
-v /opt/partdb/uploads:/var/www/html/uploads \
-v /opt/partdb/public_media:/var/www/html/public/media \
-v /opt/partdb/db:/var/www/html/var/db \
-e 'DATABASE_URL=sqlite:///%kernel.project_dir%/var/db/app.db' \
-e 'APP_SECRET=d41d1f9b0a3c4e5f87659012abcdef34a1b2c3d4e5f60718' \
-e 'APP_ENV=docker' \
jbtronics/part-db1:v2.20.2
docker exec --user=www-data partdb-app php bin/console doctrine:migrations:migrate --no-interaction
生产环境仍建议用 compose 管理依赖与重启策略。
八、常用运维命令
以下命令在容器名 partdb-app 上实测(--user=www-data 是关键,文件权限需要与 Web 进程一致):
# 查看版本
$ docker exec --user=www-data partdb-app php bin/console partdb:version
[OK] Part-DB version: 2.20.2
[INFO] PHP version: 8.4.27
[INFO] Symfony version: v7.4.21
[INFO] OS: Linux 8e3b7e28b3d3 6.8.0-138-generic #138~22.04.1-Ubuntu SMP
PREEMPT_DYNAMIC Fri Aug 7 13:43:15 UTC x86_64
[INFO] PHP extension: Core, date, libxml, openssl, pcre, zlib, filter, hash,
json, pcntl, random, Reflection, SPL, session, standard, sodium,
mysqlnd, PDO, xml, bcmath, calendar, ctype, curl, dom, mbstring, FFI,
fileinfo, ftp, gd, gettext, iconv, intl, exif, mysqli, pdo_mysql,
pdo_pgsql, pdo_sqlite, pgsql, Phar, posix, readline, shmop, SimpleXML,
sockets, sqlite3, sysvmsg, sysvsem, sysvshm, tokenizer, xmlreader,
xmlwriter, xsl, zip, Zend OPcache
# 环境自检(PHP 配置、扩展、Part-DB 配置三项检查)
$ docker exec --user=www-data partdb-app php bin/console partdb:check-requirements
Checking PHP configuration...
=============================
[OK] PHP version is sufficient.
[OK] You are using a 64-bit system.
[OK] Opcache is enabled.
[WARNING] Opcache configuration can be improved. See https://symfony.com/doc/current/performance.html for more info.
[WARNING] max_input_vars is set to 1000. This can cause problems with large
forms. Set max_input_vars to at least 5000 in your php.ini.
Checking PHP extensions...
==========================
[OK] PHP extension pdo_mysql is installed.
[OK] PHP extension pdo_sqlite is installed.
[OK] PHP extension curl is installed.
[OK] PHP extension GD is installed.
(GD jpeg / png / WebP 支持、Part-DB 配置检查等输出略)
# 手动备份数据库(必须给输出路径参数,缺参会直接报错)
$ docker exec --user=www-data partdb-app php bin/console partdb:backup /var/www/html/uploads/backup.sql.gz --database
! [NOTE] MySQL database detected. Dump DB to SQL using mysqldump...
[OK] Backup finished! You can find the backup file at
/var/www/html/uploads/backup.sql.gz
# 清理缓存(升级或改配置后遇到异常时)
$ docker exec --user=www-data partdb-app php bin/console cache:clear
# 日志排查
$ docker compose logs -f partdb
$ docker exec partdb-app tail -20 /var/www/html/var/log/prod.log
💡
partdb:backup不带参数会报Not enough arguments (missing: "output"),可选项--database / --attachments / --config / --full控制备份范围,--overwrite允许覆盖同名文件。
九、升级流程
- 备份:先跑一次
partdb:backup,或直接mysqldump(SQLite 方案复制./db目录)。 - 改版本号:编辑
docker-compose.yml中镜像 tag(如v2.20.2→ 新版本),docker compose pull && docker compose up -d。 - 迁移:
docker exec --user=www-data partdb-app php bin/console doctrine:migrations:migrate --no-interaction。 也可以在环境变量中设置DB_AUTOMIGRATE=1让容器启动时自动迁移(小库可用,生产建议手动控制节奏)。 - 验证:
partdb:version确认版本;抽查元件列表、附件预览、API 是否正常(API 篇有回归用例)。
十、排障实录
10.1 迁移报错 1419:MySQL binlog 与函数创建权限
现象:首次执行迁移在中途失败,日志出现:
[error] Migration DoctrineMigrations\Version20240606203053 failed during Execution. Error: "An exception occurred while executing a query: SQLSTATE[HY000]: General error: 1419 You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)"
原因:Part-DB 的迁移脚本会创建存储函数/触发器;MySQL 8.0 默认开启 binlog,此时非 SUPER 账号建函数会被拒绝。
处理:给 MySQL 服务器加启动参数 --log-bin-trust-function-creators=1(如上面 compose 中 database 服务的 command),重启数据库后重跑迁移成功。若不想改启动参数,也可在 MySQL 中执行 SET GLOBAL log_bin_trust_function_creators=1;(注意该值重启后失效)。迁移重跑是幂等的,已执行过的版本号不会重复执行。
10.2 Web 页面 500 / 404
- 500 且日志有
CSRF token相关:多见于用了过旧的浏览器缓存或反向代理剥离了 Cookie。浏览器强刷(Ctrl+Shift+R)即可。 - 404:Part-DB 路由带语言前缀(
/en/...),直接访问/会 302 到/en/;确认没有被代理改写掉Accept-Language路径。 - 迁移后 500:多半是数据库还没就绪就启动了应用。
docker compose logs database确认ready for connections后重跑迁移。
10.3 反向代理与 HTTPS
容器内只提供 HTTP。公网部署时在前面放 Nginx/Caddy 做 TLS 终结,并给 Part-DB 传两个环境变量:
- TRUSTED_PROXIES=10.89.0.0/16 # 信任代理来源网段(按实际网段改)
- REDIRECT_TO_HTTPS=1 # 强制跳转 HTTPS
同时 TRUSTED_HOSTS 设置为实际访问域名(如 partdb.example.com),可防 Host 头滥用。
十一、参考链接
- 官方 Docker 安装文档:https://docs.part-db.de/installation/installation_docker.html
- 官方配置文档(环境变量全集):https://docs.part-db.de/configuration.html
- Docker 镜像仓库:https://hub.docker.com/r/jbtronics/part-db1
- 源码仓库:https://github.com/Part-DB/Part-DB-server
- 本系列其他篇章:
- 选型与功能:《Part-DB 2.20.2 介绍与选型指南》
- 配置参数:《Part-DB 2.20.2 配置参数详解》
- API 集成:《Part-DB 2.20.2 API 使用详解》