<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>JohnnyTing</title>
    <link>https://ruby-china.org/JohnnyTing</link>
    <description/>
    <language>en-us</language>
    <item>
      <title>为啥 ruby 大佬们写的代码都很抽象？</title>
      <description>&lt;p&gt;因为工作原因接触到了 ruby，不到一年。看到我们老大写的代码很简洁、复用程度贼高，但也是因为表面很简洁所以代码看起来很抽象，内部各种调用，眼花缭乱&lt;img title=":joy:" alt="😂" src="https://twemoji.ruby-china.com/2/svg/1f602.svg" class="twemoji"&gt; 。也由此感觉 ruby 项目的后期维护确实是个问题。虽然代码有时看起来很费劲，但内心 OS”代码写的真牛逼！！！“&lt;/p&gt;</description>
      <author>JohnnyTing</author>
      <pubDate>Tue, 15 Oct 2019 09:42:13 +0800</pubDate>
      <link>https://ruby-china.org/topics/39151</link>
      <guid>https://ruby-china.org/topics/39151</guid>
    </item>
    <item>
      <title>自动化部署 Rails 应用 (Docker + Jenkins)</title>
      <description>&lt;p&gt;&lt;a href="https://yeasy.gitbooks.io/docker_practice/" rel="nofollow" target="_blank" title=""&gt;docker 安装参考链接&lt;/a&gt;      &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/compose/rails/" rel="nofollow" target="_blank" title=""&gt;docker 官网&lt;/a&gt;   &lt;/p&gt;

&lt;p&gt;&lt;a href="https://jenkins.io/zh/doc/tutorials/create-a-pipeline-in-blue-ocean/#%E5%9C%A8blue-ocean%E5%88%9B%E5%BB%BA%E4%BD%A0%E7%9A%84%E6%B5%81%E6%B0%B4%E7%BA%BF%E9%A1%B9%E7%9B%AE" rel="nofollow" target="_blank" title=""&gt;jenkins 中文官网&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="服务器环境为Ubuntu 16.04.2 LTS"&gt;服务器环境为 Ubuntu 16.04.2 LTS&lt;/h4&gt;
&lt;p&gt;1.卸载旧版本 docker&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get remove docker &lt;span class="se"&gt;\&lt;/span&gt;
               docker-engine &lt;span class="se"&gt;\&lt;/span&gt;
               docker.io
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.安装 docker，使用脚本自动安装&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; get.docker.com &lt;span class="nt"&gt;-o&lt;/span&gt; get-docker.sh

&lt;span class="nb"&gt;sudo &lt;/span&gt;sh get-docker.sh &lt;span class="nt"&gt;--mirror&lt;/span&gt; Aliyun
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.启动 docker&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 设置开启自启动&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;docker

&lt;span class="c"&gt;# 启动docker&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start docker

&lt;span class="c"&gt;# 查看版本&lt;/span&gt;
docker &lt;span class="nt"&gt;-v&lt;/span&gt;    &lt;span class="c"&gt;# docker --version&lt;/span&gt;
Docker version 18.09.5, build e8ff056
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4.安装 docker-compose&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="s2"&gt;"https://github.com/docker/compose/releases/download/1.24.0/docker-compose-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/local/bin/docker-compose

&lt;span class="c"&gt;# 添加执行权限&lt;/span&gt;
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; +x /usr/local/bin/docker-compose

&lt;span class="c"&gt;# 查看版本&lt;/span&gt;
docker-compose &lt;span class="nt"&gt;-v&lt;/span&gt;    &lt;span class="c"&gt;# docker-compose --version&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;5.安装 compose bash 补全命令&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://raw.githubusercontent.com/docker/compose/1.8.0/contrib/completion/bash/docker-compose &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/bash_completion.d/docker-compose
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;6.如果需要卸载 docker-compose，删除可执行文件即可&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo rm&lt;/span&gt; /usr/local/bin/docker-compose
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;7.配置 docker 镜像加速&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;在/etc/docker/daemon.json 中写入如下内容，如果没有此文件新建即可:
{
  "registry-mirrors": [
    "https://dockerhub.azk8s.cn",
    "https://reg-mirror.qiniu.com"
  ]
}

重新启动服务:
sudo systemctl daemon-reload
sudo systemctl restart docker

检查加速器是否生效:
docker info

如果出现下面内容则配置成功
Registry Mirrors:
 https://dockerhub.azk8s.cn/
 https://reg-mirror.qiniu.com/

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;8.安装 jenkins，使用 blue ocean 镜像，来创建流水线项目&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--name&lt;/span&gt; jenkins &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-p&lt;/span&gt; 8090:8080 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-v&lt;/span&gt; /home/oliver/jenkins_home:/var/jenkins_home &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-v&lt;/span&gt; /home/oliver/.ssh:/root/.ssh &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;always &lt;span class="se"&gt;\&lt;/span&gt;
    jenkinsci/blueocean

&lt;span class="c"&gt;# 将jenkins的数据目录挂载出来，防止数据丢失&lt;/span&gt;
&lt;span class="c"&gt;# 这里把.ssh目录挂载出来的原因是：&lt;/span&gt;
&lt;span class="c"&gt;# 1.之后需要将rails应用部署到其他服务器上，需要通过ssh认证来远程部署应用，所以主机host需要保证和部署服务器连通。&lt;/span&gt;
&lt;span class="c"&gt;# 2.需要将ssh公钥传入到git服务器上，保证能正常拉取代码&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;9.查看 jenkins 日志，获取管理员密码&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;➜  ~ &lt;span class="nb"&gt;sudo &lt;/span&gt;docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                               NAMES
a210c6d643a3        jenkinsci/blueocean   &lt;span class="s2"&gt;"/sbin/tini -- /usr/…"&lt;/span&gt;   3 minutes ago       Up 3 minutes        50000/tcp, 0.0.0.0:8090-&amp;gt;8080/tcp   jenkins

&lt;span class="c"&gt;# 查看jenkins日志&lt;/span&gt;
➜  ~ &lt;span class="nb"&gt;sudo &lt;/span&gt;docker logs &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;50 a210c6d643a3

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/E11B960E-EBCE-4029-BD75-34C033BB3EF2.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;看到密码后复制，或者进入容器内的/var/jenkins_home/secrets/initialAdminPassword 查看，因为 jenkins 容器目录挂载到了/home/oliver/jenkins_home 下，所以也可以查看 &lt;/p&gt;

&lt;p&gt;/home/oliver/jenkins_home/secrets/initialAdminPassword 文件中的内容。 &lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/C0C747F1-C13B-43B4-B360-077B9A90AFC1.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;10.选择安装推荐插件就行&lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/B7D75290-74AE-4742-9256-E297C8B0C3A4.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;11.然后等待安装完成，如果安装失败就重新安装。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/3F6D45F1-EA78-45CB-A92B-8CDDAE698806.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;12.然后下一步提示创建一个管理员账号，填写完就进入 jenkins 首页。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/76CBA9E6-BCE9-403D-8BBD-40958DF07932.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;13.配置凭据&lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/42EC914F-44F6-49DC-80D6-4DD02567CF32.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/BB4BD616-22B2-4CEB-83CE-D23511879F60.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;添加全局凭据：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/19B0EA90-F8BA-46F7-8168-E5D36CBE2960.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;添加 ssh 私钥，在/home/oliver/.ssh/id_rsa 中&lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/14D2B8A6-0206-4C55-B92A-590417982996.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;14.在本地 rails 项目中添加 Jenkinsfile:&lt;/p&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;
    &lt;span class="n"&gt;stages&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'start'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'jenkins构建开始...'&lt;/span&gt;
          &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
       &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'build'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'sh ssh.sh'&lt;/span&gt;
          &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
   &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'jenkins构建成功'&lt;/span&gt;
          &lt;span class="o"&gt;}&lt;/span&gt;
       &lt;span class="n"&gt;failure&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'jenkins构建失败'&lt;/span&gt;
          &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;15.连接应用部署服务器 ssh.sh（jenkins 所在服务器与应用部署服务器区分开）:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#! /bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git symbolic-ref &lt;span class="nt"&gt;--short&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; HEAD&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"分支: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
ssh root@xxxx &lt;span class="s1"&gt;'bash -s'&lt;/span&gt; &amp;lt; deploy.sh &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# 这里获取分支名称是为了在部署服务器上区分分支项目，也用来区分每个分支的docker容器&lt;/span&gt;
&lt;span class="c"&gt;# 后面的deploy.sh 是连接到部署服务器上后执行的脚本&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;16.根据部署脚本 deploy.sh 启动容器：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#! /bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /root/workspace/
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"克隆项目&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    git clone &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nv"&gt;$app&lt;/span&gt; git@xxxx/xxxx.git &lt;span class="nv"&gt;$app&lt;/span&gt;
    &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"拉取项目&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    git pull origin &lt;span class="nv"&gt;$app&lt;/span&gt;
&lt;span class="k"&gt;fi
&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="p"&gt;//-/&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;web&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;docker-compose ps | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nv"&gt;$branch&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="nv"&gt;$web&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"构建容器: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;web&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"重启容器: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;web&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    docker-compose restart
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# 上面shell主要的作用是：不存在某个分支的项目则克隆到指定目录，存在则拉取最新代码；然后根据分支名称查看容器是否构建过，没有则开始构建并启动，之前构建过则重启容器&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;17.构建所需要的 Dockerfile:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FROM ruby:2.5.3
RUN apt-get update &lt;span class="nt"&gt;-qq&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; curl netcat &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    curl &lt;span class="nt"&gt;-sL&lt;/span&gt;  https://deb.nodesource.com/setup_10.x |  bash - &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nodejs postgresql-client openjdk-8-jdk &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; yarn &lt;span class="nt"&gt;--registry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://registry.npm.taobao.org &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
    yarn config &lt;span class="nb"&gt;set &lt;/span&gt;registry https://registry.npm.taobao.org &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
    yarn config &lt;span class="nb"&gt;set &lt;/span&gt;sass_binary_site http://cdn.npm.taobao.org/dist/node-sass &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    apt-get purge &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nt"&gt;--auto-remove&lt;/span&gt; curl &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get clean &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;
ENV &lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;C.UTF-8 &lt;span class="nv"&gt;RAILS_ROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/myapp
WORKDIR &lt;span class="nv"&gt;$RAILS_ROOT&lt;/span&gt;
VOLUME &lt;span class="nv"&gt;$RAILS_ROOT&lt;/span&gt;
COPY entrypoint.sh /usr/bin/
RUN &lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/bin/entrypoint.sh
ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"entrypoint.sh"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
EXPOSE 3000
&lt;span class="c"&gt;# Start the main process.&lt;/span&gt;
CMD &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"rails"&lt;/span&gt;, &lt;span class="s2"&gt;"server"&lt;/span&gt;, &lt;span class="s2"&gt;"-b"&lt;/span&gt;, &lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;18.入口点 entrypoint.sh&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Remove a potentially pre-existing server.pid for Rails.&lt;/span&gt;
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /myapp/tmp/pids/server.pid
bundle &lt;span class="nb"&gt;install
rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; build/
./gradlew generateProto
&lt;span class="nb"&gt;nohup &lt;/span&gt;sh bin/rpcServer_development.sh &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;rpc.log 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$!&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; rpc.pid
 &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; nc &lt;span class="nt"&gt;-z&lt;/span&gt; localhost 6600&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="k"&gt;do
      &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"wait for rpc..."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nb"&gt;sleep &lt;/span&gt;2&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"rpc is ready!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"bin/downloadCenter_development.sh"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;then
   &lt;/span&gt;&lt;span class="nb"&gt;nohup &lt;/span&gt;sh bin/downloadCenter_development.sh &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;download.log 2&amp;gt;&amp;amp;1 &amp;amp;
   &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$!&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; download.pid
&lt;span class="k"&gt;fi
&lt;/span&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="c"&gt;# Then exec the container's main process (what's set as CMD in the Dockerfile).&lt;/span&gt;
&lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# 注意：上面脚本需要根据自己项目的具体情况来写&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;19.docker-compose.yml&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;version: &lt;span class="s1"&gt;'3'&lt;/span&gt;
services:
  web:
    build: &lt;span class="nb"&gt;.&lt;/span&gt;
    volumes:
      - .:/myapp
    ports:
      - &lt;span class="s2"&gt;"3000:3000"&lt;/span&gt;
    restart: always

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;20.然后创建 jenkins 项目，打开 blue ocean&lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/82D89327-DC02-429D-90B4-ED72BA76EB79.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;21.选择 git 代码仓库，填入 git 地址&lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/233C82E0-06C0-49A8-92ED-28537474B845.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;填入地址后根据提示需要将你的 ssh 公钥 key 配置到 git 服务器上，然后创建流水线。创建后多分支项目根目录有 Jenkinsfile 的自动构建。 &lt;/p&gt;

&lt;p&gt;22.在项目配置中，选择扫描项目的时间间隔，分支有改动自动触发构建 &lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/6105F645-2ED3-4B02-9788-18D1213ED392.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;这里设置每五分钟扫描一次 git 仓库&lt;/p&gt;

&lt;p&gt;&lt;img src="https://dingxu66.oss-cn-beijing.aliyuncs.com/img/119A93DA-20DD-404F-8AA1-5AB37CBACFCC.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;之后就是每次推送了代码，jenkins 发现代码有改动就会触发构建并使用 docker 部署到指定的服务器上，可以在 jenkins 后台查看构建过程，也可以在部署服务器查看容器日志。&lt;/p&gt;

&lt;p&gt;整个自动化部署 rails 应用流程就结束了，大家可以尝试一下。&lt;/p&gt;</description>
      <author>JohnnyTing</author>
      <pubDate>Tue, 09 Jul 2019 16:25:41 +0800</pubDate>
      <link>https://ruby-china.org/topics/38815</link>
      <guid>https://ruby-china.org/topics/38815</guid>
    </item>
  </channel>
</rss>
