阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

自动化部署基于 Docker 的 Rails 应用

139次阅读
没有评论

共计 4702 个字符,预计需要花费 12 分钟才能阅读完成。

自动化部署基于 Docker 的 Rails 应用

[TL;DR] 这是系列文章的第三篇,讲述了我的公司是如何将基础设施从 PaaS 移植到 Docker 上的。

  • 第一部分: 谈论了我接触 Docker 之前的经历;
  • 第二部分: 一步步搭建一个安全而又私有的 registry。

在系列文章的最后一篇里,我们将用一个实例来学习如何自动化整个部署过程。

 

基本的 Rails 应用程序

现在让我们启动一个基本的 Rails 应用。为了更好的展示,我使用 Ruby 2.2.0 和 Rails 4.1.1

在终端运行:

  1. $ rvm use2.2.0
  2. $ rails new&& cd docker-test

创建一个基本的控制器:

  1. $ rails g controller welcome index

……,然后编辑 routes.rb,以便让该项目的根指向我们新创建的 welcome#index 方法:

  1. root 'welcome#index'

在终端运行 rails s,然后打开浏览器,登录 http://localhost:3000,你会进入到索引界面当中。我们不准备给应用加上多么神奇的东西,这只是一个基础的实例,当我们将要创建并部署容器的时候,用它来验证一切是否运行正常。

 

安装 webserver

我们打算使用 Unicorn 当做我们的 webserver。在 Gemfile 中添加 gem 'unicorn'gem 'foreman'然后将它 bundle 起来 (运行 bundle install 命令)。

启动 Rails 应用时,需要先配置好 Unicorn,所以我们将一个 unicorn.rb 文件放在 config 目录下。这里有一个 Unicorn 配置文件的例子,你可以直接复制粘贴 Gist 的内容。

接下来,在项目的根目录下添加一个 Procfile,以便可以使用 foreman 启动应用,内容为下:

  1. web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb

现在运行 foreman start 命令启动应用,一切都将正常运行,并且你将能够在 http://localhost:5000 上看到一个正在运行的应用。

 

构建一个 Docker 镜像

现在我们构建一个镜像来运行我们的应用。在这个 Rails 项目的根目录下,创建一个名为 Dockerfile 的文件,然后粘贴进以下内容:

  1. # 基于镜像 ruby 2.2.0
  2. FROM ruby:2.2.0
  3. # 安装所需的库和依赖
  4. RUN apt-get update && apt-get install -qy nodejs postgresql-client sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/*
  5. # 设置 Rails 版本
  6. ENV RAILS_VERSION 4.1.1
  7. # 安装 Rails
  8. RUN gem install rails --version "$RAILS_VERSION"
  9. # 创建代码所运行的目录
  10. RUN mkdir -p /usr/src/app
  11. WORKDIR /usr/src/app
  12. # 使 webserver 可以在容器外面访问
  13. EXPOSE 3000
  14. # 设置环境变量
  15. ENV PORT=3000
  16. # 启动 web 应用
  17. CMD ["foreman","start"]
  18. # 安装所需的 gems
  19. ADD Gemfile /usr/src/app/Gemfile
  20. ADD Gemfile.lock /usr/src/app/Gemfile.lock
  21. RUN bundle install --without development test
  22. # 将 rails 项目(和 Dockerfile 同一个目录)添加到项目目录
  23. ADD ./ /usr/src/app
  24. # 运行 rake 任务
  25. RUN RAILS_ENV=production rake db:create db:migrate

使用上述 Dockerfile,执行下列命令创建一个镜像(确保 boot2docker 已经启动并在运行当中):

  1. $ docker build -t localhost:5000/your_username/docker-test .

然后,如果一切正常,长长的日志输出的最后一行应该类似于:

  1. Successfully built 82e48769506c
  2. $ docker images
  3. REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
  4. localhost:5000/your_username/docker-test latest 82e48769506cAbout a minute ago 884.2 MB

让我们运行一下容器试试!

  1. $ docker run -d -p 3000:3000--name docker-test localhost:5000/your_username/docker-test

通过你的 boot2docker 虚拟机的 3000 号端口(我的是 http://192.168.59.103:3000),你可以观察你的 Rails 应用。(如果不清楚你的 boot2docker 虚拟地址,输入 $ boot2docker ip 命令查看。)

 

使用 shell 脚本进行自动化部署

前面的文章(指文章 1 和文章 2)已经告诉了你如何将新创建的镜像推送到私有 registry 中,并将其部署在服务器上,所以我们跳过这一部分直接开始自动化进程。

我们将要定义 3 个 shell 脚本,然后最后使用 rake 将它们捆绑在一起。

 

清除

每当我们创建镜像的时候,

  • 停止并重启 boot2docker;
  • 去除 Docker 孤儿镜像(那些没有标签,并且不再被容器所使用的镜像们)。

在你的工程根目录下的 clean.sh 文件中输入下列命令。

  1. echo Restarting boot2docker...
  2. boot2docker down
  3. boot2docker up
  4. echo ExportingDocker variables...
  5. sleep 1
  6. export DOCKER_HOST=tcp://192.168.59.103:2376
  7. export DOCKER_CERT_PATH=/Users/user/.boot2docker/certs/boot2docker-vm
  8. export DOCKER_TLS_VERIFY=1
  9. sleep 1
  10. echo Removing orphaned images without tags...
  11. docker images | grep "<none>"| awk '{print $3}'| xargs docker rmi

给脚本加上执行权限:

  1. $ chmod +x clean.sh

 

构建

构建的过程基本上和之前我们所做的(docker build)内容相似。在工程的根目录下创建一个 build.sh 脚本,填写如下内容:

  1. docker build -t localhost:5000/your_username/docker-test .

记得给脚本执行权限。

 

部署

最后,创建一个 deploy.sh 脚本,在里面填进如下内容:

  1. # 打开 boot2docker 到私有注册库的 SSH 连接
  2. boot2docker ssh "ssh -o'StrictHostKeyChecking no'-i /Users/username/.ssh/id_boot2docker -N -L 5000:localhost:5000 root@your-registry.com &"&
  3. # 在推送前先确认该 SSH 通道是开放的。
  4. echo Waiting5 seconds before pushing image.
  5. echo 5...
  6. sleep 1
  7. echo 4...
  8. sleep 1
  9. echo 3...
  10. sleep 1
  11. echo 2...
  12. sleep 1
  13. echo 1...
  14. sleep 1
  15. # Push image onto remote registry / repo
  16. echo Starting push!
  17. docker push localhost:5000/username/docker-test

如果你不理解这其中的含义,请先仔细阅读这部分第二部分。

给脚本加上执行权限。

 

使用 rake 将以上所有绑定

现在的情况是,每次你想要部署你的应用时,你都需要单独运行这三个脚本。

  1. clean
  2. build
  3. deploy / push

这一点都不费工夫,可是事实上开发者比你想象的要懒得多!那么咱们就索性再懒一点!

我们最后再把工作好好整理一番,我们现在要将三个脚本通过 rake 捆绑在一起。

为了更简单一点,你可以在工程根目录下已经存在的 Rakefile 中添加几行代码,打开 Rakefile 文件,把下列内容粘贴进去。

  1. namespace:docker do
  2. desc "Remove docker container"
  3. task :clean do
  4. sh './clean.sh'
  5. end
  6. desc "Build Docker image"
  7. task :build =>[:clean]do
  8. sh './build.sh'
  9. end
  10. desc "Deploy Docker image"
  11. task :deploy =>[:build]do
  12. sh './deploy.sh'
  13. end
  14. end

即使你不清楚 rake 的语法(其实你真应该去了解一下,这玩意太酷了!),上面的内容也是很显然的吧。我们在一个命名空间(docker)里声明了三个任务。

三个任务是:

  • rake docker:clean
  • rake docker:build
  • rake docker:deploy

Deploy 独立于 build,build 独立于 clean。所以每次我们输入命令运行的时候。

  1. $ rake docker:deploy

所有的脚本都会按照顺序执行。

 

测试

现在我们来看看是否一切正常,你只需要在 app 的代码里做一个小改动:

  1. $ rake docker:deploy

接下来就是见证奇迹的时刻了。一旦镜像文件被上传(第一次可能花费较长的时间),你就可以 ssh 登录产品服务器,并且(通过 SSH 管道)把 docker 镜像拉取到服务器并运行了。多么简单!

也许你需要一段时间来习惯,但是一旦成功,它几乎与用 Heroku 部署一样简单。

备注:像往常一样,请让我了解到你的意见。我不敢保证这种方法是最好,最快,或者最安全的 Docker 开发的方法,但是这东西对我们确实奏效。

CentOS 6/ 7 系列安装 Docker http://www.linuxidc.com/Linux/2014-07/104768.htm 

Docker 的搭建 Gitlab CI 全过程详解 http://www.linuxidc.com/Linux/2013-12/93537.htm 

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm 

在 Docker 中使用 MySQL http://www.linuxidc.com/Linux/2014-01/95354.htm

在 Ubuntu Trusty 14.04 (LTS) (64-bit)安装 Docker http://www.linuxidc.com/Linux/2014-10/108184.htm 

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm 

Ubuntu 14.04 安装 Docker  http://www.linuxidc.com/linux/2014-08/105656.htm 

阿里云 CentOS 6.5 模板上安装 Docker http://www.linuxidc.com/Linux/2014-11/109107.htm 

Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-05/117190.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计4702字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中