最近,我们致力于将一个传统的Rails应用程序部署到Heroku。Heroku支持的最低Ruby版本是2.7.6。运行旧版本的应用程序必须在部署前进行升级。值得庆幸的是,这个问题可以通过将应用部署为一个容器来解决。这篇文章解释了如何将一个应用程序容器化并部署到Heroku。
Dockerize应用程序
首先,我们需要为应用程序创建一个简单的Docker文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FROM ruby:2.4.2
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
EXPOSE 3000
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
不同的Ruby应用会有不同的Dockerfile。这个例子是为运行Ruby 2.4.2的简单的Rails 4应用程序建立的,但它可以作为一个起点,为不同的使用情况进行修改。
有了这个Dockerfile,该应用就可以在本地运行:
1
docker build -t myapp . && docker run -it myapp
在运行该应用时,可能会出现错误。这在对传统应用进行容器化时很常见,通常有一些需要修复或升级的依赖项。
添加Heroku.yaml
一旦应用程序在本地运行,我们需要添加一个 heroku.yaml文件:
1
2
3
4
5
6
7
build:
docker:
web: Dockerfile
config:
RAILS_ENV: production
run:
web: bundle exec rails server -b 0.0.0.0 -p $PORT
这告诉Heroku使用Dockerfile构建一个镜像,然后指定一个运行容器的过程。
请注意,网络进程运行在一个由下列文件指定的端口上 $PORT.这是必须的,因为Heroku在每次部署时都会动态地分配一个端口,网络进程必须听从这个端口。
构建应用程序和部署
在这一点上,我们可以通过用户界面或CLI建立一个新的Heroku应用。默认情况下,Heroku应用程序不运行容器构建。我们必须通过Heroku CLI改变堆栈:
1
heroku stack:set container
代码库和Heroku应用现在已经准备好了,我们可以推送到Heroku,开始构建和部署。
切换到DB上并复制环境变量
应用程序已经成功部署,并在Heroku上运行,但我们缺少重要的组件,如数据库。这里有两个选择:
- 将附加组件从传统的Heroku应用程序迁移到新的应用程序上
- 从传统应用中复制配置变量到新应用,重新使用传统应用的附加组件
选项一比较干净,可以让我们完全停用旧的应用程序。选项二更快。
我们建议从选项二开始,以验证新应用程序是否正常工作。然后逐步将附加组件迁移过去。