この記事は「Dockerコンテナ上に開発環境一式を構築する」の一部です。
現在のステータス
- VPSにホストにUbuntuを入れる
- dnsを構築する <-イマココ
- nginxを構築する
- Selenium用のJenkins環境を構築する
- GitBucket環境を構築する
- Desktop環境(IntelliJ IDEA)を構築する
Dockerfile
gitbucketやJenkinsにコンテナの外からも中からも同じドメインでアクセスしたいですよね。そこでコンテナの中のホストのためにネームサーバーを立ち上げます。
# Bind9 Dockerfile
FROM ubuntu:14.04
ENV DEBIAN_FRONTEND noninteractive
# Install.
RUN apt-get update && apt-get -y upgrade
&& apt-get install -y bind9 dnsutils
Ubuntu14.04をベースにbindとdnsutilsだけをインストールします。EXPOSEディレクティブで使用するポートをdockerに伝える事も出来ますが、コンテナ起動時に-pで外部公開用と同時に指定もできるのでここで書いていません。
https://docs.docker.com/engine/reference/run/#expose-incoming-ports
Dockerfileを作ったらビルドします。ビルドはスクリプトにするほどでもないのですが、しばらく触らないとオプションを忘れてしまうのでファイルにしてしまいます。
#!/bin/sh
PROJECT=dns
cd /home/docker/$PROJECT/docker
docker build -t "lavans-$PROJECT:latest" .
bindの設定ファイルを取得するため、一旦起動して/etc/bindディレクトリをまるまる持ってきます。
$ docker run --name dns -d lavans-dns named -f
$ docker cp dns:/etc/bind bind
バックアップをとってファイルを変更します。
cp named.conf.options named.conf.options.org
cp named.conf named.conf.org
echo include \"/etc/bind/named.conf.example\" >> named.conf
zone "dev.example.jp" {
type master;
file "/etc/bind/db.example";
};
dockerホストのブリッジIPですが、原則172.17.42.1で衝突するときだけ移動するのかと思っていたのですが違いました。今回は172.17.0.1でした。そこで下記のような環境設定ファイルを用意します。こいつは他のコンテナからも使うので/home/dockerに置きます。
参考:Dockerコンテナ内部からホストのSMTPを利用したい
DOCKER_HOME=/home/docker
IP=`ip route | grep docker0 | awk '{print $9}'`
/etc/default/dockerにDOCKER_OPTS='--bip=<ip-addr>'
と指定することで
dockerサービスの起動時に指定できるので、固定にしてしまってもいいと思います。
https://docs.docker.com/v1.8/articles/networking/
dbファイルを下記のように設定しておきます。
; BIND data file for example.jp
$TTL 604800
@ IN SOA dns.example.jp. root.localhost. (
20160101 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS dns.example.jp.
@ IN A 127.0.0.1
@ IN AAAA ::1
dev IN A $IP
dns IN A $IP
gitbucket IN CNAME dev
jenkins IN CNAME dev
devtop IN CNAME dev
www IN CNAME dev
コマンドラインでIPをセットします。
$ . ../setenvn.sh
$ sed -e s/\$IP/$IP/g db.example.org > db.example
これでgitbucket.dev.example.jpやjenkins.dev.example.jpがみんなブリッジIPを向くようになるはずです。起動/終了スクリプトを用意して確認します。ました。bindディレクトリをマウントして確認してみます。
#/bin/sh
. ../setenv.sh
docker run -v $DOCKER_HOME/dns/bind:/etc/bind --name dns -p 53:53/udp -d \
lavans-dns named -f
-vオプションでホストのディレクトリをコンテナのディレクトリにマウントします。-pで53/udpをDockerの外にも公開してます。
#/bin/sh
docker stop dns
docker rm dns
Dockerコンテナをストップした後はコンテナファイルが残ります。そのコンテナを再利用したりそこからイメージを作成することもできますが、Dockerの「毎回同じ環境で動作する」メリットを生かすために、基本的には一度落としたコンテナは削除して次回は新しいコンテナを立ち上げ直します。
$ ./kill.sh
$ ./run.sh
コンテナが立ち上がっているか確認します。
$ docker exec -it dns bash
「dns」という名前で先ほど立ち上げたコンテナでbashをインタラクティブモードで動かします。
Error response from daemon: No such container: dns
おっと!怒られてしまいました。docker psで確認してみます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
docker@133-130-118-36:~/dns$
docker psはpsコマンドのように立ち上がっているコンテナ一覧を表示します。なにもいませんね。コンテナをbashで立ち上げてみましょう。
$ docker run -v $DOCKER_HOME/dns/bind:/etc/bind --name dns -it lavans-dns bash
これでbindディレクトリをマウントした状態でシェルにつながりました。
このようなプロンプトになります。
root@c37b3eb2d61c:/#
bind設定ファイルをチェックしてみましょう。
root@c37b3eb2d61c:/# named-checkconf
/etc/bind/named.conf:13: missing ';' before end of file
root@c37b3eb2d61c:/#
セミコロンが抜けていたようです。修正して再確認します。zoneファイルも確認しておきましょう。
root@c37b3eb2d61c:/# named-checkzone dev.lavans.jp /etc/bind/db.dev-lavans
zone dev.lavans.jp/IN: loaded serial 20160101
OK
コンテナを再起動して、hostかnslookupを叩いて確認します。
$ ./kill.sh
$ ./run.sh
$ docker exec -it dns bash
$ host jenkins.lavans.jp localhost
Using domain server:
Name: localhost
Address: ::1#53
Aliases:
jenkins.example.jp is an alias for dev.example.jp.
dev.example.jp has address 172.17.0.1
ようやく動きました。