Kestra 2.0.6 Docker Compose 部署指南

使用 Docker Compose 在 Ubuntu 22.04 上部署 Kestra 2.0.6:官方模板改造、v2.0.6 锁定版本、PostgreSQL 后端、JVM 内存限定、认证与持久化配置的完整实测记录。

KestraKestraUbuntuLinuxDockerDocker ComposeJava2026/10/17

Kestra 2.0.6 Docker Compose 部署指南

目标:使用官方 Docker Compose 模板在 Ubuntu 22.04 上完成 Kestra 2.0.6 单机部署(PostgreSQL 后端)与验证。已在 Ubuntu 22.04 实测通过。

本文档所有命令与回显均来自 Ubuntu 22.04 + Docker Compose 实机部署实测(Kestra 2.0.6,2026-10-17),可逐条复现。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(Docker 宿主机,12 vCPU)
  • Docker / Compose:Docker 29.8.0 / Docker Compose v5.5.1
  • Kestra 版本:2.0.6(镜像 kestra/kestra:v2.0.6,OSS,commitId b59444f)
  • Java 版本:Java 25.0.4.1+1-LTS(镜像内置)
  • 端口:8080(Web/API)、8081(管理口,可选暴露)
  • 数据目录:named volume kestra-data(容器内 /app/storage,任务产物与插件)与 postgres-data(PostgreSQL 元数据)
  • 配置路径:KESTRA_CONFIGURATION 内联 YAML(等价于单机安装的 application.yaml)
  • 部署形态:单机 Docker Compose(kestra server standalone + postgres:18)

二、方案说明与环境说明

2.1 部署形态

单机部署采用官方 Docker Compose 模板的常见形态:kestra(server standalone,单进程多角色)+ postgres(元数据库与消息队列)。与单二进制安装(内嵌 H2)相比,Compose 方案的优势是数据落在 PostgreSQL、天然支持升级重建与多实例扩展,且不占用宿主机 Java 环境。

2.2 实测环境与版本

项目实测值
操作系统Ubuntu 22.04.5 LTS
Docker29.8.0, build 88096ef
Docker Composev5.5.1
Kestra 镜像kestra/kestra:v2.0.6(磁盘占用约 3.63GB,压缩层 7.99GB)
PostgreSQL 镜像postgres:18(磁盘占用约 169MB,压缩层 650MB)
服务端口8080(Web/API)、8081(管理口,可选暴露)
JVM 堆-Xms256m -Xmx512m(通过 JAVA_OPTS 注入,实测生效)

💡 技术拓展:Kestra 官方镜像基于 Ubuntu,以非 root 用户运行是官方推荐的安全基线;但官方模板把 user: "root" 保留下来,是因为需要挂载 /var/run/docker.sock 供脚本任务拉起执行器(Task Runner)使用。若不使用脚本类任务,可去掉 root 与 socket 挂载。

2.3 版本锁定说明

官方模板默认写 image: kestra/kestra:latest 且 pull_policy: always,每次 up 都会重新拉取最新版,生产上容易造成"无感升级"。本文实测改为锁定 v2.0.6 并使用 pull_policy: if_not_present,保证部署版本可控。

三、准备 docker-compose.yml

3.1 编写编排文件

在部署目录(本文为 /opt/kestra-compose)创建 docker-compose.yml:

mkdir -p /opt/kestra-compose && cd /opt/kestra-compose
cat > docker-compose.yml <<'EOF'
volumes:
  postgres-data:
    driver: local
  kestra-data:
    driver: local

networks:
  kestra_net:

services:
  postgres:
    image: postgres:18
    volumes:
      - postgres-data:/var/lib/postgresql
    environment:
      POSTGRES_DB: kestra
      POSTGRES_USER: kestra
      POSTGRES_PASSWORD: k3str4
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
      interval: 10s
      timeout: 10s
      retries: 10
    networks:
      - kestra_net

  kestra:
    image: kestra/kestra:v2.0.6
    pull_policy: if_not_present
    restart: unless-stopped
    stop_grace_period: 6m
    user: "root"
    command: server standalone
    volumes:
      - kestra-data:/app/storage
      - /var/run/docker.sock:/var/run/docker.sock
      - /tmp/kestra-wd:/tmp/kestra-wd
    environment:
      KESTRA_CONFIGURATION: |
        datasources:
          postgres:
            url: jdbc:postgresql://postgres:5432/kestra
            driverClassName: org.postgresql.Driver
            username: kestra
            password: k3str4
        kestra:
          server:
            basic-auth:
              username: admin@example.com
              password: q1w2E3r4
          anonymous-usage-report:
            enabled: false
          repository:
            type: postgres
          storage:
            type: local
            local:
              base-path: "/app/storage"
          queue:
            type: postgres
          tasks:
            tmp-dir:
              path: /tmp/kestra-wd/tmp
          url: http://localhost:8080/
      JAVA_OPTS: -Xms256m -Xmx512m
    ports:
      - "8080:8080"
      - "8081:8081"
    depends_on:
      postgres:
        condition: service_started
    networks:
      - kestra_net
EOF

命令无输出。文件要点:

配置项说明
KESTRA_CONFIGURATIONKestra 的内联 YAML 配置(数据源、认证、存储、队列),等价于单机安装的 application.yaml
repository.type: postgresFlow/执行记录等元数据存 PostgreSQL
queue.type: postgres进程间消息队列用 PostgreSQL 实现(单机部署最简选择)
storage.type: local任务产物(Internal Storage)存 /app/storage(挂载到 named volume kestra-data)
JAVA_OPTS限定 JVM 堆 256~512MB,实测见 5.1
stop_grace_period: 6mKestra 停机优雅期默认 5 分钟,官方注释建议给足 6 分钟
8081管理口(health/metrics/prometheus),官方模板默认不暴露,本文实测暴露后验证见 5.3

💡 技术拓展:KESTRA_CONFIGURATION 中 basic-auth 的用户名必须是邮箱格式;密码规则实测为"至少 8 位 + 大写字母 + 数字",本文使用 q1w2E3r4。详细参数语义见《Kestra 2.0.6 配置参数详解》。

3.2 首次拉取与启动

docker compose up -d

回显(镜像已提前拉取过,故无 pull 行):

[+] Running 5/5
 ✔ Network kestra-compose_kestra_net      Created
 ✔ Container kestra-compose-postgres-1    Created
 ✔ Container kestra-compose-kestra-1      Created
 ✔ Container kestra-compose-postgres-1    Started
 ✔ Container kestra-compose-kestra-1      Started

⚠️ 排障实录:若官方模板原样的 depends_on: postgres: condition: service_healthy 在首次启动时 PostgreSQL 健康检查尚未就绪,会实测报错并中断启动:

dependency failed to start: container kestra-compose-postgres-1 is unhealthy

本机实测 12 vCPU 环境下首次拉起 postgres 后健康检查 10 秒间隔、最多重试 10 次,一般 30 秒内即可通过;再执行一次 docker compose up -d 即可继续。若希望跳过等待,可如本文改为 condition: service_started(Kestra 自带数据库连接重试)。

3.3 确认运行状态

docker compose ps

回显:

NAME                        IMAGE                  COMMAND                  SERVICE    CREATED          STATUS                    PORTS
kestra-compose-kestra-1     kestra/kestra:v2.0.6   "docker-entrypoint.s…"   kestra     45 seconds ago   Up 45 seconds             0.0.0.0:8080-8081->8080-8081/tcp, [::]:8080-8081->8080-8081/tcp
kestra-compose-postgres-1   postgres:18            "docker-entrypoint.s…"   postgres   45 seconds ago   Up 45 seconds (healthy)   5432/tcp

kestra 服务启动到 Web 可用约需 30~60 秒(首次启动含数据库表结构迁移)。

四、服务验证

4.1 HTTP 探活

wget -q -S -O /dev/null http://localhost:8080/ 2>&1 | grep HTTP
wget -q -S -O /dev/null http://localhost:8080/api/v1/configs 2>&1 | grep HTTP

回显(第一条命令重定向后还输出了 200 与 CSRF Cookie):

  HTTP/1.1 307 Temporary Redirect
  HTTP/1.1 200 OK
  Set-Cookie: csrfToken=.VvuZKFGwy6SbU79NeqY3hA; Path=/; HTTPOnly; SameSite=Strict
  HTTP/1.1 401 Unauthorized
  • 根路径 / 返回 307 重定向到 Web UI,随后 200 并下发 CSRF Cookie,属正常;
  • 未携带凭证访问 API 返回 401(已配置 basic-auth)。

4.2 携带凭证获取版本信息

AUTH=$(echo -n "admin@example.com:q1w2E3r4" | base64)
wget -q -O- --header="Authorization: Basic $AUTH" http://localhost:8080/api/v1/configs

回显(单行 JSON,已折行展示):

{"uuid":"3Pb9ubDo834p4aFBI66mY4","version":"2.0.6","edition":"OSS","commitId":"b59444f","chartDefaultDuration":"PT24H","flowTemplate":"","commitDate":"2026-10-13T13:52:17Z","isCustomDashboardsEnabled":false,"isAnonymousUsageEnabled":false,"isUiAnonymousUsageEnabled":true,"url":"http://localhost:8080...

version: 2.0.6、edition: OSS、commitId: b59444f、commitDate: 2026-10-13 与官方发布一致。浏览器访问 http://<服务器IP>:8080,用同一组邮箱密码登录即可进入 Web 控制台。

4.3 启动日志关键行

docker logs kestra-compose-kestra-1 2>&1 | grep -a "Machine information"

回显:

00:54:04.164 INFO  main         i.k.c.c.s.AbstractServerCommand Machine information: 12 available cpu(s), 512MB max memory, Java version 25.0.4.1+1-LTS

五、JVM 内存与管理口验证

5.1 验证 JAVA_OPTS 生效

docker top kestra-compose-kestra-1

回显(节选主进程行):

14572               root                0:27                java -XX:MaxRAMPercentage=50.0 -Xms256m -Xmx512m --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --sun-misc-unsafe-memory-access=allow --enable-native-access=ALL-UNNAMED -jar /app/kestra server standalone

-Xms256m -Xmx512m 已生效,日志 512MB max memory 与之一致。镜像内建了 -XX:MaxRAMPercentage=50.0 默认值,未配置 JAVA_OPTS 时会按限制内存的一半取堆——显式覆盖更可控。

5.2 镜像与磁盘占用

docker images | grep -E "kestra|postgres"

回显:

kestra/kestra:v2.0.6   bc2e8b5c639c       7.99GB         3.63GB   U
postgres:18            74935e722416        650MB         169MB   U

(列含义依次为:镜像、IMAGE ID、压缩层大小、本地解压大小、是否在用。Kestra 镜像解压后约 3.63GB,规划磁盘时需预留。)

5.3 管理口 8081

编排文件暴露了 8081 后:

wget -q -O- http://localhost:8081/health

回显:

{"name":"kestra","version":"2.0.6","edition":"OSS","commitId":"b59444f","startTime":"2026-10-17T01:24:06.572951473Z","endTime":null}
wget -q -S -O /dev/null http://localhost:8081/health 2>&1 | grep HTTP

回显:

  HTTP/1.1 200 Ok

⚠️ 注意:官方模板默认不暴露 8081(注释原话:management port 是 un-authenticated,会暴露敏感信息与操作,仅开发用途)。生产环境如无必要,建议保持注释状态。

六、数据持久化

6.1 存储目录

docker compose exec -T kestra ls -la /app/storage

回显:

total 16
drwxr-xr-x 3 root   root   4096 Oct 16 18:20 .
drwxr-xr-x 1 kestra kestra 4096 Oct 17 01:24 ..
drwxr-xr-x 2 root   root   4096 Oct 16 18:20 plugins

/app/storage 对应 named volume kestra-data,任务产物(Internal Storage)与运行期下载的插件都落在这里。PostgreSQL 数据在 volume postgres-data。

6.2 数据备份思路

  • PostgreSQL:docker compose exec postgres pg_dump -U kestra kestra > kestra-$(date +%F).sql;
  • 存储卷:备份 /var/lib/docker/volumes/kestra-compose_kestra-data/_data 目录,或用 docker run --rm -v ... tar 打包。

(二进制单机安装的备份实测见《Kestra 2.0.6 进阶实战与运维》。)

七、日常运维

7.1 日志与状态

docker compose logs -f --tail 100 kestra
docker compose ps
docker compose top

7.2 重启与完全重建

docker compose restart kestra

停止并销毁再重建(数据在 named volume 中,不受影响):

docker compose down
docker compose up -d

down 回显:

 Container kestra-compose-kestra-1 Stopping
 Container kestra-compose-kestra-1 Stopped
 Container kestra-compose-kestra-1 Removing
 Container kestra-compose-kestra-1 Removed
 Container kestra-compose-postgres-1 Stopping
 Container kestra-compose-postgres-1 Stopped
 Container kestra-compose-postgres-1 Removing
 Container kestra-compose-postgres-1 Removed
 Network kestra-compose_kestra_net Removing
 Network kestra-compose_kestra_net Removed

up -d 回显:

 Network kestra-compose_kestra_net      Created
 Container kestra-compose-postgres-1   Created
 Container kestra-compose-kestra-1     Created
 Container kestra-compose-postgres-1   Started
 Container kestra-compose-kestra-1     Started

⚠️ 排障实录:down 后 up -d,Kestra 首次可用仍需 30~60 秒;期间访问 8080 会连接失败,等待后重试即可,无需反复重启。

7.3 升级版本

修改 docker-compose.yml 中的 image 标签(如 kestra/kestra:v2.0.7)后:

docker compose pull kestra
docker compose up -d kestra

PostgreSQL 中的元数据由 Kestra 启动时自动完成迁移。从 2.0.5 到 2.0.6 的完整升级实测(含数据连续性验证、备份与回滚)见《Kestra 2.0.6 进阶实战与运维》。

八、常见问题(FAQ)

8.1 dependency failed to start: container ...-postgres-1 is unhealthy

见 3.2 排障实录:官方模板的 service_healthy 依赖在首次启动时可能因健康检查未就绪而中断。处理方式二选一:等待后重跑 docker compose up -d;或改用 condition: service_started(Kestra 会自行重试数据库连接)。

8.2 访问 401

已配置 basic-auth 后所有 API 都要求认证,浏览器登录或 -u admin@example.com:q1w2E3r4(curl)即可。若密码改弱(如全小写 q1w2e3r4),实测服务照常启动但认证返回 401——密码需满足"至少 8 位 + 大写字母 + 数字"。

8.3 脚本任务无法运行

Kestra 的脚本类任务(Shell 等)默认通过挂载的 /var/run/docker.sock 拉起执行器运行。确认编排文件中保留了该挂载与 user: "root";若两者都去掉,需改用 io.kestra.plugin.core.runner.Process 等不需要 socket 的 Task Runner。

8.4 端口冲突

宿主机 8080/8081 被占用时,修改 ports 左侧宿主端口即可(如 "18080:8080"),容器内端口不必改动。

九、参考链接