资讯详情

Hello, world!

📅 2026/9/10 16:00:05 | 华诺云谱 👁 阅读
Hello, world!
Hello, world!【免费下载链接】dokkuA docker-powered PaaS that helps you build and manage the lifecycle of applications项目地址: https://gitcode.com/GitHub_Trending/do/dokkuThis is a sample website using the Heroku Multi Buildpack on Dokku. It uses the Python, Ruby, and Node buildpacks. The Node buildpack compiles SCSS stylesheets with dart-sass and manages frontend dependencies. The Ruby buildpack converts Markdown content to HTML with kramdown. And last but not least, the Python buildpack runs the Flask application.这段文本本身就是整个应用的内容数据源它从 Markdown 出发依次经过 Rubykramdown 转 HTML、Nodedart-sass 编译 SCSS、npm 管理 Bootstrap、PythonFlask 渲染与托管三层加工最终在浏览器呈现为一个带 Bootstrap 样式的静态页面。示例应用的配套说明 [tests/apps/multi/README.md](https://link.gitcode.com/i/0421483fd9783ac08dac8c16b6f2b0a9) 明确指出它的定位是 一个用于测试 heroku buildpack multi 与 herokuish 集成的示例应用使用 python、nodejs、ruby 三个 buildpack 创建一个简单的 Flask 应用。 也就是说这个目录不是普通站点而是 Dokku 项目中验证 **herokuish 多 Buildpack 集成能力**的测试用例——这正是本文要讲透的技术主题。 ## 二、应用目录结构与三条构建链路的对应关系 先看示例应用的完整文件树理解哪些文件喂给哪个 Buildpacktests/apps/multi/ ├── app.json # Dokku app.json健康检查healthchecks声明 ├── app.py # PythonFlask 应用入口 ├── Procfile # 进程声明web 进程用 gunicorn 启动 ├── requirements.txt # Python 依赖Flask、gunicorn ├── Gemfile # Ruby 依赖kramdownMarkdown → HTML ├── generate_content.rb # Ruby 脚本调用 kramdown 生成 content.html ├── package.json # Node 依赖bootstrap、sasspostinstall 串联构建 ├── package-lock.json # Node 依赖锁定 ├── Gemfile.lock # Ruby 依赖锁定 ├── content.md # Markdown 内容源本文主体 ├── check_deploy # 部署后冒烟验证脚本curl 检查页面关键字 ├── static/styles/main.scss # Nodedart-sass 编译的 SCSS 源文件 └── templates/index.html # Jinja2 模板include 编译后的 content.html三个 Buildpack 的分工在 [package.json](https://link.gitcode.com/i/f47c56c06c0ae8b32f23e8c54e6bb0a0) 的 postinstall 脚本中体现得最为直接 json scripts: { postinstall: bundle exec ruby generate_content.rb mkdir -p static/.tmp/styles npx sass static/styles/main.scss static/.tmp/styles/main.css --load-pathnode_modules }这条脚本是整条构建链路的总调度Ruby 链路bundle exec ruby generate_content.rb读取 content.md用 kramdown 转换为 templates/content.html生成逻辑见 generate_content.rb其核心就是Kramdown::Document.new(markdown).to_htmlNode 链路npx sass static/styles/main.scss static/.tmp/styles/main.css --load-pathnode_modules把 main.scss 编译成 CSS。注意这个 SCSS 文件第一行是import bootstrap/scss/bootstrap;--load-pathnode_modules正是为了让 dart-sass 能解析到 npm 安装的 Bootstrap 源码同时该文件还把主题色变量$primary覆盖为#428bcaPython 链路Node 的postinstall在 npm 依赖安装完成后触发而所有构建完成后Procfile 中的web: gunicorn app:app将启动 Flask。Flask 侧的托管逻辑在 app.py/路由通过render_template(index.html)渲染页面而 index.html 中用 Jinja2 语法{% include content.html %}引入 Ruby 生成的 HTML随后两个SharedDataMiddleware分别把/映射到static与static/.tmp目录从而让编译产物styles/main.css能通过/styles/main.css被浏览器访问——模板中正好引用了该路径link relstylesheet ... href/styles/main.css。依赖清单同样清晰地区分了三套语言生态requirements.txtFlask3.1.3、gunicorn26.2.0Gemfileruby 4.0.2、gem kramdown, ~ 2.5package.jsonbootstrap ^5.3.8、sass ^1.103.1并声明node 24.x.x、npm 11.x.x引擎约束。从源码结构看这就是一个仓库、三套语言、按序构建、共同交付的多 Buildpack 部署范式构建阶段由 Ruby 与 Node 完成内容生成和资源编译运行阶段由 Python 完成 HTTP 服务。三、如何在 Dokku 上配置多 Buildpack3.1 Buildpack 的两种声明方式在 Dokku 中herokuish 构建器按以下优先级确定应用使用哪些 BuildpackBUILDPACK_URL环境变量通过dokku config:set或仓库根目录的.env文件设置仓库根目录的.buildpacks文件每行一个 Buildpack 地址按行序执行buildpacks插件管理的命令。官方文档明确警告见 herokuish-buildpacks.md如果使用buildpacks插件务必清空BUILDPACK_URL并从.env中移除相应条目因为BUILDPACK_URL会始终覆盖.buildpacks文件或 buildpacks 插件。以本示例应用为例若要在自己的 Dokku 实例上复现最直接的方式是提交.buildpacks文件三行、按序执行https://github.com/heroku/heroku-buildpack-python.git https://github.com/heroku/heroku-buildpack-nodejs.git https://github.com/heroku/heroku-buildpack-ruby.git顺序即执行顺序官方 buildpack 管理文档指出Buildpacks are executed in order见 buildpack-management.md。在示例应用中Node 的postinstall依赖 Ruby 的 bundle 环境bundle exec ruby ...因此 Ruby 必须先于 Node 构建这一依赖关系决定了列表的排列次序。3.2 用 buildpacks 插件命令管理除了提交.buildpacks文件还可以用插件命令动态管理全部命令如下buildpacks:add [--index 1] app buildpack # 在指定位置插入 buildpack buildpacks:clear app # 清空全部 buildpack buildpacks:list app # 列出已设置的 buildpack buildpacks:remove app buildpack # 移除指定 buildpack buildpacks:report [app] [flag] # 输出 buildpack 报告 buildpacks:set [--index 1] app buildpack # 覆盖指定位置的 buildpack buildpacks:set --replace app buildpack [buildpack ...] # 原子替换整个 buildpack 列表逐条添加三个 Buildpackdokku apps:create multi-sample dokku buildpacks:add multi-sample https://github.com/heroku/heroku-buildpack-python.git dokku buildpacks:add multi-sample https://github.com/heroku/heroku-buildpack-nodejs.git dokku buildpacks:add multi-sample https://github.com/heroku/heroku-buildpack-ruby.git关键行为说明依据 buildpack-management.md当应用未指定任何 buildpack 时第一个被添加的 buildpack 将作为唯一执行者用于检测与编译buildpacks:add --index 2 app url会从 1 开始计数插入到第二个位置后续 buildpack 依次后移buildpacks:set默认覆盖第一个 buildpack当--index大于当前列表长度时新 buildpack 会被追加到末尾buildpacks:set --replace app url ...可以一次性原子替换整个有序列表适合工具链场景若任一 buildpack 非法原列表保持不变该参数不能与--index组合buildpacks:list只显示显式设置的 buildpack不包含自动检测出的 buildpackbuildpacks:remove支持按 URL 或按--index1 起始移除。3.3 强制指定构建器builder:set当仓库根目录存在Dockerfile时Dokku 会优先倾向 Dockerfile 部署可能干扰 Buildpack 流程。此时可以显式指定构建器为 herokuishdokku builder:set multi-sample selected herokuish按官方文档herokuish 构建器在以下两种情况下会被自动检测选中设置了BUILDPACK_URL环境变量或仓库根目录存在.buildpacks文件否则可通过builder:set ... selected herokuish显式指定详见 herokuish-buildpacks.md。3.4 部署与验证完成配置后推送部署git remote add dokku dokkuyour-server:multi-sample git push dokku master部署成功的验证有两层保障app.json 健康检查app.json 声明了一个startup类型的健康检查check-1请求路径/要求响应内容包含Heroku Multi Buildpack on Dokku即 content.md 第一行渲染进页面的文本{ healthchecks: { web: [ { content: Heroku Multi Buildpack on Dokku, name: check-1, path: /, type: startup } ] } }check_deploy 脚本check_deploy 用curl -s -S $1 | grep -q Heroku Multi Buildpack on Dokku冒烟检查——这正是 Dokku 测试套件在每次部署后对示例应用执行的断言。四、底层原理herokuish 构建器与检测机制4.1 构建器与构建链路Dokku 0.15.0 将构建能力拆分为多个 builder 插件目录见 plugins/builder-herokuish、plugins/builder-pack、plugins/builder-dockerfile 等。本示例走的是 herokuish 链路builder-detect完成检测builder-release在 plugins/builder-herokuish/builder-release 中触发镜像构建构建产物最终由 release-and-deploy 流程交付给 scheduler 调度运行。从仓库插件触发器的定义plugins/20_events 下的builder-detect、builder-release、builder-dokku-image等钩子可以推断检测阶段会依次评估BUILDPACK_URL、.buildpacks文件、buildpacks 插件配置命中任一条件即选择 herokuish随后 herokuish 会在一个基于gliderlabs/herokuish:latest的栈镜像内按序执行每个 Buildpack 的 detect 与 compile 阶段。这正是Python、Ruby、Node 三套工具链可以在同一次构建中共存的根本原因——每个 Buildpack 都在自己的环境中编译最终把产物合并进同一个应用镜像。4.2 栈镜像与平台限制默认栈镜像由 OS 包安装时拉取的gliderlabs/herokuish:latest决定可通过buildpacks:set-property app stack image按应用覆盖或用--global全局覆盖全局值优先级高于全局DOKKU_IMAGE环境变量修改会触发post-stack-set触发器。自 0.29.0 起herokuish 默认不在非 amd64 平台启用多数 Buildpack 不跨平台arm64 上要么因模拟 amd64 变慢、要么直接构建失败。如需强制启用用builder-herokuish:set app allowed truecomputed-allowed的取值顺序为应用级值 → 全局值 → 平台内置默认amd64 为true否则为false。查询用builder-herokuish:report [app] [--builder-herokuish-allowed]。4.3 常见坑与对策官方文档herokuish-buildpacks.md给出了与本示例同类的多语言应用可能遇到的典型问题从 Dockerfile 部署切换过来先dokku ports:clear app否则端口配置残留会导致 Buildpack 部署失败curl 下载依赖超时构建期 Buildpack 通过 curl 拉依赖可能超时报gzip: stdin: unexpected end of file可调大超时dokku config:set --global CURL_TIMEOUT1200 dokku config:set --global CURL_CONNECT_TIMEOUT180【免费下载链接】dokkuA docker-powered PaaS that helps you build and manage the lifecycle of applications项目地址: https://gitcode.com/GitHub_Trending/do/dokku创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。