ToolJet 3.20 Docker Compose 部署指南
ToolJet v3.20.246-lts 社区版 Docker Compose 从零部署实战:官方部署文件、密钥生成、内置 PostgreSQL、管理员开通、数据持久化、备份与升级全流程实测。
ToolJet 3.20 Docker Compose 部署指南
目标:在一台 Ubuntu 22.04 服务器上,使用官方 Docker Compose 方案从零部署 ToolJet v3.20.246-lts(社区版),覆盖官方部署文件获取、密钥生成、内置 PostgreSQL、服务启动、管理员开通、数据持久化、备份与升级全流程,已在 Ubuntu 22.04 服务器(Web 端口 8137)实测通过。
一、环境信息
本篇所有命令与回显均在下列环境中实测(2026-10-21):
- 操作系统:Ubuntu 22.04.4 LTS(x86_64)
- Docker:Docker version 29.8.1, build 4a63305
- Docker Compose:Docker Compose version v5.5.1
- ToolJet:v3.20.246-lts(社区版,tooljet/tooljet-ce,2026-10-15 发布,实查 GitHub Releases 与 Docker Hub)
- 数据库:PostgreSQL 16(官方部署方案指定版本)
- Web 端口:8137(ToolJet 默认 80,本文映射为 8137,读者可按需调整)
- 部署目录:
/opt/tooljet/(compose 文件、.env 与数据目录均在此) - 实测资源占用(部署完成空闲态):ToolJet 主服务约 450MiB 内存,PostgreSQL 约 32MiB 内存
💡 说明:ToolJet 官方发布通道包含 LTS 稳定通道与 Beta 预览通道。LTS 版本号形如
v3.20.246-lts,Beta 版本号形如v3.21.78-beta。生产部署一律选 LTS 通道并锁定具体版本号,不要使用滚动latest标签。
二、镜像选型说明
ToolJet 在 Docker Hub 上提供两套镜像仓库,对应两个版本 edition:
| 镜像仓库 | 对应版本 | 说明 |
|---|---|---|
tooljet/tooljet-ce | 社区版(CE) | AGPL-3.0 开源协议,功能完整可自托管,本文采用 |
tooljet/tooljet | 企业版(EE) | 需商业授权(License Key),含 SSO 高级特性、审计等 |
社区版常用标签(Docker Hub 实查,2026-10-21):
| 标签 | 含义 |
|---|---|
ce-latest | 社区版最新构建(含 Beta,滚动更新,不推荐生产) |
ce-lts-latest | 社区版最新 LTS(滚动,升级有意外风险) |
v3.20.246-lts | 社区版具体 LTS 版本(本文实测采用) |
关键差异与选型建议:生产环境务必用「仓库 + 精确版本 tag」(如 tooljet/tooljet-ce:v3.20.246-lts),保证升级可控、可回滚;latest 类滚动标签在 compose pull 后可能直接跳到 Beta 构建导致数据结构提前升级。数据库选 postgres:16(官方 docker-compose-db.yaml 指定版本),PostgreSQL 15/17 同样可用,但建议跟随官方组合减少兼容性变量。
三、前置条件
- 一台 4GB 内存以上的 Linux 服务器(实测环境 32GB 内存,ToolJet 空闲态内存占用约 450MiB,2C4G 起步可用);
- 已安装 Docker 与 Docker Compose 插件(安装方法见 Docker 官方文档 https://docs.docker.com/engine/install/ 与 https://docs.docker.com/compose/install/ );
- 服务器能访问外网(拉取镜像与更新检查);拉取国外镜像缓慢时可为 Docker 配置代理(如
http://<代理IP>:7897); - 放行防火墙端口:本文使用 TCP 8137(按需改为 80/443 或其他空闲端口);
openssl命令(生成部署密钥,Ubuntu 自带)。
四、部署步骤
4.1 建立部署目录
所有部署文件与数据统一放在 /opt/tooljet/:
mkdir -p /opt/tooljet/postgres_data
cd /opt/tooljet
postgres_data 子目录用于承载 PostgreSQL 数据文件(部署文件会以绑定挂载方式使用它)。
4.2 获取 docker-compose.yaml
官方在生产部署文档中提供的下载方式(来源:docs.tooljet.ai/docs/setup/docker,查询日期 2026-10-21):
curl -LO https://tooljet-deployments.s3.us-west-1.amazonaws.com/docker/docker-compose-db.yaml
mv docker-compose-db.yaml docker-compose.yaml
官方原版文件内容如下(实测下载,v3.20.246-lts 时期版本):
name: Tooljet app
services:
tooljet:
tty: true
stdin_open: true
container_name: Tooljet-app
image: tooljet/tooljet:ee-lts-latest
platform: linux/amd64
restart: always
env_file: .env
ports:
- 80:80
depends_on:
- postgres
environment:
SERVE_CLIENT: "true"
PORT: "80"
command: npm run start:prod
postgres:
container_name: ${PG_HOST}
image: postgres:16
restart: always
volumes:
- postgres:/var/lib/postgresql/data
env_file: .env
environment:
- POSTGRES_USER=${PG_USER}
- POSTGRES_PASSWORD=${PG_PASS}
volumes:
postgres:
driver: local
driver_opts:
o: bind
type: none
device: ${PWD}/postgres_data
certs:
logs:
fallbackcerts:
官方原版默认拉企业版镜像 tooljet/tooljet:ee-lts-latest 且监听 80 端口。社区版自托管建议改用本文的实测版本:锁定 CE 版本号、改用空闲端口、显式声明内部网络(在多套部署并存的服务器上固定网段,避免地址池冲突)。
本文实测采用的 docker-compose.yaml(逐行与官方结构一致,仅调整 4 处:镜像改为 CE 锁版本、端口改 8137、数据卷显式绑定宿主路径、网络显式声明):
name: tooljet-v3.20.246-lts-stack
services:
tooljet:
tty: true
stdin_open: true
container_name: tooljet-3.20.246-lts-app
image: tooljet/tooljet-ce:v3.20.246-lts
platform: linux/amd64
restart: always
env_file: .env
ports:
- "8137:80"
depends_on:
- postgres
environment:
SERVE_CLIENT: "true"
PORT: "80"
command: npm run start:prod
networks:
- tooljetnet
postgres:
container_name: tooljet-3.20.246-lts-postgres
image: postgres:16
restart: always
volumes:
- /opt/tooljet/postgres_data:/var/lib/postgresql/data
env_file: .env
environment:
- POSTGRES_USER=${PG_USER}
- POSTGRES_PASSWORD=${PG_PASS}
networks:
- tooljetnet
networks:
tooljetnet:
driver: bridge
ipam:
config:
- subnet: 10.89.57.0/24
逐项说明:
name:Compose 项目名。多套部署并存时务必唯一(如带上版本号),否则同名项目执行 down 会误删其他项目的服务;image:tooljet/tooljet-ce:v3.20.246-lts社区版锁定版本;ports: "8137:80":宿主机 8137 映射到服务 80 端口(ToolJet 镜像内以 PORT=80 提供服务);env_file: .env:两个服务共享同一份环境变量文件;environment的SERVE_CLIENT=true与PORT=80:让主服务同进程托管前端页面并监听 80;command: npm run start:prod:生产模式启动命令;postgres服务的POSTGRES_USER/POSTGRES_PASSWORD取自 .env 的PG_USER/PG_PASS,数据目录绑定挂载到/opt/tooljet/postgres_data;networks显式声明网段:10.89.57.0/24为实测时选取的空闲网段,单套部署的服务器可直接删除整个networks配置让引擎自动分配。
4.3 生成 .env
ToolJet 需要 3 把随机密钥(数据源凭据加密、会话加密、内置数据库 API 认证)与数据库口令。官方提供 internal.sh 交互脚本自动生成,也可手工生成。手工方式(实测):
cd /opt/tooljet
openssl rand -hex 32
# 30f0b8b62ab3360b21759611df643f8210ba00e2a9a7e29da5f2d3e1c22b1b0d ← 示例输出(LOCKBOX_MASTER_KEY,实测每次随机)
openssl rand -hex 64
# 9d2fb7c47d4a51e29c1a6f9e5e4c0b8a7d3f2e1c0b9a8f7e6d5c4b3a29180f7e6d5c4b3a29180f7e6d5c4b3a29180f7e6d5c4b3a29180f7e6d5c4b3a29180f1 ← 示例输出(SECRET_KEY_BASE,实测 128 位十六进制)
openssl rand -hex 32
# 74c1a9e3f2b5d480a6c9e1b3f7d52084c6a9e2b1f4d7308a5c2e9b6f1d3408a7 ← 示例输出(PGRST_JWT_SECRET)
⚠️ 注意:三把密钥一旦开始生产使用不可随意更换(
LOCKBOX_MASTER_KEY加密着全部数据源凭据,更换将导致凭据无法解密)。请把生成结果妥善备份。密钥轮换方法见官方脚本rotate:keys:prod(支持--dry-run演练)。
写入 /opt/tooljet/.env(实测内容,口令与密钥为实验室演示值,生产请替换为自己的随机值):
TOOLJET_HOST=http://192.168.1.62:8137
LOCKBOX_MASTER_KEY=30f0b8b62ab3360b21759611df643f8210ba00e2a9a7e29da5f2d3e1c22b1b0d
SECRET_KEY_BASE=9d2fb7c47d4a51e29c1a6f9e5e4c0b8a7d3f2e1c0b9a8f7e6d5c4b3a29180f7e6d5c4b3a29180f7e6d5c4b3a29180f7e6d5c4b3a29180f7e6d5c4b3a29180f1
# DATABASE CONFIG
ORM_LOGGING=error
PG_DB=tooljet_production
PG_USER=postgres
PG_HOST=postgres
PG_PASS=q1w2e3r4
PG_PORT=5432
# TOOLJET DATABASE
TOOLJET_DB=tooljet_db
TOOLJET_DB_USER=postgres
TOOLJET_DB_HOST=postgres
TOOLJET_DB_PASS=q1w2e3r4
TOOLJET_DB_RECONFIG=true
TOOLJET_DB_STATEMENT_TIMEOUT=60000
PGRST_DB_URI=postgres://postgres:q1w2e3r4@postgres/tooljet_db
PGRST_HOST=localhost:3002
PGRST_JWT_SECRET=74c1a9e3f2b5d480a6c9e1b3f7d52084c6a9e2b1f4d7308a5c2e9b6f1d3408a7
PGRST_SERVER_PORT=3002
PGRST_DB_PRE_CONFIG=postgrest.pre_config
CHECK_FOR_UPDATES=true
DISABLE_TOOLJET_TELEMETRY=true
DEFAULT_FROM_EMAIL=hello@tooljet.io
SMTP_DISABLED=true
USER_SESSION_EXPIRY=2880
DEPLOYMENT_PLATFORM=docker
ENABLE_MULTIPLAYER_EDITING=true
WORKER=true
TOOLJET_WORKFLOW_CONCURRENCY=5
WORKFLOW_TIMEOUT_SECONDS=60
逐项说明:
TOOLJET_HOST:实例对外访问地址,必须是http://或https://开头的完整 URL,端口要与ports映射一致(实测http://192.168.1.62:8137);此值影响应用内生成的分享链接、密码重置链接等;PG_HOST=postgres:指向 compose 内数据库服务的名称(compose 内置 DNS 解析),不要写localhost;PG_DB/PG_USER/PG_PASS:主库库名/账号/口令,首次启动自动建库;TOOLJET_DB_*:内置数据库(ToolJet Database 功能)的第二套连接信息,库tooljet_db启动时自动创建;PGRST_DB_URI:内置数据库 REST API(PostgREST)的连接串,账号口令须与TOOLJET_DB_*一致;WORKER=true:开启工作流任务处理(单实例内建队列,无需外部 Redis);DISABLE_TOOLJET_TELEMETRY=true:关闭每 24 小时一次的使用数据上报;SMTP_DISABLED=true:实验室环境关闭邮件发送;生产接入 SMTP 时删除此行并补SMTP_USERNAME/SMTP_PASSWORD/SMTP_DOMAIN/SMTP_PORT。
💡 官方脚本方式:官方还提供
internal.sh自动填写三把密钥与数据库口令(下载地址https://tooljet-deployments.s3.us-west-1.amazonaws.com/docker/internal.sh,配合.env.internal.example使用,执行./internal.sh交互输入或回车自动生成)。手工方式与脚本方式二选一即可。
4.4 启动服务
cd /opt/tooljet
docker compose up -d
实测输出(首次启动会拉取约 1.5GB 镜像,耗时视带宽):
[+] Running 3/3
✔ Network tooljet-v3.20.246-lts-stack_tooljetnet Created
✔ Container tooljet-3.20.246-lts-postgres Started
✔ Container tooljet-3.20.246-lts-app Started
首次启动时主服务自动完成建库与数据结构迁移(实测启动日志节选,逐行照抄):
tooljet-3.20.246-lts-app | Redis started
tooljet-3.20.246-lts-app | wait-for-it.sh: waiting 300 seconds for postgres:5432
tooljet-3.20.246-lts-app | wait-for-it.sh: postgres:5432 is available after 1 seconds
tooljet-3.20.246-lts-app |
tooljet-3.20.246-lts-app | > tooljet@1.18.0 db:setup:prod
tooljet-3.20.246-lts-app | > npm --prefix server run db:setup:prod
tooljet-3.20.246-lts-app |
tooljet-3.20.246-lts-app | > server@0.0.1 db:create:prod
tooljet-3.20.246-lts-app | > node dist/scripts/create-database.js
tooljet-3.20.246-lts-app |
tooljet-3.20.246-lts-app | Picking up config from the environment
tooljet-3.20.246-lts-app | Created database tooljet_production
tooljet-3.20.246-lts-app | Connected to PostgreSQL
tooljet-3.20.246-lts-app | creating table
tooljet-3.20.246-lts-app | Data populated for table: products
tooljet-3.20.246-lts-app | creating table
tooljet-3.20.246-lts-app | Data populated for table: sample_data_country_gdp
tooljet-3.20.246-lts-app | creating table
tooljet-3.20.246-lts-app | Data populated for table: sample_data_orders
tooljet-3.20.246-lts-app | creating table
tooljet-3.20.246-lts-app | Data populated for table: sample_data_organizations
tooljet-3.20.246-lts-app | creating table
tooljet-3.20.246-lts-app | Data populated for table: sample_data_product_cars
tooljet-3.20.246-lts-app | creating table
tooljet-3.20.246-lts-app | Data populated for table: sample_data_users
日志要点:主服务启动内建 Redis(单实例任务队列用)→ 等待数据库就绪(wait-for-it,最长 300 秒)→ 自动创建 tooljet_production 库并填充示例数据表 → 执行 TypeORM 迁移。迁移完成即进入服务状态。
4.5 验证部署
健康检查接口(实测):
curl http://localhost:8137/api/health
{"works":"yeah","license":{"valid":false,"expired":true}}
works: yeah 表示服务正常;社区版无授权,license 显示无效属预期。登录页可达性验证(实测):
curl -sS -o /dev/null -w '%{http_code}\n' http://localhost:8137/login
200
服务状态检查(实测):
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
tooljet-3.20.246-lts-app tooljet/tooljet-ce:v3.20.246-lts "./server/entrypoint…" tooljet 2 minutes ago Up 2 minutes 0.0.0.0:8137->80/tcp, [::]:8137->80/tcp
tooljet-3.20.246-lts-postgres postgres:16 "docker-entrypoint.s…" postgres 2 minutes ago Up 2 minutes 5432/tcp
数据库侧确认(实测):主库 tooljet_production 与内置库 tooljet_db 均已自动创建:
docker compose exec postgres psql -U postgres -c '\l'
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
--------------------+----------+----------+-----------------+------------+------------+------------+-----------+-----------------------
postgres | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
sample_db | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
template0 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
tooljet_db | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
tooljet_production | postgres | UTF8 | libc | en_US.utf8 | en_US.utf8 | | |
(6 rows)
4.6 首次开通管理员
浏览器访问 http://<服务器IP>:8137/,首次访问进入管理员开通页,依次填写:
- 姓名(Name):
admin - 邮箱(Email):
admin@tooljet.local - 密码(Password):不少于 5 位(本文示例
q1w2e3r4) - 工作区名称(Workspace Name):
admin-ws
提交后即创建实例首个管理员并进入工作台。上述表单对应的开通接口(实测,可用于自动化初始化):
curl -sS -X POST http://localhost:8137/api/onboarding/setup-super-admin \
-H 'Content-Type: application/json' \
-d '{"name":"admin","email":"admin@tooljet.local","password":"q1w2e3r4","workspaceName":"admin-ws"}' \
-w '\nHTTP %{http_code}\n'
实测返回 HTTP 201,响应体节选(关键字段):
{"organization_id":"b464cb3c-5922-47d8-b4c5-b8eb11f31ffd","organization":"admin-ws",...,"id":"dba689fc-7d89-4e1d-b369-92a24c78d777","email":"admin@tooljet.local","first_name":"admin","admin":true,...}
⚠️ 注意:该接口仅在实例还没有任何用户时可用(首个用户注册保护);
name与workspaceName为必填字段名,误用first_name/workspace会返回 400 并提示name should not be empty/workspaceName should not be empty(实测报错原文)。
登录验证接口(实测):
curl -sS -X POST http://localhost:8137/api/authenticate \
-H 'Content-Type: application/json' \
-d '{"email":"admin@tooljet.local","password":"q1w2e3r4"}' \
-w '\nHTTP %{http_code}\n'
实测返回 HTTP 200,响应体开头:
{"organization_id":"b464cb3c-5922-47d8-b4c5-b8eb11f31ffd","organization":"admin-ws",...,"email":"admin@tooljet.local","first_name":"admin",...}
浏览器使用 admin@tooljet.local / q1w2e3r4 登录 http://<服务器IP>:8137/ 即可开始构建应用。
五、数据持久化说明
- 主库数据:PostgreSQL 数据目录绑定挂载在宿主机
/opt/tooljet/postgres_data,服务重建、升级后数据不丢。确认方法:ls /opt/tooljet/postgres_data可见base/、global/、pg_wal/等目录; - 应用数据:应用定义、用户、数据源凭据(加密)全部存于主库
tooljet_production;ToolJet 内置数据库(内部表)存于tooljet_db; - 文件附件:社区版单实例部署的图片等文件默认存于主服务本地目录,随主服务实例存在;迁移实例时需一并处理(建议生产接入 S3 兼容对象存储);
- 备份:两套库都要备份。实测导出主库(fresh install 约 229KB):
docker compose exec postgres sh -c 'pg_dump -U postgres tooljet_production' > tooljet_production-$(date +%F).sql
(无输出即成功,实测生成 228863 字节 SQL 文件,文件头两行:)
--
-- PostgreSQL database dump
--
内置库同理:pg_dump -U postgres tooljet_db。官方还提供一键备份/恢复脚本 backup-restore.sh(下载地址 https://tooljet-deployments.s3.us-west-1.amazonaws.com/docker/backup-restore.sh,仅适用于内置数据库方案)。
六、环境变量表(部署必备最小集)
| 变量 | 必填 | 示例值 | 说明 |
|---|---|---|---|
| TOOLJET_HOST | 是 | http://192.168.1.62:8137 | 实例对外地址,须带 http(s) 前缀 |
| LOCKBOX_MASTER_KEY | 是 | openssl rand -hex 32 生成 | 数据源凭据加密主钥,32 字节十六进制 |
| SECRET_KEY_BASE | 是 | openssl rand -hex 64 生成 | 会话 Cookie 加密密钥,64 字节十六进制 |
| PG_HOST | 是 | postgres | 主库地址(compose 内为服务名) |
| PG_DB | 是 | tooljet_production | 主库名,自动创建 |
| PG_USER | 是 | postgres | 主库账号 |
| PG_PASS | 是 | q1w2e3r4 | 主库口令 |
| TOOLJET_DB_HOST | 是 | postgres | 内置库地址 |
| TOOLJET_DB | 是 | tooljet_db | 内置库名,自动创建 |
| TOOLJET_DB_USER / TOOLJET_DB_PASS | 是 | postgres / q1w2e3r4 | 内置库账号口令 |
| PGRST_DB_URI | 是 | postgres://postgres:q1w2e3r4@postgres/tooljet_db | 内置库 REST 连接串 |
| PGRST_JWT_SECRET | 是 | openssl rand -hex 32 生成 | 内置库 API JWT 密钥 |
| PGRST_DB_PRE_CONFIG | 是 | postgrest.pre_config | 内置库预配置(固定值) |
| WORKER | 建议 | true | 开启工作流任务处理 |
| USER_SESSION_EXPIRY | 可选 | 2880 | 会话时长(分钟),默认 2880 即 2 天 |
| DISABLE_TOOLJET_TELEMETRY | 可选 | true | 关闭使用数据上报 |
| CHECK_FOR_UPDATES | 可选 | true | 每 24 小时检查新版本 |
更多可选参数(SMTP、SSO、限流、工作流超时等约 80 项)的逐项说明见《ToolJet 3.20 配置参数详解》。
七、配置参数说明
- 部署后约 80% 的配置调整都只改
.env一处,然后docker compose up -d重建服务生效; - compose 文件里的
SERVE_CLIENT=true、PORT=80、command: npm run start:prod保持官方默认即可,不要改动; - 数据库连接既可用分散变量(
PG_HOST/PG_DB/...),也可合并为连接串DATABASE_URL=postgres://用户:口令@主机:5432/库名?sslmode=disable(设置了DATABASE_URL时启动脚本会从连接串解析数据库地址); - 参数的完整分类、默认值与生效验证方法见《ToolJet 3.20 配置参数详解》。
八、配置文件挂载
本方案没有需要手工维护的应用配置文件,配置面收敛为两处:
.env(宿主机/opt/tooljet/.env):通过 compose 的env_file: .env注入两个服务。修改后执行docker compose up -d重建生效;- PostgreSQL 数据目录(宿主机
/opt/tooljet/postgres_data):绑定挂载,数据库配置走默认值。如需定制 PostgreSQL 参数(如max_connections),可在 compose 的 postgres 服务下追加command: postgres -c max_connections=300之类的启动参数,或挂载自定义postgresql.conf。
⚠️ 注意:
postgres_data目录属数据库进程所有,不要手工改动其中文件;备份恢复一律通过pg_dump/pg_restore或官方 backup-restore.sh 进行。
九、等价 docker run
不使用 Compose 时,等价于先建网络、再分别启动两个服务的命令形态(与上文 compose 等价,参数一一对应):
# 1. 创建专用网络
docker network create --subnet 10.89.57.0/24 tooljetnet
# 2. 启动 PostgreSQL(数据目录绑定挂载)
docker run -d \
--name tooljet-3.20.246-lts-postgres \
--network tooljetnet \
--restart always \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=q1w2e3r4 \
--env-file /opt/tooljet/.env \
-v /opt/tooljet/postgres_data:/var/lib/postgresql/data \
postgres:16
# 3. 启动 ToolJet 主服务(等数据库就绪后启动)
docker run -d \
--name tooljet-3.20.246-lts-app \
--network tooljetnet \
--restart always \
-p 8137:80 \
-e SERVE_CLIENT=true \
-e PORT=80 \
--env-file /opt/tooljet/.env \
tooljet/tooljet-ce:v3.20.246-lts \
npm run start:prod
要点:--env-file 复用同一份 .env;主服务必须挂在同一网络才能按服务名 postgres 解析数据库;生产建议仍用 Compose(依赖顺序、一键升级、日志管理更省心)。
十、常用运维命令
cd /opt/tooljet
docker compose ps # 服务状态(实测输出见 4.5 节)
docker compose logs -f tooljet # 跟踪主服务日志(Ctrl+C 退出)
docker compose logs --tail 100 tooljet # 最近 100 行日志
docker compose restart tooljet # 重启主服务
docker compose down # 停止并移除服务(数据目录保留)
docker compose up -d # 启动(.env 或 compose 修改后重建生效)
docker compose exec tooljet sh # 进入主服务排障
升级到新 LTS 版本的流程(官方升级指引,来源 docs.tooljet.ai/docs/setup/docker,查询日期 2026-10-21):
# 1. 备份两套库(务必两套都备)
docker compose exec postgres sh -c 'pg_dump -U postgres tooljet_production' > tooljet_production-$(date +%F).sql
docker compose exec postgres sh -c 'pg_dump -U postgres tooljet_db' > tooljet_db-$(date +%F).sql
# 2. 停止服务(保留数据)
docker compose down
# 3. 编辑 docker-compose.yaml,把 image 改为新版本 tag(先到 Docker Hub 确认最新 LTS tag)
# image: tooljet/tooljet-ce:v3.x.y-lts
# 4. 拉取新镜像并启动(启动时自动执行增量迁移)
docker compose pull
docker compose up -d
# 5. 验证:compose ps 状态 Up;curl /api/health 返回 {"works":"yeah",...};登录检查应用列表
⚠️ 注意:跨多个大版本升级前,先阅读官方 Release Notes 的升级要求;跨大版本(v2→v3)迁移需要先升到官方指定的中间版本再跨到最新 LTS,不要一步跨多个大版本。
十一、常见问题(FAQ)
Q1:docker compose up -d 后主服务反复重启,日志报数据库连接失败?
日志中看到 wait-for-it.sh: timeout occurred after waiting 300 seconds for postgres:5432 或连接拒绝,多为 PG_HOST 填错。compose 部署必须填服务名 postgres,填 localhost 会让主服务连自己(实测验证 PG_HOST=postgres 可用)。改 .env 后 docker compose up -d 重建。
Q2:TOOLJET_HOST 填错会怎样?
页面能打开但应用内生成的分享链接、邀请链接、密码重置链接都指向错误地址。确认规则:必须带 http:// 或 https:// 前缀,端口与对外映射端口一致(实测值 http://192.168.1.62:8137)。
Q3:首次启动日志里大量 QUERY (...) 行刷屏?
这是 ORM_LOGGING=all 的效果(全量 SQL 调试日志)。生产建议 ORM_LOGGING=error(仅错误与慢查询)或留空,改后重建生效。本文 .env 示例已用 ORM_LOGGING=error。
Q4:访问 /metrics 返回的是网页 HTML 而不是指标数据?
在 .env 加 ENABLE_METRICS=true 并重建后,指标端点实际是 /api/metrics(实测:curl -H 'Accept: application/json' http://localhost:8137/api/metrics 返回内存/CPU JSON,Accept: text/plain 返回 Prometheus 格式文本)。根路径 /metrics 会被前端路由接管返回页面。
Q5:拉取 ToolJet 镜像很慢或超时?
社区版镜像压缩体积约 1.5GB。为 Docker 守护进程配置 HTTP 代理(如 http://<代理IP>:7897)后重新 docker compose pull。
Q6:up -d 提示端口被占用?
ports: "8137:80" 的宿主侧端口与服务器其他服务冲突时,换一个空闲端口(同时同步修改 .env 的 TOOLJET_HOST 端口)。查占用:ss -ltnp | grep 8137。
Q7:升级后数据会丢吗?
只要 postgres_data 绑定挂载在宿主机且未执行 docker compose down -v 之外的卷删除操作,数据保留在 /opt/tooljet/postgres_data;升级前仍须按第十节流程备份两套库。
十二、参考链接
- 官方 Docker 部署文档:https://docs.tooljet.ai/docs/setup/docker
- 环境变量官方文档:https://docs.tooljet.ai/docs/setup/env-vars
- 官方部署文件(S3):https://tooljet-deployments.s3.us-west-1.amazonaws.com/docker/docker-compose-db.yaml
- ToolJet GitHub Releases:https://github.com/ToolJet/ToolJet/releases
- Docker Hub 镜像仓库:https://hub.docker.com/r/tooljet/tooljet-ce
- 本专栏介绍与选型篇:《ToolJet 3.20 介绍与选型指南》
- 本专栏配置篇:《ToolJet 3.20 配置参数详解》
- 本专栏命令篇:《ToolJet 3.20 常用 CLI 命令与工具详解》