实战指南:用 run 命令在应用容器中执行临时命令)
Dokku 一次性任务One-off Tasks实战指南用 run 命令在应用容器中执行临时命令【免费下载链接】dokkuA docker-powered PaaS that helps you build and manage the lifecycle of applications项目地址: https://gitcode.com/GitHub_Trending/do/dokku本文围绕 Dokku 平台的一次性任务one-off tasks功能展开系统讲解run、run:detached、run:list、run:logs、run:stop等核心命令的用法与行为细节并结合 plugins/run 插件与 scheduler-docker-local 调度器的源码说明容器生命周期、TTL 回收、标签约束与日志查看的底层实现。读完本文你将掌握在 Dokku 应用中安全、可控地执行数据库迁移、脚本调试、Procfile 进程命令等一次性操作并能理解其超时回收与日志采集机制为排障与自动化运维打下基础。一、什么是一次性任务One-off Tasks在 PaaS 平台上应用进程通常由平台统一调度管理用户无法随意docker exec进入容器或直接以任意命令启动进程。Dokku 提供了一次性任务机制通过dokku run在与当前已部署应用完全相同的镜像基础上临时启动一个全新的容器来执行你指定的命令。Dokku 对一次性任务的支持由核心插件 plugins/runplugin.toml 中描述为 dokku core run plugin插件描述为 Run a one-off process inside a container实现容器启动的实际逻辑则由应用所使用的调度器承接例如 scheduler-docker-local/scheduler-run。一次性任务非常适合以下场景执行数据库迁移如rails db:migrate、alembic upgrade head进入应用环境调试、运行交互式控制台如rails console、python manage.py shell运行一次性脚本、数据修复任务复现线上环境问题验证依赖与配置。二、命令总览dokku run:help会输出 run 插件支持的完整命令列表见 plugins/run/help-functionsrun [-e|--env KEYVALUE] [--no-tty] [--ttl-seconds SECONDS] app cmd # 使用当前应用镜像启动新容器执行命令 run:detached [-e|-env KEYVALUE] [--force-tty] [--ttl-seconds SECONDS] app cmd # 以分离模式启动新容器执行命令 run:list [--format json|stdout] app # 列出某应用的全部 run 容器 run:logs app|--container CONTAINER [-h] [-t] [-n num] [-q] # 查看 run 容器日志 run:retire [app] # 回收所有超过活跃期限的 run/cron 容器 run:stop app|--container CONTAINER # 停止某应用的全部 run 容器或指定 run 容器其中run:retire在文档的命令列表中同样存在plugins/run/help-functions用于停止超过活跃期限的容器与 TTL 机制配套使用。三、运行一次性命令dokku run3.1 基本用法dokku run会根据当前已部署应用正在使用的镜像启动一个全新容器并在其中执行命令# 在 node-js-app 应用的 /app 目录下运行 ls -lah dokku run node-js-app ls -lah # 传入自定义环境变量 dokku run --env NODE_ENVdevelopment --env PATH/custom/path node-js-app npm run mytask[!IMPORTANT] 从 0.25.0 版本起一次性容器在进程退出后会被自动删除无需手动清理。在源码层面cmd-run会设置DOKKU_RM_CONTAINER1随后调用fn-run触发调度器的scheduler-run见 plugins/run/internal-functions。调度器收到该变量后会在 docker 启动参数中加入--rm见 scheduler-docker-local/scheduler-run从而保证容器在退出后被 Docker 守护进程自动移除。3.2 参数说明fn-run的参数解析逻辑见 plugins/run/internal-functions支持以下参数参数说明默认值-e, --env KEYVALUE注入自定义环境变量可多次使用无--no-tty禁用交互式 TTY0.25.0 新增尽可能启用 TTY--ttl-seconds SECONDS容器最大存活时间秒超时后被回收8640024 小时--cron-id关联 cron 任务标识供 cron 插件内部使用无--concurrency-policycron 并发策略allow/forbid/replace供 cron 插件内部使用allow源码还会对参数做合法性校验若--ttl-seconds为空则回退到86400若非数字则直接报错--ttl-seconds must be a positive integer若同时指定--force-tty与--no-tty则报错见 plugins/run/internal-functions。3.3 运行 Procfile 中定义的命令如果应用根目录的Procfile中定义了进程命令dokku run会先尝试把第一个参数当作 Procfile 中的 key 来解析# Procfile 内容示例 console: bundle exec racksh# 运行 my-app 的 Procfile 中 console 命令等价于 bundle exec racksh dokku run my-app console调度器源码中会先通过procfile-get-command触发器查询该 key 对应的命令命中后输出Found console in Procfile, running that command并为容器打上com.dokku.process-type标签见 scheduler-docker-local/scheduler-run。未命中时参数会被当作普通 shell 命令直接执行。3.4 指定容器标签可以为一次性容器附加自定义标签便于后续用 Docker 过滤与管理dokku --labelcom.example.test-labelvalue run node-js-app ls -lah[!WARNING] 为避免与 Dokku 内部机制冲突不要使用以com.dokku或org.label-schema开头的标签。调度器在构造 docker 参数时会从DOKKU_GLOBAL_FLAGS中筛选出--label开头的全局参数附加到容器上见 scheduler-docker-local/scheduler-run同时 Dokku 自身也会写入com.dokku.container-type、com.dokku.app-name、com.dokku.active-deadline-seconds等内部标签见 scheduler-docker-local/scheduler-run。3.5 禁用 TTY一次性容器默认在可行的情况下以交互模式TTY运行。若你的命令在无终端环境下执行如 CI 流水线可以显式禁用# 0.25.0 版本新增 dokku run --no-tty node-js-app ls -lah调度器在has_tty为真且未禁用 TTY 时会向 docker 参数追加--interactive --tty见 scheduler-docker-local/scheduler-run非交互模式下DOKKU_DISABLE_TTYtrue会使has_tty返回假从而去掉这两个标志。3.6 默认命令未指定命令时的行为dokku run app不带命令时会启动一个交互式 shell。调度器源码中当RUN_COMMAND为空时会依次读取应用级与全局的scheduler插件的shell属性若都未设置则回退到/bin/bash见 scheduler-docker-local/scheduler-run。该属性可通过属性命令进行配置。四、运行分离容器dokku run:detached从 0.25.0 版本起可以以分离模式启动一次性容器命令立即返回容器名称使用 k3s 调度器时返回 pod 名称# 立即返回新容器的名称如 node-js-app.run.XXXXX dokku run:detached node-js-app ls -lah分离容器默认不带 TTY进程退出后同样会被删除。若需要后台运行一个可交互会话可配合--force-ttydokku run:detached --force-tty node-js-app bash此时容器仍会在命令终止时退出但在运行期间可以被 attach。源码层面cmd-run-detached同时设置了DOKKU_DETACH_CONTAINER1与DOKKU_RM_CONTAINER1见 plugins/run/internal-functionsfn-run中还会在未显式指定--force-tty时自动设置DOKKU_DISABLE_TTYtrue。调度器在分离模式下不会附带--attach启动后直接通过docker container inspect --format {{.Name}}输出容器名见 scheduler-docker-local/scheduler-run。五、TTL 超时与自动回收机制5.1 默认存活期限与覆盖一次性容器默认最长运行24 小时86400 秒到达期限后会被回收。可以通过--ttl-seconds调整# 让容器最多运行 10 分钟 dokku run --ttl-seconds 600 node-js-app npm run mytaskTTL 值会以com.dokku.active-deadline-seconds标签写入容器见 scheduler-docker-local/scheduler-run。5.2 回收周期与精度说明超过运行时限的一次性容器每 5 分钟回收一次因此--ttl-seconds是近似值——你的应用实际运行时长可能比设定值多出最多 5 分钟。回收动作由scheduler-run-retire触发器执行对应run:retire命令。5.3 回收逻辑的源码实现在 docker-local 调度器中回收逻辑会按com.dokku.container-type标签筛选 run/cron 类型容器若指定了应用则叠加com.dokku.app-name过滤见 scheduler-docker-local/scheduler-run-retire读取每个容器的com.dokku.active-deadline-seconds标签换算成截止时间戳与容器启动时间比较见 scheduler-docker-local/scheduler-run-retire对超时容器依次执行container update --restartno、stop、kill、rm见 scheduler-docker-local/scheduler-run-retire并尊重应用配置的stop-timeout-seconds停止超时。此外fn-run内部还透传了DOKKU_CRON_ID与DOKKU_CONCURRENCY_POLICY供 cron 插件复用同一套 run 机制执行定时任务并支持forbid存在同 ID 运行中容器则退出与replace替换正在运行的容器两种并发策略见 scheduler-docker-local/scheduler-run。六、查看一次性容器日志dokku run:logs6.1 基本用法# 查看 node-js-app 所有 run 容器的日志 dokku run:logs node-js-app日志通过应用所使用调度器的 live tailing 能力拉取因此历史部署产生的日志通常不可用。若需要长期保留日志用于排障建议将日志持久化并外送可参考 docs/deployment/logs.md 中关于 Vector 日志集成的说明把日志转发到第三方平台。6.2 行为修饰参数run:logs支持以下修饰参数解析见 plugins/run/internal-functions参数说明默认值--container NAME只显示指定容器的日志容器名形如node-js-app.run.1234无取全部-n, --num NUM显示的行数100-t, --tail持续流式输出日志关闭-q, --quiet输出原始日志不带颜色、时间与名称关闭示例持续跟踪指定一次性进程的日志dokku run:logs -t --container node-js-app.run.1234当指定--container时源码会校验容器名必须含两个.、第二段必须为run且应用名需与容器名前缀一致否则报错见 plugins/run/internal-functions。七、列出一次性容器dokku run:list[!IMPORTANT] 从 0.25.0 版本起提供。dokku run:list node-js-app输出示例 node-js-app run containers NAMES COMMAND CREATED node-js-app.run.28689 /exec sleep 15 2 seconds ago说明COMMAND列显示的是 Docker 实际执行的命令可能与dokku run传入的原始命令不完全一致例如 herokuish 镜像会通过/exec包装执行。输出也支持 JSON 格式便于脚本化处理dokku run:list node-js-app --format json[ { name: node-js-app.run.28689, state: running, command: \/exec sleep 15\, created_at: 2022-08-03 05:47:44 0000 UTC } ]源码中stdout 格式通过docker container ls --all --no-trunc配合com.dokku.app-name与com.dokku.container-typerun两个标签过滤输出scheduler-docker-local/scheduler-run-listJSON 格式则通过jq将字段映射为name、state、command、created_at见 scheduler-docker-local/scheduler-run-list。另支持--quiet输出无表头的裸格式。八、停止一次性容器dokku run:stop[!IMPORTANT] 从 0.29.0 版本起提供。停止指定的一次性容器输出被停止容器的名称# 先启动一个运行 300 秒的容器输出类似 node-js-app.run.2313 dokku run node-js-app sleep 300 # 停止该容器 dokku run:stop --container node-js-app.run.2313输出node-js-app.run.2313也可以直接指定应用名停止该应用的全部 run 容器dokku run:stop node-js-app输出node-js-app.run.2313 node-js-app.run.574源码中停止指定容器时同样会校验容器名格式两个.、第二段为run停止顺序为docker container stop若失败再kill并遵循应用配置的stop-timeout-seconds若未指定容器则列出该应用全部container-typerun的容器逐一停止见 scheduler-docker-local/scheduler-run-stop。无容器时会输出No run containers exist。九、执行流程全景一次dokku run背后的调用链综合以上源码dokku run app cmd的完整调用链如下用户输入命令后进入 run 插件子命令入口 plugins/run/subcommands/defaultrun:detached则进入 plugins/run/subcommands/detachedcmd-run设置DOKKU_RM_CONTAINER1fn-run解析--env、--ttl-seconds、--no-tty等参数并做合法性校验fn-run通过get_app_scheduler获取应用调度器默认docker-local触发scheduler-run触发器见 plugins/run/internal-functionsdocker-local 调度器从当前运行镜像解析出发布镜像image-stage必须为release否则报错提示先成功部署应用见 scheduler-docker-local/scheduler-run组合docker-args-run、docker-args-process-run触发器返回的启动参数依次附加环境变量、DYNO环境变量、--rm、TTY 标志、TTL 标签、内部标签与全局--label参数解析 Procfile 命令或直接使用传入命令创建并启动容器前台模式附带--attach并等待退出码分离模式直接输出容器名最后触发scheduler-post-run触发器向事件系统上报执行结果见 scheduler-docker-local/scheduler-run。此外调度器还会根据镜像架构自动处理跨平台问题当镜像为linux/amd64而宿主机不是 amd64 架构时会自动附加--platformlinux/amd64以保证可执行见 scheduler-docker-local/scheduler-run。十、常见问题与最佳实践提示 Invalid image stage detected说明应用当前没有成功部署过或镜像非 release 阶段先执行一次正常部署再运行dokku run。长时间任务不要依赖默认 TTL默认 24 小时且每 5 分钟回收一次若任务可能超时请用--ttl-seconds显式设置并预留回收间隔余量。日志持久化run:logs依赖 live tailing历史日志不可回溯关键任务的日志应主动写入外部存储或日志平台。标签冲突规避自定义标签务必避开com.dokku、org.label-schema前缀以免干扰 Dokku 内部标签过滤逻辑。脚本化集成run:list --format json与run:logs --quiet适合在 CI/CD 与运维脚本中解析使用无命令执行时可通过scheduler插件的shell属性自定义默认 shell。权限与资源一次性容器与应用容器共用镜像与网络配置注意其中的环境变量与挂载可能带来的副作用执行前确认命令与参数无误。一次任务机制是 Dokku 日常运维中最常被使用的入口之一它既保持了镜像一致、环境一致的可复现性又通过 TTL、自动回收、命名规范app.run.id与标签体系保证了资源可控与可观测。理解其背后从 run 插件到调度器的完整链路能帮助你在迁移数据库、调试、批量脚本等场景中更稳妥地使用它。【免费下载链接】dokkuA docker-powered PaaS that helps you build and manage the lifecycle of applications项目地址: https://gitcode.com/GitHub_Trending/do/dokku创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考