首页
/ NocoDB 生产部署实战:Traefik 自定义 SSL 证书 + 外部 PostgreSQL/Redis 架构解析

NocoDB 生产部署实战:Traefik 自定义 SSL 证书 + 外部 PostgreSQL/Redis 架构解析

2026-09-04 15:14:30作者:史锋燃Gardner

本文以 NocoDB 仓库中 traefik-custom-ssl 部署示例为核心,完整讲解「外部托管数据库 + 外部缓存 + Traefik 自有证书终结 TLS」这套生产级部署形态:如何组织证书文件与 certs.yml、如何用 Docker Compose 编排 nocodb 主容器、worker 容器与 Traefik 反向代理,以及配合外部服务实现水平扩容的关键点。读完后你能直接复制该示例改造成自己域名的 HTTPS 生产部署,并理解每个环境变量与标签在 NocoDB 源码中的实际作用。

适用场景:全外置依赖 + 企业证书

该示例的定位(见 examples 总览)是「使用你自己的 SSL 证书进行生产部署」——所有后端服务均外置,Traefik 使用你自己的证书(企业 CA、通配符证书均可)终结 TLS:

  • PostgreSQL:外部托管数据库(RDS/Azure/Cloud SQL),启用 SSL;
  • Redis:外部托管(ElastiCache、Memorystore、Azure Cache 等);
  • Proxy:Traefik + 自定义 SSL 证书。

这套形态的典型价值在于:数据与状态全部落在外部托管服务上,NocoDB 本身是无状态应用容器,可以随意横向扩容和滚动重启。

部署步骤:复制示例、放证书、改三处配置

原文档给出的标准操作流程如下:

cp -r examples/traefik-custom-ssl ./my-deployment
cd my-deployment

# Place your TLS certificate and key
mkdir -p certs
cp /path/to/cert.pem certs/cert.pem
cp /path/to/key.pem certs/key.pem

# Edit docker.env: set NC_REDIS_URL
# Edit nocodb/db.json: set your database host and credentials
# Edit docker-compose.yml: replace nocodb.example.com with your domain
docker compose up -d

需要修改的三处配置分别对应三个文件:

文件 要改的内容
docker.env 外部 Redis 地址 NC_REDIS_URL(以及 NC_SITE_URL 等)
nocodb/db.json 外部 PostgreSQL 的主机、账号密码等连接信息
docker-compose.yml nocodb.example.com 替换为你的真实域名

另外注意 examples 总览文档中的通用警告:所有占位符(CHANGE_ME_db_passwordyour-managed-db-host 等)在启动前必须替换。

证书文件规范:完整证书链 + 私钥

证书必须放在部署目录的 certs/ 下,文件内容要求如下(源自 README):

文件 内容
certs/cert.pem 完整证书链(服务器证书 + 中间证书)
certs/key.pem 对应私钥

注意 cert.pem 要求的是完整证书链而非单张叶子证书,即需要把中间证书拼接进去,否则部分客户端会因缺少中间 CA 而报证书错误。

certs.yml 负责告诉 Traefik 证书在哪里。示例中的默认内容(certs.yml):

tls:
  certificates:
    - certFile: /etc/traefik/certs/cert.pem
      keyFile: /etc/traefik/certs/key.pem

如果还需要为额外域名配置多张证书,向 certs.yml 追加条目即可:

tls:
  certificates:
    - certFile: /etc/traefik/certs/cert.pem
      keyFile: /etc/traefik/certs/key.pem
    - certFile: /etc/traefik/certs/other-cert.pem
      keyFile: /etc/traefik/certs/other-key.pem

编排细节:docker-compose.yml 逐段解析

完整编排文件包含三个服务,逐个拆解如下。

nocodb 主服务

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
  labels:
    - 'traefik.enable=true'
    - 'traefik.http.routers.nocodb.rule=Host(`nocodb.example.com`)'
    - 'traefik.http.routers.nocodb.entrypoints=websecure'
    - 'traefik.http.routers.nocodb.tls=true'
  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

几个关键点:

  • deploy.mode: replicated + replicas:以声明式副本数管理实例,这是后续水平扩容的基础(见后文「水平扩容」一节)。
  • db.json 通过卷注入./nocodb/db.json:/usr/app/data/db.json,与 docker.env 中的 NC_DB_JSON_FILE=/usr/app/data/db.json 指向同一位置——NocoDB 由此读取外部 PostgreSQL 连接配置。
  • Traefik 标签exposedbydefault=false 的 Traefik 只暴露带 traefik.enable=true 标签的服务;路由规则 Host(\nocodb.example.com`)绑定域名,且仅挂在websecure(443)入口并强制 tls=true`。
  • 健康检查:容器内用 wget --spider 探测 http://localhost:8080/api/v1/health,间隔 30 秒、超时 5 秒、重试 5 次,start_period: 30s 给启动留出宽限——该健康检查是 worker 容器启动的前置条件。

worker 服务:把后台任务剥离出来

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

worker 使用同一镜像,通过 NC_WORKER_CONTAINER='true' 切换到 worker 模式,且必须等 nocodb 主容器通过健康检查后才启动condition: service_healthy)。从源码可以印证这个标志的实际含义(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(任务队列依赖 Redis),未配置时直接抛错退出;同时自动禁用遥测(NC_DISABLE_TELE=true)。这解释了为什么本示例的 docker.envNC_REDIS_URL 是必填项。此外,源码中如 jobs-redis.tsauth.module.ts 等模块都依据该标志决定只挂载 worker 侧逻辑(跳过 AuthController 等 HTTP 路由)。

traefik 服务:文件 + Docker 双 Provider

traefik:
  image: traefik:v3.6
  command:
    - '--providers.docker=true'
    - '--providers.docker.exposedbydefault=false'
    - '--providers.file.filename=/etc/traefik/certs.yml'
    - '--entryPoints.web.address=:80'
    - '--entryPoints.websecure.address=:443'
    - '--entryPoints.web.http.redirections.entryPoint.to=websecure'
    - '--entryPoints.web.http.redirections.entryPoint.scheme=https'
  ports:
    - '80:80'
    - '443:443'
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock:ro
    - ./certs:/etc/traefik/certs:ro
    - ./certs.yml:/etc/traefik/certs.yml:ro
  restart: unless-stopped
  networks:
    - nocodb-network

配置要点:

  • 双 Provider:Docker provider(exposedbydefault=false,配合服务标签使用)+ file provider(加载 /etc/traefik/certs.yml 中的 TLS 证书)。路由规则来自 Docker 标签,证书配置来自本地文件,两者职责分离。
  • 强制 HTTPSweb(80)入口上配置了 redirections.entryPoint,所有 HTTP 流量 301 跳转到 websecure(443),用户无法再明文访问。
  • 只读挂载:docker.sock 以 :ro 挂载(Traefik 只读取容器事件),./certs./certs.yml 同样只读挂载,证书文件与容器内路径的对应关系即 /etc/traefik/certs/

环境变量与数据库配置:docker.env 和 db.json

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:告诉 NocoDB 去哪里读数据库连接 JSON,与 compose 中卷挂载路径一致。
  • NC_REDIS_URL:外部 Redis 地址,worker 模式与缓存均依赖它。
  • NC_SITE_URL:对外公开 URL,用于邮件链接、Webhook、OAuth 回调。从源码(envs.ts)看,ncSiteUrlNC_SITE_URL(兼容回退 NC_PUBLIC_URL);mail.service.ts 中若该值未配置,系统无法生成安全链接并发出告警邮件,因此生产环境必须设置且与实际访问域名一致。
  • NC_SECURE_ATTACHMENTS:启用附件访问控制。源码中(envs.ts)它与 NC_ATTACHMENT_ACCESS_CONTROL_ENABLED 共同决定 isSecureAttachmentEnabled,并在 noco.module.ts 中据此启用相应安全模块;经由 Traefik 反代暴露公网时建议保持 true

nocodb/db.json:外部 PostgreSQL 连接

db.json 模板如下:

{
  "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 客户端;
  • host/port/user/password/database 换成你托管数据库的实际值;
  • ssl.rejectUnauthorized: true 表示严格校验数据库服务端证书——连接托管数据库(RDS 等)时通常直接可用;若你的私有 PG 使用自签或内部 CA 证书,需要另行处理 CA 信任问题(可参考仓库中同系列的 postgres-private-ca 示例)。

替换 CHANGE_ME_db_password 等占位符是本示例启动前的硬性要求。

水平扩容:外部服务 + 副本模式

README 最后给出的扩容方式:

deploy:
  mode: replicated
  replicas: 3

nocodb(worker 同理)的 replicas 调大即可水平扩容,前提是状态已全部外置:

  • 元数据/数据在外部 PostgreSQL,不依赖容器本地文件系统;
  • 缓存与任务队列在外部 Redis,跨副本共享;
  • 容器卷 nocodb_data 只承载共享的 db.json 配置(各副本读的是同一个只读模板文件)。

这正是「全外置依赖」架构相对本地 SQLite/内置 Redis 的核心优势:任意副本都可以接收请求与执行任务,扩缩容不需要数据迁移。

自检清单

启动前按顺序核对一遍(均来自本示例的 README 与配置文件要求):

  1. certs/cert.pem 为完整证书链、certs/key.pem 为对应私钥,且文件名与 certs.yml 一致;
  2. docker.envNC_REDIS_URLNC_SITE_URL 已改为真实值,NC_SITE_URL 的域名与 Traefik 路由 Host() 规则一致;
  3. nocodb/db.json 的数据库主机与凭据已替换,ssl.rejectUnauthorized 与你的 CA 信任策略匹配;
  4. docker-compose.yml 中的 nocodb.example.com 已替换为你的域名(出现在 traefik.http.routers.nocodb.rule 标签里);
  5. 执行 docker compose up -d 后,先访问 HTTP 确认 301 跳转到 HTTPS,再用 https://你的域名 验证证书链是否完整受信。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384