Dockerコンテナ上でJenkinsをインストールして実行する

はじめに

Dockerコンテナ上でJenkinsをインストールして実行する手順を説明します。Dockerのバージョンは現在の最新安定版の0.7.6であることを前提としています。

なお、今回作成したDockerイメージは、Docker Index上にリポジトリyosssi/jenkinsとして格納しています。

手順

ubuntuイメージよりコンテナを新規作成し、コンテナ上でシェルを起動します。

$ docker run -i -t ubuntu /bin/bash

wgetをインストールします。

/# apt-get update
/# apt-get install -y wget

Jenkinsをインストールします。

/# wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | apt-key add -
/# echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list
/# apt-get update
/# apt-get install -y jenkins

コンテナのシェルを終了し、コンテナからイメージを作成します。

/# exit
$ docker commit コンテナID yosssi/jenkins 

作成したイメージよりコンテナを起動し、そのコンテナ上でJenkinsを起動します。

$ docker run -d -i -p 80:8080 yosssi/jenkins /bin/bash -c '/etc/init.d/jenkins start; read;'

ローカルホストへアクセスし、Jenkinsが起動していることを確認します。

f:id:kysd:20140201165020p:plain

参考資料

DrupalがインストールされたDockerイメージを作成する

はじめに

本記事ではDrupal on Docker - Rob Knight's blogの記事をもとに、DrupalがインストールされたDockerイメージを作成する手順を説明します。本記事の説明は、読み手の端末にDockerがインストールされていることを前提としています。DockerがプリインストールされたVagrant boxは、以下のリンクより取得頂けます。(Vagrant boxファイルへの直接リンクです。私がPackerにて作成したものになります。)本記事にて記載しているコマンドは、現時点でのDockerの最新安定版である0.7.6にて動作確認を行っております。

https://s3-ap-northeast-1.amazonaws.com/yosssi/vagrant-boxes/ubuntu-13.10-server-amd64-docker.box

なお、今回作成したDockerイメージは、Docker Index上にリポジトリyosssi/lampとして格納しています。

事前準備

VagrantからDockerを起動する場合は、下記の通り、ゲストOSのポート番号80をホストOSの任意のポート番号(以下の例では8080)へ転送するようVagrantfileを設定し、Vagrantを起動します。

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ubuntu-13.10-server-amd64-docker"
  config.vm.box_url = "https://s3-ap-northeast-1.amazonaws.com/yosssi/vagrant-boxes/ubuntu-13.10-server-amd64-docker.box"
  config.vm.network :forwarded_port, guest: 80, host: 8080
end

手順

runコマンドを実行し、centosイメージをベースにコンテナを作成し、シェルを起動します。

$ docker run -i -t centos /bin/bash

コンテナ内で、必要なライブラリをインストールします。

bash-4.1# yum install httpd php php-common php-cli php-pdo php-mysql php-xml php-mbstring mysql mysql-server

コンテナのシェルを終了し、commitコマンドを実行してコンテナからイメージを作成します。

bash-4.1# exit
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
b5a7b1bfaf46        centos:6.4          /bin/bash           5 minutes ago       Exit 0                                  cranky_lumiere   
$ docker commit b5a7b1bfaf46 yosssi/lamp
659ab11532a0cbcd9569eef72e0f77482507a0ae2ad67b2c0227887c98028714
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
yosssi/lamp         latest              659ab11532a0        23 seconds ago      426.8 MB
centos              6.4                 539c0211cd76        10 months ago       300.6 MB
centos              latest              539c0211cd76        10 months ago       300.6 MB

以上により、PHPMySQLApacheがインストールされているyosssi/lampというイメージが作成されました。

このイメージをもとにコンテナを作成し、コンテナ上でApacheを起動します。

$ docker run -i -t -p 80:80 yosssi/lamp /bin/bash
bash-4.1# /sbin/service httpd start

ブラウザよりローカルホストへアクセスし、Apacheがコンテナ上で正常に起動されていることを確認します。

f:id:kysd:20140131234331p:plain

コンテナのシェルを終了し、insertコマンドを実行してファイルをyosssi/lampイメージへ追加します。

bash-4.1# exit
$ docker insert yosssi/lamp http://ftp.drupal.org/files/projects/drupal-7.22.tar.gz /root/drupal.tar.gz
71ebfc254213526d298719384e0fc359f43f2b24f0215d07951163cd0e8dd726
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
<none>              <none>              71ebfc254213        4 minutes ago       430 MB
yosssi/lamp         latest              659ab11532a0        19 minutes ago      426.8 MB
centos              6.4                 539c0211cd76        10 months ago       300.6 MB
centos              latest              539c0211cd76        10 months ago       300.6 MB

tagコマンドを実行し、新規に作成されたイメージに対してリポジトリ、タグを設定します。

$ docker tag 71ebfc254213526d298719384e0fc359f43f2b24f0215d07951163cd0e8dd726 yosssi/lamp:drupal
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
yosssi/lamp         drupal              71ebfc254213        7 minutes ago       430 MB
yosssi/lamp         latest              659ab11532a0        22 minutes ago      426.8 MB
centos              6.4                 539c0211cd76        10 months ago       300.6 MB
centos              latest              539c0211cd76        10 months ago       300.6 MB

作成したイメージyosssi/lamp:drupalをベースにコンテナを作成・起動し、Drupalの設定を行います。

$ docker run -i -t -p 80:80 yosssi/lamp:drupal /bin/bash
bash-4.1# tar zxf /root/drupal.tar.gz --strip=1 -C /var/www/html
bash-4.1# echo "NETWORKING=yes" > /etc/sysconfig/network
bash-4.1# /sbin/service mysqld start
bash-4.1# mysql -uroot
mysql> create database drupal;
Query OK, 1 row affected (0.00 sec)
mysql> grant all privileges on drupal.* to 'drupal'@'localhost' identified by 'drupal';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
mysql> exit
Bye
bash-4.1# cp /var/www/html/sites/default/default.settings.php /var/www/html/sites/default/settings.php
# database settingsのdatabase、username、passwordを全て 'drupal'へ修正します
bash-4.1# vi /var/www/html/sites/default/settings.php 
bash-4.1# mkdir /var/www/html/sites/default/files
bash-4.1# chown apache:apache /var/www/html/sites/default/files
bash-4.1# /sbin/service httpd start

ブラウザよりローカルホストへアクセスし、Drupalのサービスへ正常にアクセスできることを確認します。

f:id:kysd:20140201001254p:plain

参考資料

RedisがインストールされたDockerイメージの作成

はじめに

本記事では、Installing Redis on Docker - John Costa's Blogの記事をもとに、RedisがインストールされたDockerイメージの作成手順を説明します。本記事は、Dockerがインストール済であることを前提としています。DockerがプリインストールされたVagrant boxは、以下のリンクより取得頂けます。(Vagrant boxファイルへの直接リンクです。私がPackerにて作成したものになります。)本記事にて記載しているコマンドは、現時点でのDockerの最新安定版である0.7.6にて動作確認を行っております。

https://s3-ap-northeast-1.amazonaws.com/yosssi/vagrant-boxes/ubuntu-13.10-server-amd64-docker.box

手順

Dockerの公式イメージであるubuntuイメージを使ってコンテナを新規に立ち上げます。

$ docker run -i -t ubuntu /bin/bash
root@aaadab642e4c:/# 

runコマンドは、引数で指定されたイメージ(今回の場合はubuntu)上にコンテナを新規に作成し、そのコンテナ上で引数で指定されたコマンド(今回の場合は/bin/bash)を実行します。-iオプションを指定することで標準入力からの入力を可能にします。-tオプションを指定することで疑似端末(pseudo-tty)が割り当てられます。

パッケージリストを最新化し、redis-serverをインストールします。

root@aaadab642e4c:/# apt-get update
root@aaadab642e4c:/# apt-get install -y redis-server

redis-serverがインストールされていることを確認します。

root@aaadab642e4c:/# which redis-server
/usr/bin/redis-server

コンテナのシェルから退出します。

root@aaadab642e4c:/# exit
exit
$

コンテナの一覧を出力し、先ほど作成したコンテナのIDを確認します。

$ docker ps -a
CONTAINER ID        IMAGE                     COMMAND                CREATED             STATUS              PORTS               NAMES
aaadab642e4c        ubuntu:12.04              /bin/bash              28 minutes ago      Exit 0                                  pensive_torvalds

psコマンドは、コンテナの一覧を表示します。-aオプションを指定することで、現在実行されていないコンテナを含めた全てのコンテナが表示されます。このオプションが指定されていない場合は、現在実行中のコンテナのみが表示されます。

今回の場合、コンテナIDはaaadab642e4cとなります。

Dockerレジストリサーバへログインします。アカウントをお持ちでない場合は、ご希望のEメール、パスワード、ユーザ名を指定することで、アカウントが作成されます。

$ docker login -e あなたのEメール -p あなたのパスワード -u あなたのユーザ名
Login Succeeded

今回作成したコンテナのイメージを作成します。

$ docker commit aaadab642e4c あなたのユーザ名/redis
4b4b6b00568083fe438374c9078a3da75fbd0657b1ec8da572068803fbe1b8ac

commitコマンドは、引数のコンテナID(今回の場合はaaadab642e4c)に合致するコンテナからイメージを作成します。引数「あなたのユーザ名/redis」は、作成されるイメージのリポジトリとタグを表します。リポジトリにはあなたのユーザ名を指定します。

イメージが作成されたことを確認します。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
yosssi/redis        latest              4b4b6b005680        5 seconds ago       205.8 MB
ubuntu              12.10               426130da57f7        5 days ago          127.6 MB
ubuntu              quantal             426130da57f7        5 days ago          127.6 MB
ubuntu              10.04               8589d4e9c7c6        5 days ago          139.6 MB
ubuntu              lucid               8589d4e9c7c6        5 days ago          139.6 MB
ubuntu              12.04               72e10143e54a        5 days ago          125.9 MB
ubuntu              latest              72e10143e54a        5 days ago          125.9 MB
ubuntu              precise             72e10143e54a        5 days ago          125.9 MB
ubuntu              13.10               721f07d19f96        5 days ago          144.6 MB
ubuntu              saucy               721f07d19f96        5 days ago          144.6 MB
ubuntu              raring              476aa49de636        5 days ago          133.6 MB
ubuntu              13.04               476aa49de636        5 days ago          133.6 MB

imagesコマンドはイメージの一覧を出力します。

作成したイメージをDockerレジストリサーバへアップロードします。

$ docker push あなたのユーザ名/redis

pushコマンドはイメージ・リポジトリレジストリへアップロードします。

本コマンドの実行後、Docker indexにて、アップロードしたイメージが存在することを確認することができます。

作成したイメージのコンテナを実行し、Redisサーバを起動します。

$ docker run -p 6379 -d あなたのユーザ名/redis /usr/bin/redis-server

runコマンドで-pオプションを指定することで、ネットワークポートをコンテナに設定することができます。また、-dオプションを指定することで、コマンドをバックグラウンドで実行することができます。

実行中のコンテナのステータスを確認します。

$ docker ps
CONTAINER ID        IMAGE                 COMMAND                CREATED             STATUS              PORTS                     NAMES
79a9719d914f        yosssi/redis:latest   /usr/bin/redis-serve   3 minutes ago       Up 3 minutes        0.0.0.0:49158->6379/tcp   backstabbing_poincare  

PORTSの項を見ると、コンテナ内のポート番号6379が、外部のポート番号(今回の例では49158)に紐付けられていることが分かります。コンテナ外からは、この外部ポート番号を指定することで、コンテナのポート番号6379のプロセスへアクセスすることができます。

telnetを使ってコンテナの外からコンテナ内のRedisサーバへアクセスしてみます。

$ telnet 0.0.0.0 49158
Trying 0.0.0.0...
Connected to 0.0.0.0.
Escape character is '^]'.
monitor
+OK
+1391159705.184861 "monitor"
set docker awesome
+OK
+1391159714.071889 "set" "docker" "awesome"
get docker
$7
awesome
+1391159720.705523 "get" "docker"
quit
+OK
Connection closed by foreign host.
$

最後に

今回の例では、公式イメージubuntuをベースにコンテナを立ち上げ、RedisをインストールしてDockerイメージを新規に作成しました。その後、作成したイメージをリポジトリへアップロードする作業を実施しました。最後に、作成したDockerイメージよりコンテナを立ち上げ、そのコンテナ上でRedisサーバをバックグラウンドで起動し、コンテナ外からRedisサーバへアクセスする方法を確認しました。

参考資料

Packerを使ってDockerがプリインストールされたVagrant boxを作成してみました。

Packerを使ってDockerがプリインストールされたVagrant boxを作成してみました。

PackerのテンプレートファイルはこちらGitHubリポジトリにあります。

生成されたVagrant boxは、こちらより取得頂けます。

Go言語の識別子iotaについて

Go言語の標準パッケージtimeにおいて、以下の定数定義があります。

type Month int

const (
    January Month = 1 + iota
    February
    March
    April
    May
    June
    July
    August
    September
    October
    November
    December
)

各月に対応する数値を定義した定数であり、それぞれの評価値は(皆様の推測の通り)以下の通りとなります。

package main

import ( 
    "fmt"
    "time"
)

func main() {
    fmt.Printf("%d\n", time.January)   //-> 1
    fmt.Printf("%d\n", time.February)  //-> 2
    fmt.Printf("%d\n", time.March)     //-> 3
    fmt.Printf("%d\n", time.April)     //-> 4
    fmt.Printf("%d\n", time.May)       //-> 5
    fmt.Printf("%d\n", time.June)      //-> 6
    fmt.Printf("%d\n", time.July)      //-> 7
    fmt.Printf("%d\n", time.August)    //-> 8
    fmt.Printf("%d\n", time.September) //-> 9
    fmt.Printf("%d\n", time.October)   //-> 10
    fmt.Printf("%d\n", time.November)  //-> 11
    fmt.Printf("%d\n", time.December)  //-> 12
}

前述の定数定義で使用されている識別子iotaについて、仕様書を見て調べてみました。

識別子iotaは、定数宣言文(const)内で使用される、連続する型未定の整数の定数を表します。この定数は予約語constが現れたときに0に初期化され、各定数定義の後に1ずつインクリメントされます。

package main

import (
    "fmt"
)

const (
    a0 = iota // 予約語constがあるため0に初期化される
    a1 = iota // 1
    a2 = iota // 2
)

const (
    b0 = iota // 予約語constがあるため0に初期化される
    b1 = iota // 1
    b2 = iota // 2
)

func main() {
    fmt.Println(a0) //-> 0
    fmt.Println(a1) //-> 1
    fmt.Println(a2) //-> 2

    fmt.Println(b0) //-> 0
    fmt.Println(b1) //-> 1
    fmt.Println(b2) //-> 2
}

iotaの値を用いた演算結果を定数に設定することもできます。

package main

import (
    "fmt"
)

const (
    a0 = iota      // 予約語constがあるため0に初期化される
    a1 = iota * 10 // 1 * 10
    a2 = iota * 20 // 2 * 20
)

func main() {
    fmt.Println(a0) //-> 0
    fmt.Println(a1) //-> 10
    fmt.Println(a2) //-> 40
}

また、定数宣言文内で代入値を省略すると前回の代入と同じ値が代入されるため、これを利用してiotaの記載を省略しながら、連続した値を定数として定義することができます。

package main

import (
    "fmt"
)

const (
    a0 = iota // 予約語constがあるため0に初期化される
    a1        // 前回と同じくiotaが代入されるため、1が代入される
    a2        // 前回と同じくiotaが代入されるため、2が代入される
    a3 = 10
    a4        // 前回と同じく10が代入される
    a5 = iota // 5(a3、a4の定数定義でiotaが使用されていなくとも、iotaはインクリメントされている)
    a6        // 前回と同じくiotaが代入されるため、6が代入される
)

func main() {
    fmt.Println(a0) //-> 0
    fmt.Println(a1) //-> 1
    fmt.Println(a2) //-> 2
    fmt.Println(a3) //-> 10
    fmt.Println(a4) //-> 10
    fmt.Println(a5) //-> 5
    fmt.Println(a6) //-> 6
}

以上のように、識別子iotaを用いることで、連続した値を持つ定数を簡潔に定義することができるようになります。

*本記事は、執筆時点におけるGo言語の最新バージョンである1.2の仕様ソースコードに基づいて執筆されています。