# 在 Dokku 上部署后端应用

本指南介绍如何在 Dokku (opens new window) 上部署平台后端。本文只涉及后端;希望在一台服务器上部署完整平台(前端、后端、数据库)时,推荐使用 生产环境部署 介绍的 Docker Compose 方式。

下文中的名称都是占位符,请替换成自己的:

占位符 含义
my-server Dokku 应用名
my_postgres PostgreSQL 服务名
my_redis Redis 服务名
api.example.com 后端域名
dokku.example.com Dokku 主机

注意

本页的步骤按平台源码和 Dokku 官方文档整理,尚未在 Dokku 主机上端到端验证。遇到问题请通过 社区 (opens new window) 联系我们。

# 部署步骤

# 1. 创建应用

ssh [email protected]
dokku apps:create my-server
1
2

# 2. 添加持久化存储

附件和应用种子数据需要放在宿主机目录中,容器重建后不会丢失:

mkdir -p /var/lib/dokku/data/storage/my-server/attachments
mkdir -p /var/lib/dokku/data/storage/my-server/data/csv
dokku storage:mount my-server /var/lib/dokku/data/storage/my-server/attachments:/app/attachments
dokku storage:mount my-server /var/lib/dokku/data/storage/my-server/data:/app/plugin/data
1
2
3
4

data 目录的结构与 platform 仓库中的 codes/data 相同(csv、groovy、attachments 等子目录),可以直接把 codes/data 的内容复制过去。

# 3. 添加 PostgreSQL 和 Redis

# 首次使用需安装插件
dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres
dokku plugin:install https://github.com/dokku/dokku-redis.git redis

# 创建 PostgreSQL(使用与 Docker Compose 相同的 pgvector 镜像)并关联到应用
dokku postgres:create my_postgres --image pgvector/pgvector --image-version 0.8.0-pg17
dokku postgres:link my_postgres my-server

# 创建 Redis 并关联到应用
dokku redis:create my_redis
dokku redis:link my_redis my-server
1
2
3
4
5
6
7
8
9
10
11

redis:link 注入的 REDIS_URL 后端可以直接使用。

postgres:link 注入的是 DATABASE_URL(postgres://... 格式),而后端读取的是 JDBC_DATABASE_URL、JDBC_DATABASE_USERNAME、JDBC_DATABASE_PASSWORD,需要在下一步设置。

# 导入初始数据库

这里与 Docker Compose 方式不同:Docker Compose 在数据库首次启动时会自动执行 platform 仓库 db-seed-data/initdb 下的脚本,恢复初始数据库 seed-data.dump 并创建 vector 扩展;Dokku 创建的是一个空数据库,这些脚本不会执行。

为了与 Docker Compose 的初始状态一致,请在首次部署后端之前,把 platform 仓库中的 db-seed-data/initdb/seed-data.dump 复制到 Dokku 主机,再导入:

# 在本机执行,把初始数据库复制到 Dokku 主机
scp db-seed-data/initdb/seed-data.dump [email protected]:/tmp/

# 在 Dokku 主机上执行
dokku postgres:import my_postgres < /tmp/seed-data.dump
1
2
3
4
5

postgres:import 用 pg_restore 导入 custom 格式的转储。seed-data.dump 中包含 CREATE EXTENSION vector,所以上面创建数据库时要使用 pgvector 镜像。当前后端版本没有用到向量功能,vector 扩展本身不是必需的。

# 4. 设置环境变量

先查看数据库的连接信息:

dokku postgres:info my_postgres --dsn
# 输出形如 postgres://postgres:<密码>@dokku-postgres-my_postgres:5432/my_postgres
1
2

按输出设置 JDBC 连接和其他变量:

dokku config:set --no-restart my-server \
  JDBC_DATABASE_URL=jdbc:postgresql://dokku-postgres-my_postgres:5432/my_postgres \
  JDBC_DATABASE_USERNAME=postgres \
  JDBC_DATABASE_PASSWORD=<密码> \
  JWT_SECRET=$(openssl rand -hex 32) \
  TENANT_ID=muyan \
  SEED_DATA_FOLDER=/app/plugin/data \
  GRAILS_ENV=development \
  PORT=8080
1
2
3
4
5
6
7
8
9
变量 说明
JDBC_DATABASE_URL 等 数据库连接。未设置时后端连接 localhost:5432/platform,在 Dokku 上会启动失败
JWT_SECRET 登录令牌签名密钥,至少 32 字节。不设置时使用公开的默认值,任何人都能伪造令牌
TENANT_ID 租户名。必须设置,并与导入的 seed-data.dump 中的租户(muyan)一致
SEED_DATA_FOLDER 应用种子数据目录,与第 2 步的挂载路径一致
GRAILS_ENV 保持 development,每次启动刷新平台模型定义和种子数据,与 Docker Compose 配置一致
PORT 后端监听端口,启动脚本以 -Dserver.port=$PORT 传给后端

提示

也可以设置 PAAS_VENDOR=heroku,让镜像的启动脚本自动把 DATABASE_URL 转换为 JDBC_DATABASE_*(启动脚本只对 heroku、fly、railway 做这个转换)。PAAS_VENDOR=dokku 不会触发转换。

后端日志中含有密钥

当前版本的后端镜像在启动时会先执行 printenv,把全部环境变量(包括 JDBC_DATABASE_PASSWORD、JWT_SECRET)写进日志,dokku logs my-server 能直接看到。这是当前版本的问题。不要把日志原样贴到公开渠道或工单里,并限制能登录 Dokku 主机、执行 dokku logs 的账号。怀疑日志外泄时,更换数据库密码和 JWT_SECRET。

# 5. 部署后端镜像

后端镜像 muyantech/backend 需要登录 Docker Hub 才能拉取。令牌是 platform 仓库中的 token.txt,先把它复制到 Dokku 主机(例如 scp token.txt [email protected]:/root/),再在 Dokku 主机上执行:

cat /root/token.txt | dokku registry:login --global --password-stdin docker.io muyantech
dokku git:from-image my-server muyantech/backend:1.0.0-beta18
1
2

镜像声明了 8080、10000、5005 三个端口,Dokku 默认会把它们全部对外开放。只保留 8080:

dokku ports:set my-server http:80:8080
1

# 6. 绑定域名并启用 HTTPS

dokku domains:add my-server api.example.com

dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
dokku letsencrypt:set my-server email [email protected]
dokku letsencrypt:enable my-server
1
2
3
4
5

启用 HTTPS 后再执行一次 dokku ports:report my-server,确认只有 8080 的 http/https 映射。

# 7. 升级

dokku git:from-image my-server muyantech/backend:<新版本>
1

升级前请阅读 升级说明,并先用 dokku postgres:export my_postgres > backup.dump 备份数据库。

# 附件存储配置

附件默认按以下两个系统配置(DynamicConfig)保存,请确认它们的值:

  1. attachment.storageEngine(附件存储引擎)为 LOCAL_FILE
  2. attachment.local.folder(本地引擎存储目录)为 /app/attachments,与第 2 步的挂载路径一致

否则附件可能上传失败,或者容器重建后已上传的附件丢失。也可以直接设置环境变量 ATTACHMENT_LOCAL_FOLDER=/app/attachments,它优先于系统配置。

# Dokku 命令参考

# 基本应用维护

  • 创建应用: dokku apps:create <应用名称>
  • 删除应用: dokku apps:destroy <应用名称>
  • 列出所有应用: dokku apps:list
  • 查看应用日志: dokku logs <应用名称>
  • 环境变量管理:
    • 查看应用的所有环境变量:dokku config:show <应用名称>
    • 为应用设置环境变量:dokku config:set <应用名称> KEY1=VALUE1 KEY2=VALUE2
    • 删除应用的环境变量:dokku config:unset <应用名称> KEY1 KEY2
  • 停止和启动应用:
    • 停止应用:dokku ps:stop <应用名称>
    • 启动应用:dokku ps:start <应用名称>
    • 重新启动应用:dokku ps:restart <应用名称>
  • 挂载磁盘:
    • 创建挂载点:dokku storage:mount <应用名称> <宿主机目录>:<容器内目录>
    • 查看挂载点:dokku storage:list <应用名称>
    • 使挂载生效:dokku ps:restart <应用名称>
    • 删除挂载点:dokku storage:unmount <应用名称> <宿主机目录>:<容器内目录>
  • 域名管理:
    • 设置域名:dokku domains:add <应用名称> your-subdomain.yourdomain.com
    • 查看域名:dokku domains:report <应用名称>
    • 删除域名:dokku domains:remove <应用名称> your-subdomain.yourdomain.com
  • 帮助: 任何命令加 --help 可查看用法。

# Redis 插件

  • 创建服务: dokku redis:create <服务名称>
  • 关联到应用: dokku redis:link <服务名称> <应用名称>
  • 删除服务: dokku redis:destroy <服务名称>
  • 查看服务信息: dokku redis:info <服务名称>

# PostgreSQL 插件

  • 创建服务: dokku postgres:create <服务名称>
  • 关联到应用: dokku postgres:link <服务名称> <应用名称>
  • 删除服务: dokku postgres:destroy <服务名称>
  • 查看服务信息: dokku postgres:info <服务名称>
  • 导出备份: dokku postgres:export <服务名称> > backup.dump

# Let's Encrypt 插件

  • 设置通知邮箱: dokku letsencrypt:set <应用名称> email [email protected]
  • 启用 Let's Encrypt: dokku letsencrypt:enable <应用名称>
  • 查看证书信息: dokku letsencrypt:list
  • 自动续期: dokku letsencrypt:cron-job --add
Last Updated: 2026/9/24 14:27:35