在Docker中自动化部署Ruby on Rails的教程

基本的Rails应用程序

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

在终端运行:

  $ 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。在Gemfile中添加 gem 'unicorn'和 gem 'foreman'然后将它bundle起来(运行 bundle install命令)。

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

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

代码如下:

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

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

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

代码如下:

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

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

 $ 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),你可以观察你的Rails应用。(如果不清楚你的boot2docker虚拟地址,输入$ boot2docker ip命令查看。)
使用shell脚本进行自动化部署

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

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

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

  • 停止并重启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

构建

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

代码如下:

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

记得给脚本执行权限。
部署

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

代码如下:

# 打开 boot2docker 到私有注册库的 SSH 连接
    boot2docker ssh "ssh -o 'StrictHostKeyChecking no' -i /Users/username/.ssh/id_boot2docker -N -L 5000:localhost:5000 root@your-registry.com &" &
    # 在推送前先确认该 SSH 通道是开放的。
    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将以上所有绑定

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

  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)里声明了三个任务。

三个任务是:

  1. rake docker:clean
  2. rake docker:build
  3. rake docker:deploy

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

  $ rake docker:deploy

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

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

  $ rake docker:deploy

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

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

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

(0)

相关推荐

  • Docker 容器操作退出后进入解决办法

    在我们对Docker容器操作的时候,有时候会误操作或者其他的原因无意间退出了正在操作的容器,也许你会担忧你在其中的一些操作未保存下来,无须担忧,本文中将会提供各种方法供你参考(我的建议使用最后一种).在本文,我们将讨论五种(4+1)连接Docker容器并与其进行交互的方法.例子中所有的代码都可以在GitHub中找到,你可以亲自对它们进行测试. 1.nsenter 安装 nsenter 工具在 util-Linux 包2.23版本后包含. 如果系统中 util-linux 包没有该命令,可以按照下

  • Docker到底是什么?Docker为什么它这么火!

    Xcode 是运行在操作系统Mac OS X上的集成开发工具(IDE),由苹果公司开发.Xcode是开发OS X 和 iOS 应用程序的最快捷的方式.Xcode 具有统一的用户界面设计,编码.测试.调试都在一个简单的窗口内完成. 背景介绍 Xcode前身是继承自NeXT的Project Builder. The Xcode suite 包含有GNU Compiler Collection自由软件 (GCC. apple-darwin9-gcc-4.0.1 以及 apple-darwin9-gcc

  • Docker 端口映射详细介绍

    Docker 端口映射: 最近抽空,把Docker 端口映射的资料整理了一下,以便后续项目应用,大家也可以参考下. # Find IP address of container with ID <container_id> 通过容器 id 获取 ip $ sudo docker inspect <container_id> | grep IPAddress | cut -d '"' -f 4 无论如何,这些 ip 是基于本地系统的并且容器的端口非本地主机是访问不到的.此外

  • 在Docker中使用MySQL的教程

    提及虚拟化技术,我可是linuxContainer(LXC)的热爱者.但随着Docker技术的声名鹊起,我想在这展示一下如何使用带有Docker的Mysql Docker是什么? 实际上,Docker就是LXC的封装.使用起来很有意思.Docker采用LXC来虚拟化每个应用.所以在接下来的示例中,我们会启动chroot环境中一个被封装在自己命名空间内的mysql实例(你也可以设置Cgroups对应的资源)使用Docker的一个亮点就是统一文件系统(aufs).所以当启动一个Docker容器后,它

  • 再Docker中架设完整的WordPress站点全攻略

    1. 安装 Docker 在我们真正开始之前,我们需要确保在我们的 Linux 机器上已经安装了 Docker.我们使用的主机是 CentOS 7,因此我们用下面的命令使用 yum 管理器安装 docker. # yum install docker # systemctl restart docker.service 2. 创建 WordPress 的 Dockerfile 我们需要创建用于自动安装 wordpress 以及其前置需求的 Dockerfile.这个 Dockerfile 将用于

  • 基于 Docker 开发 NodeJS 应用

    有关这个 Node 应用 此应用包含一个 package.json, server.js 以及一个 .gitignore 文件, 它们简单到可以信手拈来. .gitignore node_modules/* package.json { "name": "docker-dev", "version": "0.1.0", "description": "Docker Dev", "

  • Centos下安装docker教程

    通过yum安装 需要root或者能sudo的权限 yum包更新到最新 $ sudo yum update 添加Docker yum源 $ sudo tee /etc/yum.repos.d/docker.repo <<-'EOF' [dockerrepo] name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/ enabled=1 gpgcheck=1 gpgkey=h

  • 在docker中部署tomcat并且部署java应用程序的步骤详解

    先给大家简单说下Docker的概念 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何接口. 1.先说如何在docker中部署tomcat 第一步:root用户登录在系统根目录下创建文件夹tomcat7,命令如:mkdir tomcat7,并且切换到该目录下:cd tomcat7: 第二步:创建Dockerfile,命令如:touch Docker

  • Docker for windows pull镜像文件的安装位置改变的方法

    Docker for windows pull镜像文件的安装位置改变的方法 发生现象: 在windows10下安装Docker for windows,随着用docker pull image文件后,C盘的容量越来越小了,你可能也有一种跟我一样的想法,想改变默认的安装路径,本文希望能解决你的问题. 原因分析: windows上安装的docker其实本质上还是借助与windows平台的hyper-v技术来创建一个Linux虚拟机,你执行的所有命令其实都是在这个虚拟机里执行的,所以所有pull到本地

  • Docker 配置固定IP及桥接的实现方法

    docker默认使用bridge模式,通过网桥连接到宿主机,而容器内部的ip则从网桥所在的ip段取未用的ip.这样做一个不方便的地方在于容器内部的ip不是固定的,想要连接容器时只能通过映射到宿主机的端口,因而有很多项目使用overlay来为docker提供网络的配置,比如Pipework.Flannel.Kubernetes.Weave.opencontrail等. 想要使用overlay来为docker配置网络,需要首先了解下docker的网络模式: 一.Docker的四种网络模式 Docke

随机推荐