LoginSignup
64
64

More than 5 years have passed since last update.

CircleCIでDockerコンテナのCI環境を整える

Last updated at Posted at 2015-09-04

自分の備忘録兼、社内ハンズオン用の資料なので、足りないところが多いかもしれません。

記事の最後まで進んだ状態が以下にありますので、参考にどうぞ。

honeniq/docker-circleci-sample

事前に必要なもの

  • ローカルでDockerが使える環境
    • Docker-Toolboxなど
  • DockerHubのアカウント
  • GitHubのアカウント
    • CircleCIはGitHubアカウントでログインできます
  • Ruby
    • Bundlerも必要

大体の手順

  1. GitHubでリポジトリを作って、ローカルにクローン
  2. Gemfileを作成
  3. テストの準備をする
  4. テストと実装コードを書く
  5. CircleCIの設定
  6. GitHubフローでCIを回す
  7. DockerHubに自動デプロイ

GitHubでリポジトリを作って、ローカルにクローン

項目として作ってみたけど、特に書くことがない。

Gemfileを作成

こんな感じの内容で作成。

source 'https://rubygems.org/'

gem 'docker-api'

group :test do
  gem 'specinfra', '2.12.7'
  gem 'serverspec'
end

specinfraのバージョンを指定しているのは、CircleCIとの相性から。
参照: CircleCIでDockerコンテナをテストしようとしたらエラーになるとき

保存したら、コンソールからbundleコマンドを叩く。

$ bundle
Fetching gem metadata from https://rubygems.org/.......
Fetching version metadata from https://rubygems.org/..
Resolving dependencies....
Using diff-lcs 1.2.5
Using excon 0.45.4

  ~

Using serverspec 2.8.2
Using bundler 1.9.9
Bundle complete! 3 Gemfile dependencies, 16 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.

テストの準備をする

.rspecを作成する

--color
--format documentation

設定しておかないとテストの結果表示が味気ないので。

spec_helper.rbを作成する

spec/spec_helper.rb
require "docker"
require "serverspec"

set :backend, :docker
set :docker_url, ENV["DOCKER_HOST"]
set :docker_image, "honeniq/docker-circleci-sample"

Excon.defaults[:ssl_verify_peer] = false

set :backend, :dockerでDockerコンテナに対してテストするように指定してる。

イメージ名を直接書いてるのがイケてないので、そのうち修正する。

テストのテスト

この状態でrspecコマンドを叩くと、空のテストが回る。

$ bundle exec rspec
No examples found.

Finished in 0.0003 seconds (files took 0.06445 seconds to load)
0 examples, 0 failures

テストと実装コードを書く

とりあえず今回はnginxが入ればOKという要件で。

web_spec.rb を作成する

spec/web/web_spec.rb
require 'spec_helper'

# Workaround needed for circleCI
if ENV['CIRCLECI']
  class Docker::Container
    def remove(options={}); end
    alias_method :delete, :remove
  end
end

describe "nginx" do
  describe package("nginx") do
    it { should be_installed }
  end
end

上半分は、これまたCircleCIで動かすためのコード。

この状態でrspecすると、Dockerイメージが見つからないと怒られる。

Failures:

  1) nginx Package "nginx"
     Failure/Error: Unable to find matching line from backtrace
     Docker::Error::NotFoundError:
       No such image: honeniq/docker-circleci-sample
     # (eval):1:in `backend'

Dockerfileを作成する

FROM ubuntu

とりあえずイメージがビルドできるだけ。

docker buildを叩いてイメージを作る。イメージ名はspec_helper.rbで指定しているもの。

$ docker build -t honeniq/docker-circleci-sample .

Sending build context to Docker daemon 67.58 kB
Step 0 : FROM ubuntu
 ---> d2a0ecffe6fa

これで、rspecのコケ方が変わる。

Failures:

  1) nginx Package "nginx" should be installed
     Failure/Error: it { should be_installed }
       expected Package "nginx" to be installed
     # ./spec/web/web_spec.rb:13:in `block (3 levels) in <top (required)>'

テストを通す

nginxをインストールするようにDockerfileを編集する。

FROM ubuntu

RUN apt-get update
RUN apt-get install -y nginx

再度docker buildしてイメージに反映させる。

$ docker build -t honeniq/docker-circleci-sample .
Sending build context to Docker daemon 73.22 kB
Step 0 : FROM ubuntu
 ---> d2a0ecffe6fa
Step 1 : RUN apt-get update
 ---> Using cache
 ---> cb24a07d1bd2
Step 2 : RUN apt-get install -y nginx
 ---> Running in 5fd7387700fa
Reading package lists...

  ~

 ---> 1d87758f46a8
Removing intermediate container 5fd7387700fa
Successfully built 1d87758f46a8

これでテストも無事通るようになる。

$ bundle exec rspec

nginx
  Package "nginx"
    should be installed

Finished in 12.72 seconds (files took 0.26434 seconds to load)
1 example, 0 failures

ローカルでテストが通るようになったので、GitHubにPushしておく。

CircleCIの設定

新規プロジェクト作成

CircleCIのメニューから、 Add Projects を選んで、GitHubに作ったリポジトリ名の横にある Build project を押す。

しばらくすると1回目のテストが走って・・・コケる。

kobito.1441379041.240178.png

CircleCIがDockerコンテナを使う設定になっていないのが原因。

circle.ymlを作成する

circle.yml
machine:
  services:
    - docker

dependencies:
  override:
    - docker info
    - docker build -t honeniq/docker-circleci-sample .

test:
  override:
    - bundle
    - bundle exec rspec

大体見たまんまの内容で、CircleCIでテストを走らせるホストでDockerを使えるようにして、テストの前段でdocker buildを実行、あとはbundleで必要なgemを入れたあとにrspecしているだけ。

作成したらGitHubにPush。
CircleCIがリポジトリの更新を検知して、2回目のテストが走る。

kobito.1441379700.114022.png

通った!

GitHubフローでCIを回す

参照: GitHub Flow

Featureブランチを作る

nginxのindexページの中身を変更する、って体で。

テストコードを書き換える

後半のみ抜粋。

web_spec.rb
describe "nginx" do
  describe package("nginx") do
    it { should be_installed }
  end

  describe file("/usr/share/nginx/html/index.html") do
    its(:content) { should match /Welcome to test container/ }
    its(:content) { should_not match /Welcome to nginx/ }
  end
end

当然、rspecはコケる。

Dockerfileを書き換える

FROM ubuntu

RUN apt-get update
RUN apt-get install -y nginx
RUN sed -i 's/Welcome to nginx/Welcome to test container/g' /usr/share/nginx/html/index.html

テストが通るように修正。

Pull Requestを投げる

自分で自分のリポジトリに投げることになるけど気にしない。

CircleCIがPRを検知して、自動的にFeatureブランチのテストを始めてくれる。

kobito.1441384708.262199.png

こんな感じに、masterと区別してテスト状況が確認できる。

Pull Requestをマージする

自分で自分のPRをマージすることになるけど気にしない。

kobito.1441384832.226240.png

GitHub上でもCircleCIのテスト結果が確認できるので非常に分かりやすい。

PRがmasterブランチにマージされると、masterブランチの更新を検知してCircleCIがまたテストを走らせてくれる。

kobito.1441384965.550473.png

DockerHubに自動デプロイ

masterでもテストが通ったら、DockerイメージをDockerHubに自動デプロイするように変更する。

Featureブランチを作る

一応、GitHubフローに沿うように。

ただ、今回の変更内容はmasterブランチ上でしか検証できないので、あんまり意味ないかもしれない。

circle.ymlを修正する

machine:
  services:
    - docker

dependencies:
  override:
    - docker info
    - docker build -t honeniq/docker-handson .

test:
  override:
    - bundle
    - bundle exec rspec

deployment:
  hub:
    branch: master
    commands:
      - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
      - docker push honeniq/docker-handson

deploymentタスクを追加。
branch: masterで、masterブランチの時のみ実行するように絞っている。

途中、docker loginでDockerHubにログインしてもらう必要があるけど、直接コードにユーザー名やパスワードを書くわけにはいかないので、環境変数に入れる。

CircleCIに環境変数を登録

circle.ymlに指定した3つの環境変数を返せるように、CircleCI側にも登録してあげる。

kobito.1441429887.390978.png

Project SettingTweaks / Environment Variables と進んで、環境変数を登録する。

「Name」に環境変数名、「Value」に対応する値を入力して保存。以下3つを登録。

  • DOCKER_EMAIL : DockerHubに登録しているメールアドレス
  • DOCKER_USER : DockerHubのユーザー名
  • DOCKER_PASS : DockerHubのパスワード

Pull Requestを投げてマージする

先ほどと同じく、自分で自分にPRを投げてマージする。

masterブランチのテストも問題なく通れば、追加したdeploymentタスクが走ってDockerHub上のイメージが更新される。kobito.1441430777.228240.png

これで、デプロイまで一通り流れるようになった。

64
64
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
64
64