
在 Heroku 上部署 Docker 容器 (以 One-API 为例)
近期,我发现之前使用 Vercel 搭建的 RSSHub 服务版本过时,尝试更新部署新版本时却在 Vercel 上持续遇到故障。在寻找替代方案的过程中,我了解到可以通过 GitHub 学生包等途径获取 Heroku 的使用额度(例如当时发现的 $312 赠金),并且 Heroku 平台原生支持运行 Docker 容器,这为部署各种应用提供了极大的灵活性。
Heroku 部署方式概览
Heroku 主要提供三种部署应用的方式:
- Heroku Git: 通过 Heroku 提供的 Git 远程仓库部署代码,Heroku 使用 Buildpacks 自动构建和运行应用。
- GitHub: 直接连接 GitHub 仓库,实现自动或手动部署。
- Container Registry: 将构建好的 Docker 镜像推送到 Heroku 的容器注册表进行部署。
本文将重点介绍第三种方法:使用 Heroku Container Registry 部署预先构建好的 Docker 镜像。
下面,我将以部署 One-API
(一个 API 管理和分发项目)为例,详细说明在 Heroku 上部署 Docker 容器的具体步骤。
环境与准备
- 操作系统: 示例使用 Ubuntu 22.04,但步骤适用于其他支持 Docker 和 Heroku CLI 的系统。
- 必要工具:
- Docker (已安装并运行)
- Heroku CLI (Heroku 命令行工具)
- Heroku 账号: 你需要一个 Heroku 注册账号。
- 待部署的 Docker 镜像:
- 你需要一个已经构建好的、可以在本地成功运行的 Docker 镜像。本文以本地已有的
calciumion/new-api:latest
镜像为例。 - 关键要求: 该 Docker 镜像启动的应用 必须 监听由 Heroku 运行时动态注入的
$PORT
环境变量所指定的端口号。大多数 Web 框架能自动识别或可以配置为使用此环境变量。同时,建议在 Dockerfile 中使用EXPOSE $PORT
或具体的端口号(如果你的应用固定监听某个端口,但监听$PORT
是最推荐的做法)。
- 你需要一个已经构建好的、可以在本地成功运行的 Docker 镜像。本文以本地已有的
我的本地 Ubuntu 环境,可以看到 calciumion/new-api
镜像已存在:
部署步骤
1. 安装 Heroku CLI
Heroku CLI 是与 Heroku 平台交互的主要工具。
对于 Debian/Ubuntu 系统,可以使用官方脚本安装:
1
curl [https://cli-assets.heroku.com/install-ubuntu.sh](https://cli-assets.heroku.com/install-ubuntu.sh) | sh
对于 macOS, Windows 或其他 Linux 发行版,请参考 Heroku 官方文档 进行安装。
安装完成后,可以通过 heroku --version
验证安装。
2. 登录 Heroku
在终端执行登录命令,它会打开浏览器引导你完成登录授权过程:
1 | heroku login |
3. 创建 Heroku 应用
在部署之前,你需要在 Heroku 上创建一个应用。应用名称 (<your-app-name>
) 在 Heroku 全平台上必须是唯一的。
1 | # 将 <your-app-name> 替换为你想要的应用名称,例如 newapi0819 |
成功后,Heroku 会返回应用的访问 URL 和 Git 仓库 URL。
4. 设置应用堆栈为 Container (关键步骤)
默认情况下,Heroku 应用使用 Buildpack 堆栈来构建源代码。因为我们要部署的是预构建的 Docker 镜像,所以需要将应用的堆栈(Stack)明确设置为 container
。
1 | # 将 newapi0819 替换为你的应用名称 |
5. 登录 Heroku Container Registry
你需要登录到 Heroku 自己的 Docker 镜像注册表,才能推送镜像:
1 | heroku container:login |
6. 标记 (Tag) 本地 Docker 镜像
将你本地准备好的 Docker 镜像,按照 Heroku Container Registry 的格式进行标记。格式为:registry.heroku.com/<app-name>/<process-type>
。
<app-name>
: 你在第 3 步创建的应用名称 (例如newapi0819
)。<process-type>
: 定义这个容器扮演的角色。对于处理 Web 请求的应用,通常使用web
。其他类型如worker
用于后台任务。
假设你的本地镜像是 calciumion/new-api:latest
,应用名为 newapi0819
,进程类型为 web
:
1 | docker tag calciumion/new-api:latest [registry.heroku.com/newapi0819/web](https://registry.heroku.com/newapi0819/web) |
7. 推送 Docker 镜像到 Heroku
将标记好的镜像推送到 Heroku Container Registry:
1 | docker push [registry.heroku.com/newapi0819/web](https://registry.heroku.com/newapi0819/web) |
推送过程可能需要一些时间,具体取决于镜像大小和网络速度。
8. 发布 (Release) 镜像到应用
推送完成后,你需要执行 release
命令,告诉 Heroku 使用这个新推送的镜像来运行你的应用。
1 | # 发布 web 进程类型的容器 |
Heroku 会拉取镜像并在新的 Dyno(Heroku 的容器实例)中启动它。
9. 验证部署
部署完成后,可以通过以下方式验证:
查看实时日志:
1
heroku logs --tail -a newapi0819
观察是否有错误信息,确认应用是否成功启动并监听在
$PORT
上。打开应用 URL:
1
heroku open -a newapi0819
或者直接在浏览器中访问
https://newapi0819.herokuapp.com
(将newapi0819
替换为你的应用名)。
注意事项
- 环境变量: 如果你的 Docker 应用依赖环境变量(例如数据库连接字符串、API 密钥等),你需要在 Heroku 应用的设置 (Settings) -> “Config Vars” 部分进行配置。Heroku 会将这些 Config Vars 作为环境变量注入到运行的容器中。不要 将敏感信息硬编码在 Docker 镜像里。
- 短暂文件系统与数据持久化: Heroku 的 Dyno 文件系统是 短暂的 (Ephemeral)。这意味着每次 Dyno 重启(至少每天发生一次,或在部署、配置更改、平台维护、崩溃后),所有写入容器本地文件系统的更改都会丢失。如果你的应用需要持久化存储数据(如数据库内容、用户上传的文件等),必须 使用 Heroku Add-ons(例如 Heroku Postgres, Heroku Redis)或外部的云数据库/云存储服务(如 AWS RDS, AWS S3)。
- 监听
$PORT
: 再次强调,部署到 Heroku 的 Web 应用 必须 监听$PORT
环境变量指定的端口。Heroku 的路由层会将外部的 80/443 端口请求路由到你的容器内部监听的这个动态端口上。 - Heroku 赠金/额度: 如果你通过 GitHub 学生包或其他途径获得了 Heroku 额度,请注意其使用规则。例如,文中提到的 $13/月使用上限和 24 个月有效期。Heroku 的定价和优惠政策可能会变化,请参考 Heroku 官方文档获取最新信息。免费套餐通常也有一定的限制(如 Dyno 休眠机制)。
通过以上步骤,你应该能够成功地将你的 Docker 容器化应用部署到 Heroku 平台上。
- Title: 在 Heroku 上部署 Docker 容器 (以 One-API 为例)
- Author: 凡
- Created at : 2024-07-21 13:29:03
- Updated at : 2025-04-29 19:17:00
- Link: https://xblog.aptzone.cc/2024/07/21/在Heroku上部署Docker容器/
- License: All Rights Reserved © 凡