文档章节

Moving to Docker(三)基于Docker的Rails自动化部署

DockOne
 DockOne
发布于 2015/02/04 20:57
字数 1798
阅读 291
收藏 7

这是本系列的第三篇,整个系列介绍了我们公司如何把基础框架从PaaS移植到Docker上。

  • 第一篇:介绍了我们在接触Docker之前的探索过程。

  • 第二篇:介绍了如何搭建一个内网安全的私有registry。


在这最后一篇,我们用一个真实的例子来介绍如何自动化整个部署过程。

基本的Rails应用

我们来进入主题并启动一个基本的Rails应用。在这个Demo中,我将使用Ruby 2.20 和Rails 4.11。

在终端中运行:

$ rvm use 2.2.0
$ rails new  && cd docker-test



然后我们来创建个基本的控制器:

$ rails g controller welcome index


然后修改routes.rb文件,使这个项目的根路径指向我们刚创建的welcome#index方法:

root 'welcome#index'


在终端执行 rails s来启动服务并打开http://localhost:3000就可以看到首页了。我们不准备做其它功能了,这只是个例子来证明我们可以创建并在容器里部署且正常工作。

创建webserver

我们将用Unicorn做我们的webserver。添加gem 'unicorn'gem 'foreman'到Gemfile然后安装它们(在终端执行bundle install)。

Unicorn 需要在Rails应用启动前配置,我们需要在config文件夹中放入unicorn.rb配置文件。这里有个关于Unicorn的配置的例子。你可以直接复制粘贴这个Gist的内容。

然后我们添加包含下面内容的Procfile到项目的根目录下,这样我们就可以用foreman来启动项目了:

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


如果你用foreman start来运行应用,它也能正常工作并且可以在http://localhost:5000上进行访问。

创建Docker镜像

接下来我们来创建运行应用的镜像文件。在Rails项目的根目录创建个Dockerfile文件,并把下面的内容贴进去:

# Base image with ruby 2.2.0
FROM ruby:2.2.0

# Install required libraries and dependencies
RUN apt-get update && apt-get install -qy nodejs postgresql-client sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/*

# Set Rails version
ENV RAILS_VERSION 4.1.1

# Install Rails
RUN gem install rails --version "$RAILS_VERSION"

# Create directory from where the code will run 
RUN mkdir -p /usr/src/app  
WORKDIR /usr/src/app

# Make webserver reachable to the outside world
EXPOSE 3000

# Set ENV variables
ENV PORT=3000

# Start the web app
CMD ["foreman","start"]

# Install the necessary gems 
ADD Gemfile /usr/src/app/Gemfile  
ADD Gemfile.lock /usr/src/app/Gemfile.lock  
RUN bundle install --without development test

# Add rails project (from same dir as Dockerfile) to project directory
ADD ./ /usr/src/app

# Run rake tasks
RUN RAILS_ENV=production rake db:create db:migrate


利用上面提供的Dockerfile,通过下面的命令进行创建镜像:

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


如果一切顺利,在长长的日志的最后能看到如下信息:

Successfully built 82e48769506c  
$ docker images
REPOSITORY                                       TAG                 IMAGE ID            CREATED              VIRTUAL SIZE  
localhost:5000/your_username/docker-test         latest              82e48769506c        About a minute ago   884.2 MB


试试运行这个容器:

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


现在应该可以用通过Boot2Docker虚拟机的3000端口来访问这个应用了(例如我的:http://192.168.59.103:3000)。

用shell脚本来自动化

通过本系列的第二篇,你应该已经了解如何发布刚才新创建的镜像到私有registry并部署在一个机器上了,我们跳过这一部分直接讨论如何自动化这个过程。

接下来将定义3个shell脚本,然后用rake将他们捆绑在一起执行。

Clean

每次我们创建镜像并部署时,最后把所有的东西都清除掉。主要包括:

  • 停止(如果已经运行),然后重启Boot2Docker

  • 移除孤立的Docker镜像(那些没有标签并且不再使用的容器)


把如下的clean.sh脚本文件放在项目的根目录。

echo Restarting boot2docker...  
boot2docker down  
boot2docker up

echo Exporting Docker variables...  
sleep 1  
export DOCKER_HOST=tcp://192.168.59.103:2376  
export DOCKER_CERT_PATH=/Users/user/.boot2docker/certs/boot2docker-vm  
export DOCKER_TLS_VERIFY=1

sleep 1  
echo Removing orphaned images without tags...  
docker images | grep "<none>" | awk '{print $3}' | xargs docker rmi


然后给这个文件可执行权限:

$ chmod +x clean.sh


Build

创建的过程基本上是前面的步骤重做一遍。创建一个build.sh文件在项目的根目录,然后把下面内容贴进去:

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


记得给它可执行权限。

Deploy

最后,来创建如下内容的deploy.sh文件:

# Open SSH connection from boot2docker to private registry
boot2docker ssh "ssh -o 'StrictHostKeyChecking no' -i /Users/username/.ssh/id_boot2docker -N -L 5000:localhost:5000 root@your-registry.com &" &

# Wait to make sure the SSH tunnel is open before pushing...
echo Waiting 5 seconds before pushing image.

echo 5...  
sleep 1  
echo 4...  
sleep 1  
echo 3...  
sleep 1  
echo 2...  
sleep 1  
echo 1...  
sleep 1

# Push image onto remote registry / repo
echo Starting push!  
docker push localhost:5000/username/docker-test


如果你对这部分有疑惑,请确认你已经理解了本系列的第二篇文章的相关部分。

同样,记得给这个文件可执行权限。

用Rake将它们捆绑

将这3个脚本分开依次执行:

  1. clean

  2. build

  3. deploy/push


由于开发者都是比较懒的,所以这会是一个很大的帮助。

最后一步是将这些打包起来,也就是用rake将三部分合在一起。

为了简单,你可以将这一堆代码直接粘贴在项目根目录下的Rakefile后面。打开Rakefile文件,然后把这些粘贴在最后:

namespace :docker do  
desc "Remove docker container"
task :clean do
sh './clean.sh'
end

desc "Build Docker image"
task :build => [:clean] do
sh './build.sh'
end

desc "Deploy Docker image"
task :deploy => [:build] do
sh './deploy.sh'
end
end


尽管你可能不懂这些rake的语法(它们真的很棒!),但是我们这么做的目的很明显。我们在Docker命名空间下声明了3个任务。他们会创建以下3个任务:

  • rake docker:clean

  • rake docker:build

  • rake docker:deploy


Deploy是依赖build的,而build依赖于clean,于是每次我们从终端这么执行:

$ rake docker:deploy


这样,3个脚本就都会被按顺序执行。

测试

为了验证它们可以正常工作,你只需要在应用的代码中做一点小的改动,然后执行:

$ rake docker:deploy


然后来看看结果。一旦镜像被上传(初次执行会比较慢),你可以SSH进入你的生产环境服务器,然后pull(用SSH隧道)Docker镜像并执行它。这非常简单。

好吧,可能它花了一些功夫来让所有的组成部分工作起来,但是一旦完成,在Heroku上部署的工作就变得非常简单。

P.S. 跟以前一样,请让我知道你的想法。我不确定这是最好的或者是最快的或者是最安全的方案来用Docker部署应用,但是我们确实是这么用它的。

  1. 确认Boot2Docker启动并在运行。

  2. 如果你不知道你的Boot2Docker虚拟机的IP,执行boot2docker ip

  3. 如果你忘了如何用私有registry,请看本系列第二篇


本文转载自:http://dockerone.com/article/179

DockOne
粉丝 8
博文 12
码字总数 5880
作品 0
海淀
私信 提问
《Moving to Docker》系列之译者序

无论是大公司还是小型创业公司,都有遇到过系统环境选择、开发环境和生产环境不一致以及如何快速部署的问题,这些琐碎的问题不仅消耗了大量的时间去排查,而且还容易反复再犯。于是,开发者们...

DockOne
2015/02/05
570
2
Moving to Docker(二)搭建一个私有registry服务

这是迁移到Docker系列的第二篇,整个系列都是介绍我们公司是如何把基础设施从PaaS迁移到Docker的。 第一篇:我会介绍在使用Docker之前我们的处理过程。 第三篇:我会介绍如何自动化构建整个镜...

DockOne
2015/02/04
482
0
docker搭建gitlab+Jenkins持续集成环境

安装docker 此处省略 一.使用docker安装gitlab docker pull gitlab/gitlab-ce:latest 下载完成之后使用docker生成容器 docker run -dit -p 8443:443 -p 8080:80 -p 2222:22 -p 9090:9090 --n......

攀岩人生
2018/07/17
0
0
生活不止有苟且,还有N个免费DevOps开源工具

你喜欢免费的东西吗?获得开发者社区支持的自动化,开源的工具是大家梦寐以求的。这里列举了 N多款最棒的开源工具,可以帮助你很好的实行 DevOps。对的,生活不止有眼前的苟且,还有诗和远方的...

oschina
2016/04/04
7.1K
21
Moving to Docker(一)

【编者的话】本文是《Moving to Docker》系列的第一篇文章,这个系列的文章讲述了创业公司如何把基础服务迁移到Docker上,以及迁移过程中的经验教训。本文主要介绍了Touchware为什么要从Her...

DockOne
2015/01/31
2
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Cloud Sleuth 整合 feign 源码分析之修改span名称

org.springframework.cloud.sleuth.instrument.web.client.feign.TraceFeignClient 包括创建span一些参数 需求场景: 由于项目中有restful 风格的http请求,sleuth feign 的span名称默认是u...

xiaomin0322
28分钟前
4
0
Less 延伸

extend 是一个 Less 伪类,它通过使用 :extend 选择器在一个选择器中扩展其他选择器样式。 扩展语法 扩展可以是附加到选择器,也可以是集中放置在规则,看上去像是带有选择器参数的可选伪类,...

凌兮洛
28分钟前
4
0
RedHat 7.0系统中安装mysql 5.7.22

在安装之前,首先要查看的是,你的系统中有没有已经安装过的情况。键入rpm -qa|grep mysql,如果无任何显示,则表示没有安装过相关组件,如果有,则根据显示出来的名字,键入rpm -e --nodeps...

最菜最菜之小菜鸟
34分钟前
4
0
RPA:企业信息孤岛的“克星”

为了降本增效,近来世界范围内掀起一股流程优化的热潮,转型升级成为众多企业时刻挂在嘴边的热词。不过在企业数字化转型的过程中,信息孤岛的出现,往往成为了企业升级的绊脚石。 信息孤岛:...

UiBot
34分钟前
4
0
我的测试

我的测试

daiison
34分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部