NocoDB 外部 Postgres + 外部 Redis 部署实战:最小化 Docker 足迹的生产架构
本篇技术指南基于 NocoDB 仓库中的示例部署 external-postgres-and-redis 展开,讲解如何在“PostgreSQL 与 Redis 均运行在 Docker 之外”的前提下,仅用 NocoDB 主容器和单个工作者(worker)容器完成生产部署。读完后,你能掌握 docker-compose.yml 的双容器编排原理、docker.env 与 nocodb/db.json 的关键参数含义,以及针对不同证书 CA 类型的 Postgres SSL 配置策略。
1. 场景定位:什么情况下选择这种部署形态
该示例面向的核心诉求是最小化 Docker 足迹:两个数据库(PostgreSQL 与 Redis)都部署在 Docker 外部,由你自行管理的主机或托管服务提供,Docker 里只跑 NocoDB 本体。官方给出的适用条件是:
- 你有自建的 Postgres 和 Redis(部署在专用主机上);
- 或者你使用的是某种“塞不进
managed-postgres示例”的 Postgres 服务(例如网络拓扑、认证方式等不满足托管库典型形态的自建服务)。
示例声明的部署形态如下:
| 组件 | 形态 |
|---|---|
| PostgreSQL | 外部(任意可达主机) |
| Redis | 外部(任意可达主机) |
| 反向代理 | 无,NocoDB 直接监听 8080 端口 |
它与仓库内其他示例的分工在 examples 总览 中有一张清晰的对照表:quickstart-demo 适合本地评估(Postgres/Redis 均内置),managed-postgres 适合托管数据库(RDS/Azure/Cloud SQL),traefik-custom-ssl 适合带自有证书的正式环境,而本示例 external-postgres-and-redis 正是“Postgres 与 Redis 都外部自建、不引入代理”的最小生产形态。总览文档同时提醒:启动前必须替换所有占位值(CHANGE_ME_db_password、your-managed-db-host 等)。
2. 快速开始:三步部署
官方给出的操作命令如下(在 NocoDB 仓库根目录执行复制,然后进入部署目录修改配置):
cp -r docker-compose/examples/external-postgres-and-redis ./my-deployment
cd my-deployment
# Edit docker.env: set NC_REDIS_URL
# Edit nocodb/db.json: set host, credentials, and SSL choice
docker compose up -d
整个流程只有两个必改文件:
- docker.env —— 设置
NC_REDIS_URL指向你的外部 Redis; - nocodb/db.json —— 设置 Postgres 主机、凭据和 SSL 选项。
此外建议按实际环境修改 NC_SITE_URL(对外公开地址)与 NC_SECURE_ATTACHMENTS,详见下文第 4 节。
3. 容器编排:docker-compose.yml 的结构解析
示例的 docker-compose.yml 只定义了 nocodb 与 worker 两个服务,完整配置如下:
services:
nocodb:
image: nocodb/nocodb:latest
env_file: docker.env
deploy:
mode: replicated
replicas: 1
restart: unless-stopped
volumes:
- nocodb_data:/usr/app/data
- ./nocodb/db.json:/usr/app/data/db.json
networks:
- nocodb-network
ports:
- '8080:8080'
healthcheck:
test: ['CMD-SHELL', 'wget -q --tries=1 --spider http://localhost:8080/api/v1/health || exit 1']
interval: 30s
timeout: 5s
retries: 5
start_period: 30s
worker:
image: nocodb/nocodb:latest
env_file: docker.env
environment:
NC_WORKER_CONTAINER: 'true'
depends_on:
nocodb:
condition: service_healthy
restart: unless-stopped
volumes:
- nocodb_data:/usr/app/data
- ./nocodb/db.json:/usr/app/data/db.json
networks:
- nocodb-network
networks:
nocodb-network:
driver: bridge
volumes:
nocodb_data:
几个关键设计点值得展开:
3.1 同一镜像,两种角色
两个服务使用同一个镜像 nocodb/nocodb:latest,角色由环境变量 NC_WORKER_CONTAINER 区分:主容器不设置该变量,worker 容器设置为 'true'。源码印证了这一点——Noco.ts 中:
if (process.env.NC_WORKER_CONTAINER === 'true') {
if (!getRedisURL()) {
throw new Error('NC_REDIS_URL is required');
}
process.env.NC_DISABLE_TELE = 'true';
}
也就是说,worker 容器启动时如果没有配置 NC_REDIS_URL 会直接抛错退出,这是本示例必须先把 docker.env 里的 Redis 地址填真实的原因之一;同时 worker 会强制关闭 telemetry 上报(NC_DISABLE_TELE)。而 redisHelpers.ts 中的 getRedisURL() 解析优先级为 NC_CACHE_REDIS_URL || NC_REDIS_URL,因此本示例的 NC_REDIS_URL 即生效的 Redis 连接串。
worker 的存在是为了把后台任务(导入导出、报表、定时任务等 job 处理)从 API 主进程中剥离——从 jobs-redis.ts 与 jobs.service.ts 中大量对 NC_WORKER_CONTAINER 的分支判断可以推断,任务的生产/消费职责由该变量划分:API 容器只负责任务入队,worker 容器负责消费。
3.2 共享卷与挂载的 db.json
两个容器都挂载了同一命名卷 nocodb_data:/usr/app/data(存放附件、本地数据等)以及同一份 ./nocodb/db.json(映射到容器内 /usr/app/data/db.json)。这保证主容器和 worker 使用完全一致的数据库连接配置,避免二者指向不同 Postgres 的错配事故。
3.3 健康检查作为启动屏障
主容器定义了基于 /api/v1/health 的 healthcheck(30 秒间隔、5 次重试、30 秒启动宽限),worker 则通过 depends_on: nocodb: condition: service_healthy 保证只有主容器健康后才启动。这解决了“worker 先起来、Redis 里还没有 API 侧初始化好的 job 通道”这类竞态问题,是本编排中容易被忽视但很实用的细节。
3.4 端口暴露
主容器把宿主 8080 映射到容器 8080,且示例不内置任何反向代理——官方建议在你自己的负载均衡器或代理之后转发到 8080。如需换宿主端口,改 ports 映射即可,这与 managed-postgres 示例 中给出的做法一致:
ports:
- '3000:8080' # 暴露到 3000 端口
4. 环境变量:docker.env 逐项说明
docker.env 完整内容如下:
# Database
NC_DB_JSON_FILE=/usr/app/data/db.json
# Redis
NC_REDIS_URL=redis://your-redis-host:6379
# Public URL (email links, webhooks, OAuth redirects). Set to your public-facing URL.
NC_SITE_URL=https://nocodb.example.com
# Settings
NC_SECURE_ATTACHMENTS=true
NC_DISABLE_MUX=true
各变量含义与源码依据:
| 变量 | 示例值 | 说明 |
|---|---|---|
NC_DB_JSON_FILE |
/usr/app/data/db.json |
指定数据库连接配置文件(db.json)在容器内的路径。NcConfig.ts 中若该文件不存在会直接抛出 NC_DB_JSON_FILE not found 错误 |
NC_REDIS_URL |
redis://your-redis-host:6379 |
外部 Redis 的连接串,替换为你自己的 Redis 主机与端口;worker 容器强制依赖该值(见 3.1 节) |
NC_SITE_URL |
https://nocodb.example.com |
对外公开地址,用于邮件链接、webhook、OAuth 回调跳转;务必设置为你的真实公网 URL |
NC_SECURE_ATTACHMENTS |
true |
开启附件安全模式。envs.ts 中通过 process.env.NC_SECURE_ATTACHMENTS === 'true' 解析;noco.module.ts 会据此启用附件安全相关模块。生产环境建议保持 true |
NC_DISABLE_MUX |
true |
关闭 NocoDB 的 Mux(实时消息通道)能力,本示例中显式禁用 |
5. 数据库连接:nocodb/db.json 参数详解
db.json 决定了 NocoDB 元数据库的连接方式,示例内容:
{
"client": "pg",
"connection": {
"host": "your-managed-db-host.rds.amazonaws.com",
"port": "5432",
"user": "nocodb",
"password": "CHANGE_ME_db_password",
"database": "nocodb",
"ssl": {
"rejectUnauthorized": true
}
}
}
字段说明:
| 字段 | 取值 | 说明 |
|---|---|---|
client |
pg |
使用 PostgreSQL 驱动 |
connection.host |
你的外部主机 | 本示例中为任意可达主机(自建或托管),替换占位值 |
connection.port |
"5432" |
Postgres 默认端口,字符串形式 |
connection.user / password |
你的凭据 | password 的 CHANGE_ME_db_password 是占位符,启动前必须替换 |
connection.database |
nocodb |
NocoDB 使用的库名 |
connection.ssl.rejectUnauthorized |
true |
严格校验服务端证书链,适用于使用公共受信 CA 的外部 Postgres |
需要强调的是:PostgreSQL 是 NocoDB 启用许可(License)的前提,官方 examples 总览中明确“本目录所有示例都满足这一要求”,因为 Postgres 元数据库是其中的硬性组件。
6. SSL 策略:公共 CA 与私有 CA 的分叉
这是本示例 README 中独立成节的重要内容。针对外部 Postgres 的证书来源,官方给出两条路径:
- 公共受信 CA(如云厂商托管库通常使用的证书体系):保持
db.json默认的ssl.rejectUnauthorized: true,即严格证书校验,无需任何额外配置。这与 managed-postgres 示例 的结论一致:ssl.rejectUnauthorized: true适用于 RDS、Azure、Cloud SQL 这类使用公共 CA 证书的托管数据库。 - 自签名或私有 CA(本地机房、私有云常见):不要在本示例上打补丁,而是直接改用仓库中的 postgres-private-ca 示例。该示例要求在
db.json中内嵌 CA 证书,并给出了将多行 PEM 证书压成单行(换行替换为\n)的转换命令:
awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' your-ca.pem
然后将其输出作为 db.json 中的 ca 值填入。这样划分示例的意图很明确:本示例保持配置最小化,把“私有 CA + 证书内嵌”这一复杂场景隔离到专门示例中,降低误配风险。
7. 部署后的验证与收尾
- 健康检查自证:主容器的 healthcheck 就是官方认可的就绪信号,
docker compose ps中主容器显示 healthy 后,worker 才会被拉起(3.3 节的启动屏障),因此观察容器状态即可判断整体就绪。 - 占位值复查:
docker.env的your-redis-host与db.json的CHANGE_ME_db_password、your-managed-db-host等占位值必须在docker compose up -d之前全部替换,否则 worker 会在 Redis 连接失败时直接退出。 - 首个用户与许可:按 examples 总览 的说明,栈跑起来后在 NocoDB 中注册第一个用户,再于 Admin Panel → License 激活许可。
- 与其他示例的横向选择:如果你的托管库属于典型 RDS/Azure/Cloud SQL 形态,可优先评估 managed-postgres;如果需要在 NocoDB 前加 Traefik 和自有 TLS 证书,则参考 traefik-custom-ssl。本示例的独特价值在于“双外部 + 零代理”的最小容器集合,适合基础设施已经完备、只想让 Docker 承担应用本体的团队。
参考路径汇总
- 示例入口:docker-compose/examples/external-postgres-and-redis/README.md
- 编排文件:docker-compose.yml
- 环境变量:docker.env
- 数据库配置:nocodb/db.json
- 示例总览与选型表:docker-compose/examples/README.md
- 私有 CA 变体:docker-compose/examples/postgres-private-ca/README.md
- worker/Redis 启动逻辑:packages/nocodb/src/Noco.ts
- Redis 连接解析:packages/nocodb/src/helpers/redisHelpers.ts
- 配置文件加载:packages/nocodb/src/utils/nc-config/NcConfig.ts
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00