在 Dokploy 上自托管 InsForge:Compose 应用部署与源码级配置指南
【免费下载链接】InsForgeThe all-in-one, open-source backend platform for agentic coding. InsForge gives your coding agent database, auth, storage, compute, hosting, and AI gateway to ship full-stack apps end-to-end.项目地址: https://gitcode.com/GitHub_Trending/in/InsForge
本文是基于开源仓库 InsForge 的官方部署文档《Self-Host InsForge on Dokploy》整理而成的一站式技术指南。它面向已经拥有 Dokploy 实例的开发者,讲解如何以Compose 应用的形式把 InsForge 后端平台部署到自己的服务器上,并深入解释其中的关键设计(为什么 Postgres 要“现构建”而非直接拉取镜像、ENCRYPTION_KEY为什么必须单独设置、对象存储在该平台下的正确配置方式)。读完本文,你将掌握在 Dokploy 上完成 InsForge 创建、环境变量注入、域名路由、首次部署、后续更新与存储接入的完整实战流程。
注意:本指南部署的是InsForge 平台本身,而不是你基于 InsForge 构建的应用。如果你只是想把你写的应用上线,请使用 Sites 功能,而不是自托管整个平台。
前置条件
开始之前,你需要具备:
- 一台可用的Dokploy 实例(Dokploy 是开源的、可自托管在你自己服务器上的 PaaS 平台);
- 一个指向该服务器的域名或子域名,用于后续路由到 InsForge 服务。
仓库中对自托管的一般性硬件建议(见 docs/deployment/README.md)同样适用于 Dokploy:至少 2 GB 内存(推荐 4 GB)、至少 20 GB 存储(推荐 30 GB),并需支持 Docker 与 Docker Compose。
1. 创建 Compose 应用
在 Dokploy 控制台中进入Create → Compose,将本仓库作为 provider 连接,然后按以下字段配置:
| 字段 | 值 |
|---|---|
| Compose Path | deploy/dokploy/docker-compose.yml |
| Compose Type | Docker Compose |
仓库中对应的 Compose 文件位于 deploy/dokploy/docker-compose.yml,它定义了完整的服务栈:postgres、postgrest、insforge(后端 + Dashboard)与deno(函数运行时),以及 4 个本地命名卷(postgres-data、deno_cache、storage-data、insforge-logs)。所有服务均带security_opt: no-new-privileges:true加固,且没有任何服务把仓库目录 bind-mount 进容器——这是为 Dokploy“每次部署重新克隆code/”的行为专门设计的(详见第 7 节)。
2. 配置环境变量
在 Dokploy 的Environment标签页中设置以下变量。每个密钥建议用openssl rand -hex 32生成:
JWT_SECRET=<32+ characters> ENCRYPTION_KEY=<32+ characters, different from JWT_SECRET> POSTGRES_PASSWORD=<strong password> ROOT_ADMIN_USERNAME=admin ROOT_ADMIN_PASSWORD=<strong password>其中前三个变量在 Compose 文件里使用了 Docker 的强制插值语法(:?),缺失时服务会直接启动失败而不是带着占位符运行。例如 deploy/dokploy/docker-compose.yml 中 Postgres 的启动命令:
command: postgres -c config_file=/etc/postgresql/postgresql.conf \ -c cron.database_name='${POSTGRES_DB:-insforge}' \ -c app.encryption_key='${ENCRYPTION_KEY:?set ENCRYPTION_KEY in Dokploy Environment - openssl rand -hex 32, must differ from JWT_SECRET}'为什么 ENCRYPTION_KEY 必须单独设置?
文档明确指出:ENCRYPTION_KEY在未设置时会回退到JWT_SECRET,而事后轮换JWT_SECRET会让所有已加密存储的密钥永远无法解密。这一点在源码中有直接对应实现——backend/src/infra/security/encryption.manager.ts:
const key = process.env.ENCRYPTION_KEY || process.env.JWT_SECRET; if (!process.env.ENCRYPTION_KEY) { logger.warn( 'ENCRYPTION_KEY is not set — falling back to JWT_SECRET for secrets encryption. ' + 'WARNING: rotating JWT_SECRET without setting a dedicated ENCRYPTION_KEY will corrupt all stored secrets.' ); } this.encryptionKey = crypto.createHash('sha256').update(key).digest();密钥经过 SHA-256 哈希后用于AES-256-GCM加解密。一旦使用JWT_SECRET加密过 Secrets、OAuth 凭据等数据,再轮换JWT_SECRET就意味着解密密钥变化、数据全部不可读。因此务必在首次部署时就为ENCRYPTION_KEY设置一个与JWT_SECRET不同的独立值。
POSTGRES_PASSWORD 只在初始化时生效
Postgres 只有在**首次初始化数据簇(initdb)**时才会读取POSTGRES_PASSWORD。之后修改该变量并不会改变数据库密码,必须通过其他数据库运维手段处理。这也是为什么首部署前就要把密码定好的原因。
其余可选变量
除上述必填项外,Compose 文件还透传了大量可选变量(均带默认值),涵盖:对象存储(S3_*系列)、OAuth 登录(GOOGLE_CLIENT_ID、GITHUB_CLIENT_ID、DISCORD_*、MICROSOFT_*、LINKEDIN_*、X_*、APPLE_*)、支付(STRIPE_TEST_SECRET_KEY、STRIPE_LIVE_SECRET_KEY)、AI 网关(OPENROUTER_API_KEY)、Sites 部署(VERCEL_TOKEN等)、自定义计算(COMPUTE_*/ Docker provider)以及遥测开关(INSFORGE_TELEMETRY_DISABLED)。Compose 文件默认值只是占位符而非安全值,生产环境务必显式覆盖。
后端实际读取这些变量时有一套完整的解析逻辑(默认值、布尔解析、字节上限钳制),见 backend/src/infra/config/app.config.ts。几个与 Dokploy 部署直接相关的要点:
POSTGREST_MAX_SOCKETS默认50,与 Compose 中 PostgREST 的PGRST_DB_POOL默认值保持一致(deploy/dokploy/docker-compose.yml 有“Keep in sync”注释)——调大任一侧都会导致连接池排队位置发生偏移;S3_USE_PRESIGNED_URLS、S3_FORCE_PATH_STYLE都是非false即开的宽松解析(!== 'false'),而布尔开关(如COMPUTE_ISOLATE_NETWORK)则用parseEnvBool支持1/true/yes/on多种写法;COMPUTE_BUILD_MAX_CONTEXT默认64mb,COMPUTE_BUILD_UPLOAD_IDLE_TIMEOUT默认 30 秒(并被钳制在 32 位有符号整数上限内),这是对“一次只允许一个构建”的自我保护。
3. 添加域名
由于 Compose 文件没有向宿主机发布任何端口,整个栈只会停留在 Dokploy 的内部网络上,必须通过域名路由才能访问。在 Dokploy 的Domains中为insforge服务添加域名:
| 字段 | 值 |
|---|---|
| Service Name | insforge |
| Container Port | 7130 |
然后回到 Environment,把与该域名匹配的 URL 加进环境变量:
API_BASE_URL=https://insforge.example.com VITE_API_BASE_URL=https://insforge.example.com这两者必须与浏览器实际访问的 URL完全一致,否则 Dashboard 会向后端发出错误的 origin 请求。7130正是后端服务端口(PORT默认值,见 backend/src/infra/config/app.config.ts)。
只有insforge需要域名。Postgres、PostgREST 和 Deno 运行时都留在 Dokploy 内部网络中,通过服务名互通(POSTGRES_HOST: postgres、POSTGREST_BASE_URL: http://postgrest:3000、DENO_RUNTIME_URL: http://deno:7133)。
4. 部署
点击Deploy按钮。首次部署会执行两件事:
- 构建两个小镜像:基于仓库的 Postgres 镜像(deploy/Dockerfile.postgres)和 Deno 函数宿主镜像(deploy/Dockerfile.deno),其余镜像(
postgrest/postgrest:v12.2.12、ghcr.io/insforge/insforge-oss:latest)直接拉取; - 启动后自动运行后端的数据库迁移,无需手动干预。
部署完成后,打开你的域名,使用ROOT_ADMIN_USERNAME/ROOT_ADMIN_PASSWORD登录 Dashboard 即可。
服务依赖与健康检查
Compose 文件为服务间的启动顺序定义了明确的依赖关系:
postgrest等待postgres的service_healthy(pg_isready探测,5 秒间隔、5 次重试);insforge同时等待postgres健康与postgrest启动;deno依赖postgres与postgrest,并以wget --spider http://127.0.0.1:7133/health自检(60 秒启动宽限)。
值得注意的是 PostgREST 服务没有健康检查——注释说明其 amd64 官方镜像不携带 shell 与任何工具,容器内没有可用的探测程序,这也是部署时无需为其配置 healthcheck 的原因。
5. 更新
更新 InsForge 非常简单:
- 再次点击Deploy,或
- 开启Auto Deploy,在推送代码时自动重新部署。
每次部署都会从当前 commit 重新构建 Postgres 与 Deno 镜像,因此它们的配置和函数宿主始终跟随最新发布,不会出现“代码已更新、底层配置还是旧的”的漂移问题。
更新前请审查.env.example的 diff:如果新版本新增了环境变量,它不会自动出现在你的 Dokploy 环境里,需要手动补上。仓库根目录的 .env.example(位于仓库根)列出了所有受支持变量及其默认值,是核对的最佳依据。
6. 存储:Dokploy 场景下的对象存储
InsForge 的对象存储默认使用容器文件系统上的 Docker 卷(STORAGE_DIR=/insforge-storage对应storage-data卷),开箱即用。这也意味着 Dokploy 之外的 MinIO/RustFSoverlay 方式在这里不适用——Dokploy 只接受单个 Compose 文件,无法叠加docker-compose.minio.yml或docker-compose.rustfs.yml。
在 Dokploy 上接入 S3 存储有两种可行方案(详见 docs/deployment/self-host-storage.mdx):
- 使用外部 S3 兼容存储:在 Dokploy 的 Environment 中设置
S3_BUCKET、S3_ENDPOINT_URL、S3_ACCESS_KEY_ID、S3_SECRET_ACCESS_KEY、S3_FORCE_PATH_STYLE=true(私有端点还需S3_USE_PRESIGNED_URLS=false)。deploy/dokploy/docker-compose.yml已将这些变量完整透传给后端; - 在同一台 Dokploy 主机上自部署 MinIO/RustFS:把它们作为独立的 Dokploy 服务运行,再把上面的环境变量指向其内部地址。
相关默认值(与 backend/src/infra/config/app.config.ts 一致):S3_REGION默认us-east-2,S3_FORCE_PATH_STYLE默认true,S3_USE_PRESIGNED_URLS默认true,S3_MAX_OBJECT_SIZE_BYTES默认 5 GB,MAX_FILE_SIZE(REST 上传上限)默认 50 MB。
警告:把已有部署从本地存储切换到 S3 后端不会迁移旧对象。切换前请先迁移
storage-data卷中的内容(例如用mc mirror或aws s3 sync),或干脆清空重来。
7. 为什么 Postgres 要“现构建”而不是直接拉取?
这是本文档最有价值的设计决策之一。InsForge 的 Postgres 镜像需要仓库中的三个文件:
- deploy/docker-init/db/postgresql.conf:核心配置,其中
shared_preload_libraries = 'pg_cron,http,pgcrypto,insforge_pg_utils'加载了insforge_pg_utils扩展——托管表的行级安全(RLS)依赖它;同时还定义了insforge.internal_schemas(后端内部 schema 白名单)与insforge.policy_grant_role等参数; - deploy/docker-init/db/db-init.sql:初始化脚本,创建
anon/authenticated/project_admin三类角色,并注册事件触发器——任何新表创建或启用 RLS 时自动为project_admin生成默认策略; - deploy/docker-init/db/jwt.sql:JWT 相关初始化脚本。
对应构建方式见 deploy/Dockerfile.postgres,它以ghcr.io/insforge/postgres:v15.13.4为基础,把上述三个文件复制进镜像:
FROM ghcr.io/insforge/postgres:v15.13.4 COPY deploy/docker-init/db/postgresql.conf /etc/postgresql/postgresql.conf COPY deploy/docker-init/db/db-init.sql /docker-entrypoint-initdb.d/01-init.sql COPY deploy/docker-init/db/jwt.sql /docker-entrypoint-initdb.d/02-jwt.sql为什么不改用 bind mount 或预构建镜像?Dokploy每次部署都会重新克隆code/目录,指向仓库的 bind mount 会随之失效;其官方文档也要求用 UI 中创建的 File Mounts 并以../files/形式引用,这需要为每次安装做手动配置。而在部署时构建镜像则把当前文件直接烧进镜像:
- 无需任何额外配置,开箱即用;
- 配置永远不会落后于代码——对比预构建镜像,其内部文件被冻结在构建那一刻,历史上就曾因此导致自托管 RLS 失效(镜像里缺少
insforge_pg_utils的shared_preload_libraries)。
同样的理由也适用于 Deno 函数宿主:ghcr.io/insforge/deno-runtime预构建镜像在另一个仓库组装,其functions/副本不对应当前仓库的任何 commit,本仓库的修复永远到不了它。因此 deploy/Dockerfile.deno 直接从denoland/deno:alpine-2.0.6构建,把本仓库的functions/目录复制进去,并以非 root 的deno用户运行(注意基础镜像已自带 uid 1000 的 deno 用户,重复创建会导致构建失败)。
架构速览
综合 docs/deployment/README.md 与 Compose 文件,这套栈共 4 个主要服务:
| 服务 | 作用 | 端口 |
|---|---|---|
| PostgreSQL | 数据库,内置 RLS 扩展与初始化脚本 | 5432(内部) |
| PostgREST | 自动生成的 REST API,insforge后端通过 HTTP 连接池代理转发 | 3000(内部) |
| InsForge Backend | Node.js API 服务,同时托管 Dashboard | 7130(对外) |
| Deno Runtime | 无服务器函数运行时 | 7133(内部) |
结语
在 Dokploy 上部署 InsForge 的核心体验是“一个 Compose 文件搞定一切”:配置集中在 deploy/dokploy/docker-compose.yml,关键密钥通过 Dokploy 的 Environment 注入并以:?强制校验,Postgres 与 Deno 宿主由仓库现构建从而与代码保持同步,域名路由只需指向insforge:7130。只要遵守“ENCRYPTION_KEY独立设置、域名与API_BASE_URL一致、更新前审查.env.examplediff”三条纪律,后续的升级与运维都相当省心。若需在其他 PaaS 或裸机 VPS 上部署,可参考仓库中同目录下的 Coolify 指南 与 通用部署与安全指南。
【免费下载链接】InsForgeThe all-in-one, open-source backend platform for agentic coding. InsForge gives your coding agent database, auth, storage, compute, hosting, and AI gateway to ship full-stack apps end-to-end.项目地址: https://gitcode.com/GitHub_Trending/in/InsForge
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考