Docker PostgreSQLイメージを利用する(https://qiita.com/kimullaa/items/70eaec61c02d2513e76c)

PostgreSQLDocker

目的

この記事はDockerで開発環境用のPostgreSQLを用意することを目的にしています。運用レベルの考慮はしていません。

検証環境

$ cat /etc/redhat-release CentOS Linux release 7.1.1503 (Core) $ docker -v Docker version 18.03.1-ce, build 9ee9f40 $ docker-compose -v docker-compose version 1.21.2, build a133471

PostgreSQLを起動する

$ docker run --name my-db -p 5432:5432 -e POSTGRES_USER=dev -e POSTGRES_PASSWORD=secret -d postgres:9.6

オプション役割

--name my-db コンテナ名
-p 5432:5432 ホストのポート:コンテナのポート
-e POSTGRES_USER スーパユーザ名(省略時は"postgres")
-e POSTGRES_PASSWORD スーパユーザのパスワード(省略時はパスワードなしでログイン可)
-e POSTGRES_DB データベース名(省略時はPOSTGRES_USERと同じ)デフォルトだとユーザ名と同じデータベースが存在しないとエラーになるため、変える機会は少なそう
-e PGDATA PostgreSQLのデータの格納先ディレクトリ(省略時は/var/lib/postgresql/data)

起動しているコンテナの一覧はdocker psで確認できる。

# --name my-dbで指定した値がNAMESに表示される $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ebb9cf2ff57f postgres:9.6 "docker-entrypoint.s…" 14 seconds ago Up 10 seconds 0.0.0.0:5432->5432/tcp my-db

PostgreSQLに接続する

ホストからアクセスする

-p xxxx:5432で指定したホストのポートにアクセスすると、コンテナにパケットが転送される。PostgreSQLがコンテナで動いていることを意識する必要はない。ローカルで動くアプリケーションから接続するときは、この方法になる。

$ psql -h localhost -U dev ユーザ dev のパスワード: psql (9.6.9) "help" でヘルプを表示します. dev=#

コンテナを利用してアクセスする パターン1

psqlクライアント用にコンテナを立ち上げ、--linkを利用して接続する。

$ docker run -it --rm --link my-db:db postgres:9.6 psql -h db -U dev Password for user dev: psql (9.6.9) Type "help" for help. dev=#

オプション役割

--rm 実行が終わったらpsqlのコンテナを破棄する
--link my-db:db コンテナの/etc/hostsに、my-dbにアクセス可能なIPを持つホスト名(db)が設定される
psql -h db -U dev コンテナ内で実行するコマンド。 接続先には --linkで設定したホスト名を指定する

ただし --linkは古い機能のため扱いに注意。
参考 Legacy container links

コンテナを利用してアクセスする パターン2

現在立ち上がっているコンテナで別プロセスを立ち上げる。

$ docker exec -it my-db psql -U dev psql (9.6.9) Type "help" for help. dev=#

PostgreSQLコンテナの停止

docker stopするだけ。

$ docker stop my-db

PostgreSQLコンテナの再開

docker rmしてなければ、docker startできる。
DBデータは消えずに利用できる。

$ docker start my-db

初期データを設定する

コンテナの/docker-entrypoint-initdb.dディレクトリに*.sql, *.sql.gz, or *.shのファイルを配置すると、コンテナ起動時に実行される。アプリケーション用のスキーマを毎回実行したいときに利用すると便利。

$ cat sql/schema.sql CREATE TABLE SAMPLE(); $ docker run -it --name my-db -v $(pwd)/sql:/docker-entrypoint-initdb.d -e POSTGRES_PASSWORD=secret -d postgres:9.6 56fdad8741465fd86b618b62ed2ca7bf613b715b73e3ccf90e3618155d58d5d3 [kimura@localhost docker]$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 56fdad874146 postgres:9.6 "docker-entrypoint.s…" 5 seconds ago Up 2 seconds 5432/tcp my-db [kimura@localhost docker]$ docker exec -it my-db psql -U postgres psql (9.6.9) Type "help" for help. postgres=# \d List of relations Schema | Name | Type | Owner --------+--------+-------+---------- public | sample | table | postgres (1 row)

PostgreSQLコンテナの削除

docker rmするだけ。

$ docker rm my-db

docker runすると、DBデータはまっさらな状態になる。

PostgreSQLコンテナを消すとDBデータはどうなる?

PostgreSQLのDockerfileに、以下のような記述がある。
参考 Dockerfile

VOLUME /var/lib/postgresql/data

VOLUMEの指定があると、コンテナ起動時にボリュームが自動で作成される。
作成されたボリューム名は、docker inspectで確認できる。

$ docker inspect my-db ... "Mounts": [ { "Type": "volume", "Name": "813a6def1e8a1e07e6e5cb317bd4577a83ecce8d6d2846449014ea3e32e56fd4", "Source": "/var/lib/docker/volumes/813a6def1e8a1e07e6e5cb317bd4577a83ecce8d6d2846449014ea3e32e56fd4/_data", "Destination": "/var/lib/postgresql/data", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ], ...

コンテナを削除するだけではボリュームは削除されない

Removing the service does not remove any volumes created by the service. Volume removal is a separate step.

参考 Manage data in Docker

そのため、ボリュームを指定すれば昔のDBデータにアクセスできる。

$ docker run -it -v 813a6def1e8a1e07e6e5cb317bd4577a83ecce8d6d2846449014ea3e32e56fd4:/var/lib/postgresql/data --name my-db -e POSTGRES_PA SSWORD=secret -d postgres:9.6

逆に、明示的にボリュームを消さないとデータは残り続ける。
コンテナを削除するときにボリュームも消す場合は、-vオプションを使う。

$ docker rm -v my-db

また、以下のコマンドで不要なボリュームを一括で削除できる。

$ docker volume prune

DBデータを永続化する

ボリュームに名前を付けておけば、手軽にコンテナにアタッチできる。
参考 Use volumes

$ docker volume create --name pgdata pgdata $ docker volume inspect pgdata [ { "CreatedAt": "2018-06-14T03:55:37+09:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/pgdata/_data", "Name": "pgdata", "Options": {}, "Scope": "local" } ]

起動時にData Volumeを指定してテーブルを作成する。

$ docker run -it --name my-db -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=secret -d postgres:9.6 $ docker exec -it my-db -U postgres psql (9.6.9) Type "help" for help. postgres=# create table book(); CREATE TABLE

コンテナを停止して削除する。

$ docker stop my-db $ docker rm my-db

起動時に同じData Volumeを指定すれば、永続化したデータが参照できる。

$ docker run -it --name my-db -v pgdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD=secret -d postgres:9.6 $ docker exec -it my-db -U postgres psql (9.6.9) Type "help" for help. postgres=# \d List of relations Schema | Name | Type | Owner --------+------+-------+---------- public | book | table | postgres (1 row)

ただしボリュームにデータを永続化した場合、/docker-entrypoint-initdb.dのスクリプトはコンテナ起動ごとに実行されない点に注意。

ロケール設定

デフォルトではサーバロケールがen_US.utf8になっている。
ja_JP.utf8にしたい人は以下のように、Dockerfileを作成する必要がある。

You can also extend the image with a simple Dockerfile to set a different locale. The following example will set the default locale to de_DE.utf8:

FROM postgres:9.4
RUN localedef -i de_DE -c -f UTF-8 -A /usr/share/locale/locale.alias de_DE.UTF-8
ENV LANG de_DE.utf8

Since database initialization only happens on container startup, this allows us to set the language before it is created.

参考 OFFICIAL REPOSITORY

日本語化する

ロケールを追加し、LANG環境変数に設定する。

$ cat Dockerfile FROM postgres:9.6 RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8 ENV LANG ja_JP.utf8

Dockerfileをビルドし、起動すると日本語になる。

$ docker build -t dev-postgres -f Dockerfile . $ docker run -it --name my-db -e POSTGRES_PASSWORD=secret -d dev-postgres $ docker exec -it my-db -U postgres psql (9.6.9) Type "help" for help. postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+------------+------------+----------------------- postgres | postgres | UTF8 | ja_JP.utf8 | ja_JP.utf8 | template0 | postgres | UTF8 | ja_JP.utf8 | ja_JP.utf8 | =c/postgres + | | | | | postgres=CTc/postgres

なぜユーザ名やパスワードが起動引数で変えられるのか?

-eオプションでコンテナの環境変数を設定できる仕組みがDockerにある。
参考 Docker run リファレンス

以下のようなコマンドを実行すると -e SAMPLE=sampleで指定した値が環境変数に設定されることがわかる。

$ docker run -it -e SAPMLE=sample --rm centos:7 env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=c650fe32fc3b TERM=xterm SAPMLE=sample HOME=/root

また、既に設定された環境変数を上書きすることもできる。
例えば、HOME=/rootをHOME=/tmpで上書きしてみる。

$ docker run -it -e HOME=/tmp --rm centos:7 env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=4c5e7303b0fa TERM=xterm HOME=/tmp

上記の仕組みを利用し、起動スクリプトの動きを動的に変えている様子。

起動スクリプトの詳細を確認するときはdocker inspectを利用する。

$ docker inspect postgres:9.6 ... "WorkingDir": "", "Entrypoint": [ // 起動時に呼ばれるコマンド "docker-entrypoint.sh" ], ...

起動スクリプト(docker-entrypoint.sh)は以下のような処理になっている。
参考 docker-entrypoint.sh

docker-entrypoint.sh

file_env 'POSTGRES_USER' 'postgres' file_env 'POSTGRES_DB' "$POSTGRES_USER" psql=( psql -v ON_ERROR_STOP=1 ) if [ "$POSTGRES_DB" != 'postgres' ]; then "${psql[@]}" --username postgres <<-EOSQL CREATE DATABASE "$POSTGRES_DB" ; EOSQL echo fi if [ "$POSTGRES_USER" = 'postgres' ]; then op='ALTER'

PostgreSQLコンテナの構成を知る

起動しているコンテナにbashで入ることができる。

スクリプトやディレクトリ構成を確認できる。

$ docker exec -it my-db /bin/bash root@f43f50193fa6:/# ls bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var boot docker-entrypoint-initdb.d etc lib media opt root sbin sys usr

PostgreSQLの設定の変更

設定ファイルの編集

まず、コンテナからpostgresql.confをコピーする。

$ docker cp my-db:/var/lib/postgresql/data/postgresql.conf .

次に、ホスト側で設定ファイルを編集する。
(今回はmax_connectionsを100から5にする)

$ cat postgresql.conf ... max_connections = 5 ...

編集した設定ファイルの配置

コンテナ側にファイルを配置するだけだと、以下のようにエラーになる。
参考 Unable to replace postgresql.conf

$ docker run -it --name my-db -v $(pwd)/postgresql.conf:/var/lib/postgresql/data/postgresql.conf -e POSTGRES_PASSWORD=secret postgres:9.6 The files belonging to this database system will be owned by user "postgres". This user must also own the server process. The database cluster will be initialized with locale "en_US.utf8". The default database encoding has accordingly been set to "UTF8". The default text search configuration will be set to "english". Data page checksums are disabled. initdb: directory "/var/lib/postgresql/data" exists but is not empty If you want to create a new database system, either remove or empty the directory "/var/lib/postgresql/data" or run initdb with an argument other than "/var/lib/postgresql/data".

以下のように、$PGDATAに設定ファイルを配置しないでPostgreSQLの起動時にconfig_fileで設定ファイルのパスを指定すればよい。

$ docker run -it --name my-db -v $(pwd)/postgresql.conf:/etc/postgresql.conf -e POSTGRES_PASSWORD=secret -d postgres:9.6 -c config_file=/etc/postgresql.conf bf55391afe2ae709e84efd81025b4d7f542f3db4bb42d13c348807cc9342b47f $ $ docker exec -it my-db psql -U postgres psql (9.6.9) Type "help" for help. postgres=# SHOW max_connections; max_connections ----------------- 5 (1 row)

設定をまとめる

docker-composeを使ってコマンドをまとめる。

$ ll 合計 8 -rw-rw-r--. 1 kimura kimura 119 6月 14 07:02 Dockerfile drwxrwxr-x. 2 kimura kimura 28 6月 14 06:58 conf -rw-rw-r--. 1 kimura kimura 438 6月 14 13:11 docker-compose.yml drwxrwxr-x. 2 kimura kimura 23 6月 14 13:41 sql

Dockerfile

FROM postgres:9.6 RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8 ENV LANG ja_JP.utf8

docker-compose.yml

version: "3" volumes: pgdata: driver: "local" services: my-db: build: . container_name: "my-db" ports: - "5432:5432" environment: POSTGRES_USER: "dev" POSTGRES_PASSWORD: "secret" command: 'postgres -c config_file="/etc/postgresql.conf"' volumes: - "pgdata:/var/lib/postgresql/data" - "./conf/postgresql.conf:/etc/postgresql.conf" - "./sql:/docker-entrypoint-initdb.d"

これでDockerfileのビルドから起動までコマンド一発。

$ docker-compose up -d Creating network "postgres_default" with the default driver Creating volume "postgres_pgdata" with local driver Building my-db Step 1/3 : FROM postgres:9.6 ---> d92dad241eff Step 2/3 : RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8 ---> Running in 4ae5282dc582 Removing intermediate container 4ae5282dc582 ---> ae2a5b8d31fe Step 3/3 : ENV LANG ja_JP.utf8 ---> Running in aa9c01cdc114 Removing intermediate container aa9c01cdc114 ---> 117a670283ca Successfully built 117a670283ca Successfully tagged postgres_my-db:latest WARNING: Image for service my-db was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`. Creating my-db ... done

PostgreSQLに接続したい場合は以下のようにする。

$ docker-compose exec my-db psql -U dev psql (9.6.9) "help" でヘルプを表示します. dev=# \d リレーションの一覧 スキーマ | 名前 | 型 | 所有者 ----------+--------+----------+-------- public | sample | テーブル | dev (1 行) dev=# show max_connections; max_connections ----------------- 5 (1 行)

docker execでもアクセスできる。

$ docker exec -it my-db psql -U dev psql (9.6.9) "help" でヘルプを表示します. dev=# show max_connections ; max_connections ----------------- 5 (1 行)

コンテナとデータのどちらも削除したい場合は、-vオプションを付ける。

$ docker-compose down -v Removing network postgres_default Removing volume postgres_pgdata

参考 docker-compose down

関連記事

http://www.calazan.com/docker-cleanup-commands/
上記サイトで紹介されているコマンドをよく使うので、日本語訳、しようかと思ったのですが、コマンドだけコピペで。

Dockerコマンドメモ
こちらのメモにもお世話になってます。

Kill all running containers
docker kill $(docker ps -q)

Delete all stopped containers (including data-only containers)
docker rm $(docker ps -a -q)

Delete all ‘untagged/dangling’ () images
docker rmi $(docker images -q -f dangling=true)

Delete ALL images
docker rmi $(docker images -q)

任意のレポジトリのイメージを全部削除したい場合(誤って他のも消しちゃうかもなので、grep注意
docker rmi $(docker images | grep 'REPOSITORY_NAME' | awk '{print$3}')

古いコンテナを削除したい場合(-fオプションがついているため実行中のContainerも削除されます。停止しているContainerのみ削除したい場合は-fを取り除いて下さい。

  • 数週間前
    • docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm -f
  • 1週間前
    • docker ps -a | grep 'week ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm -f
  • 数日前
    • docker ps -a | grep 'days ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm -f
  • 1日前
    • docker ps -a | grep 'day ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm -f
  • 数時間前
    • docker ps -a | grep 'hours ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm -f
  • 1時間前
    • docker ps -a | grep 'hour ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm -f
  • 数分前
    • docker ps -a | grep 'minutes ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm -f
  • 1分前
    • docker ps -a | grep 'minute ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm -f
  • 数秒前
    • docker ps -a | grep 'seconds ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm -f

適宜自分用に更新します。。


'Server > Docker' 카테고리의 다른 글

Docker로 postgre 콘테나 가동하기  (0) 2019.05.21
Docker container간 연동 확인  (0) 2018.11.20
Why docker container exits immediately  (0) 2018.11.14
docker-compose.yml 내부 명령어  (0) 2018.11.14
docker-compose 커맨들 일람  (0) 2018.11.09

Docker container間の連携について
(https://qiita.com/taka4sato/items/b1bf33941a1ec8b69fd2)

この記事は最終更新日から3年以上が経過しています。

docker初心者なので、Docker container同士の連携について、設定方法やらを半年後の自分用にチラシの裏しておきます。

この内容を踏まえた上で、docker-compose (旧Fig)に進む事をお奨めします。

初めに

Container同士の連携と言っても、大きく2つのケースがあります。

  1. 同じHost内にあるContainer間の連携 (シングルホスト)
  2. 別のHostにあるContainerとの連携 (マルチホスト)

マルチホストでの連携は、Best practiceについてまだ試行錯誤の段階にあるみたいですが、ここら辺とかここら辺を参照して見て下さい。

ここでは、シングルホストでの連携についてチラシの裏しておきます。
結論から言うと、同じHost上のContainer-A→Container-Bにアクセスさせる場合、

  • Container-Aの起動時に、docker run に--link OptionでContainer-Bを指定して上げる事でアクセスできる様になります
  • Container-A上でcurl localhost:xxx (xxxはContainer-BがHostにexposeしてるPort)ではアクセス出来ないです

参考URL

素のContainerからnginx Containerにアクセス

Container-A (素のubuntu) から、Container-B (nginx, Port 25525をhostにexpose)にアクセスしたい、というCase studyで、Container間の連携の設定方法やアクセス方法を見てみたいと思います。

Container-Bを立ち上げる

まず、アクセスを受ける側のContainer-Bを立ち上げます。中身のdockerfile/nginxこのDockerfileです。単にnginxをinstallして、port 80で待ち受けしているだけです。このcontainerにnginx_testという名前を付けて、Host側からPort 25525でアクセスできるようにしています。

#docker run -d -p 25525:80 --name nginx_test dockerfile/nginx

Container-Bの起動後、host上で、curl localhost:25525すると、Container-Bのnginxから応答(Welcome to nginxのHTML code)がある事を確認して下さい。

Container-Aを立ち上げる

続いて、アクセスする側のContainer-Aを立ち上げます。中身は素のubuntu 14.04です。
--link nginx_test:nginxで、nginx_testというcontainerにnginxというAliasを付与しています。

#docker run -it --link nginx_test:nginx ubuntu:14.04

すると、Container-Aのshellに遷移すると思います。

Container-AからContainer-Bがどう見えるか確認する

Container-AのShell上で以下の操作をして、Container-BがContainer-Aからどう見えて居るのか、Container-Bのnginxにどうすればアクセスできるのか見てみます。

環境変数の確認
#env | grep NGINX
NGINX_PORT_443_TCP_ADDR=172.17.0.2
NGINX_NAME=/cranky_kowalevski/nginx
NGINX_PORT_80_TCP_PROTO=tcp
NGINX_PORT_80_TCP=tcp://172.17.0.2:80
NGINX_PORT_443_TCP_PORT=443
NGINX_PORT_80_TCP_PORT=80
NGINX_PORT_443_TCP=tcp://172.17.0.2:443
NGINX_PORT_443_TCP_PROTO=tcp
NGINX_PORT_80_TCP_ADDR=172.17.0.2
NGINX_PORT=tcp://172.17.0.2:80

/ect/hostsの確認
#cat /ect/hosts | grep nginx
172.17.0.2      nginx

Container-Bにping
#ping nginx
PING nginx (172.17.0.2) 56(84) bytes of data.
64 bytes from nginx (172.17.0.2): icmp_seq=1 ttl=64 time=0.114 ms
...

Container-Bのnginxに接続してみる
#apt-get update && apt-get install -y curl
#curl nginx
で、Welcome to nginxのHTML codeが戻って来たら成功です。

まとめ

  • Container-AからはContainer-Bはnginxというaliasで見える。curl nginxもしくはcurl nginx:80でアクセスできる
  • Container-Aの環境変数に、Container-Bの情報が色々登録されている
  • Container-Aから、curl localhost:25525curl localhost:80してもContainer-Bにはアクセスできない
  • Container-Bは、docker run -p 25525:80として起動させたが、Container-Aからはnginx:80として見える
    25525はあくまでhost側に見せるport。つまりContainer-BにはContainer-Aしかアクセスせず、HostからContainer-Bへのアクセスは存在しない場合には、Container-BのPortはHostにExposeする必要は無い

素のContainerからMongo Containerにアクセス

続いて、Container-A (素のubuntu) から、Container-B (MongoDB, Port 27017をhostにexpose)にアクセスしたい、というCase studyで、Container間の連携の設定方法やアクセス方法を見てみたいと思います。

Container-Bを立ち上げる

まず、アクセスされる側のContainer-Bを立ち上げます。中身のdockerfile/mongodbこのDockerfileです。単にMongo DBをinstallして、port 27017で待ち受けしているだけです。このcontainerにmongo_testという名前を付けて、Host側からPort 27017でアクセスできるようにします。

#docker run -d -p 27017:27017 --name mongo_test dockerfile/mongodb

Container-Aを立ち上げる

続いて、アクセスする側のContainer-Aを立ち上げます。中身は素のubuntu 14.04です。
--link mongo_test:mongo_test1で、mongo_testというcontainerにmongo_test1というAliasを付与しています。

#docker run -it --link mongo_test:mongo_test1 ubuntu:14.04

すると、Container-Aのshellに遷移すると思います。

Container-AからContainer-Bがどう見えるか確認する

Container-AのShell上で以下の操作をして、Container-BがContainer-Aからどう見えて居るのか、Container-BのMongoにどうすればアクセスできるのか見てみます。

環境変数の確認
#env | grep MONGO
MONGO_TEST1_PORT_27017_TCP_ADDR=172.17.0.57
MONGO_TEST1_PORT_27017_TCP=tcp://172.17.0.57:27017
MONGO_TEST1_PORT=tcp://172.17.0.57:27017
MONGO_TEST1_PORT_27017_TCP_PROTO=tcp
MONGO_TEST1_PORT_28017_TCP=tcp://172.17.0.57:28017
MONGO_TEST1_PORT_27017_TCP_PORT=27017
MONGO_TEST1_PORT_28017_TCP_ADDR=172.17.0.57
MONGO_TEST1_PORT_28017_TCP_PORT=28017
MONGO_TEST1_NAME=/sharp_pike/mongo_test1
MONGO_TEST1_PORT_28017_TCP_PROTO=tcp


/ect/hostsの確認
#cat /ect/hosts | grep mongo
172.17.0.57     mongo_test1


Container-Bにping
#ping mongo_test1
PING mongo_test1 (172.17.0.57) 56(84) bytes of data.
64 bytes from mongo_test1 (172.17.0.57): icmp_seq=1 ttl=64 time=0.058 ms
...


Container-BのMongoに接続してみる
#apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
#echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' > /etc/apt/sources.list.d/mongodb.list
#apt-get update && apt-get install -y mongodb-org-shell
#mongo $MONGO_TEST1_PORT_27017_TCP_ADDR:$MONGO_TEST1_PORT_27017_TCP_PORT
MongoDB shell version: 2.6.7
connecting to: 172.17.0.57:27017/test
...
mongo cliに入れて、mongoの操作が出来る事を確認して下さい


最後のmongoコマンドは、単純に以下でもOKです
#mongo --host mongo_test1

まとめ

  • Container-Aからは、Container-Bは、mongo_test1というaliasで見えている。curl mongo_test1でアクセスできる
  • Container-Aの環境変数に、Container-Bの情報が色々登録されている
  • Container-Aから、curl localhost:27017してもContainer-Bにはアクセスできない



I run a container in the background using

 docker run -d --name hadoop h_Service

it exits quickly. But if I run in the foreground, it works fine. I checked logs using

docker logs hadoop

there was no error. Any ideas?

DOCKERFILE

 FROM java_ubuntu_new
 RUN wget http://archive.cloudera.com/cdh4/one-click-install/precise/amd64/cdh4-repository_1.0_all.deb
 RUN dpkg -i cdh4-repository_1.0_all.deb
 RUN curl -s http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh/archive.key | apt-key add -
 RUN  apt-get update
 RUN apt-get install -y hadoop-0.20-conf-pseudo
 RUN dpkg -L hadoop-0.20-conf-pseudo
 USER hdfs
 RUN hdfs namenode -format
 USER root
 RUN apt-get install -y sudo
 ADD . /usr/local/
 RUN chmod 777 /usr/local/start-all.sh
 CMD ["/usr/local/start-all.sh"]

start-all.sh

 #!/usr/bin/env bash
 /etc/init.d/hadoop-hdfs-namenode start
 /etc/init.d/hadoop-hdfs-datanode start
 /etc/init.d/hadoop-hdfs-secondarynamenode start
 /etc/init.d/hadoop-0.20-mapreduce-tasktracker start
 sudo -u hdfs hadoop fs -chmod 777 /
 /etc/init.d/hadoop-0.20-mapreduce-jobtracker start
 /bin/bash
  • can you show us your Dockerfile and the complete run command ? – user2915097 Jan 29 '15 at 10:46
  • I ll edit and show you docker file. i have provided you already run command – Gops AB Jan 29 '15 at 10:50
  • The golden rule is that you should prevent your dockerized servers from daemonizing. Most server packages have options to force them in the foreground since daemonizing is the normal case. – Arnaud Meuret Sep 22 '15 at 10:29

答えが見つからない?日本語で聞いてみましょう。

A docker container exits when its main process finishes.

In this case it will exit when your start-all.sh script ends. I don't know enough about hadoop to tell you how to do it in this case, but you need to either leave something running in the foreground or use a process manager such as runit or supervisord to run the processes.

I think you must be mistaken about it working if you don't specify -d; it should have exactly the same effect. I suspect you launched it with a slightly different command or using -it which will change things.

A simple solution may be to add something like:

while true; do sleep 1000; done

to the end of the script. I don't like this however, as the script should really be monitoring the processes it kicked off.

(I should say I stole that code from https://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh)


Docker Compose - docker-compose.yml リファレンス(https://qiita.com/zembutsu/items/9e9d80e05e36e882caaa)

Docker Compose - docker-compose.yml リファレンス

原文:docker-compose.yml reference
https://docs.docker.com/compose/yml/

docker-compose.yml で定義される各々のサービスは、特定の image か build を指定する必要があります。その他のキーはオプションであり、docker run コマンドラインのものと似ています。

docker run と同様に、Dockerfile で指定されたオプションがデフォルトとして尊重されます(例:CMD,EXPOSE,VOLUME,ENV)。そのため、docker-compose.yml で再び定義する必要はありません。

image

タグや image ID の一部です。ローカルでもリモートでも構いません。ローカルに存在しなければ、Compose はイメージを取得(pull)します。

image: ubuntu
image: orchardup/postgresql
image: a4bc65fd

build

Dockerfile のあるディレクトリのパスを指定します。この値が相対パスで指定された場合は、yml ファイル自身がある場所からの相対パスになります。また、ディレクトリは内容構築のため、Docker デーモンにも送られます。

Compose は構築し、生成した名前をタグ付けし、以後のイメージでも使われます。

build: /path/to/build/dir

dockerfile

代替用の Dockerfile です。

Compose は構築時に指定されたファイルを使います。

dockerfile: Dockerfile-alternate

command

デフォルトのコマンドを上書きします。

command: bundle exec thin -p 3000

links

コンテナを他のサービスにリンクします。サービス名とリンク・エイリアス(サービス:エイリアス)を指定できるだけでなく、あるいは、サービス名(エイリアスとしても使われます)でも指定できます。

links:
 - db
 - db:database
 - redis

エイリアス名を記述すると、コンテナ内の /etc/hosts の中にサービス名が追加されます。例:

172.17.2.186  db
172.17.2.186  database
172.17.2.187  redis

環境変数も作成されます。詳細は環境変数リファレンスをご覧ください。

external_links

この docker-compose.yml や、とりわけ Compose の外にある共有ないし共通サービスが提供するコンテナとリンクします。external_links はコンテナ名やリンク・エイリアス(CONTAINER:ALIAS)の指定時に links と似たような意味あいを持ちます。

external_links:
 - redis_1
 - project_db_1:mysql
 - project_db_1:postgresql

extra_hosts

ホスト名のマッピングを追加します。docker クライアントの --add-host パラメータと同じ値です。

extra_hosts:
 - "somehost:162.242.195.82"
 - "otherhost:50.31.209.229"

入力した IP アドレスとホスト名は、コンテナ内の /etc/hosts にサービスと記載されます。例:

162.242.195.82  somehost
50.31.209.229   otherhost

ports

ポートを公開(expose)します。ホストとポートを指定(ホスト:コンテナ)するか、コンテナのポートのみ指定します(ホスト側のポートはランダムに選ばれます)。

メモ:ポートのマッピングに ホスト:コンテナ の形式を使うとき、コンテナのポートが 60 以下の場合はエラーが表示されるでしょう。これは YTML がxx:yy 形式を60進数と認識するためです。そのため、常に明確なポートのマッピングを文字列で指定することを推奨します。

ports:
 - "3000"
 - "8000:8000"
 - "49100:22"
 - "127.0.0.1:8001:8001"

expose

ホストマシン上にポートを露出(expose)しますが、公開はしません。リンクされたサービスのみアクセスできます。内部ポートのみ指定できます。

expose:
 - "3000"
 - "8000"

volumes

パスをボリュームとしてマウントします。オプションとしてホスト側のパスを指定(ホスト:コンテナ)したり、アクセスモードを指定します(ホスト:コンテナ:ro)。

volumes:
 - /var/lib/mysql
 - cache/:/tmp/cache
 - ~/configs:/etc/configs/:ro

volumes_from

他のサービスやコンテナから、全てのボリュームをマウントします。

volumes_from:
 - service_name
 - container_name

environment

環境変数を追加します。配列や dictionary(訳注;YAML のハッシュ)を使えます。

キーだけの環境変数は、Compose 起動時に用いられる値があてられますので、秘密にしたい値やホスト固有の値を指定しやすいです。

environment:
  RACK_ENV: development
  SESSION_SECRET:

environment:
  - RACK_ENV=development
  - SESSION_SECRET

env_file

ファイルから環境変数を追加します。リストには1つの値です。

Compose でファイルを docker-compose -f ファイル名 で指定した場合は、env_file のパスはそのファイルがあるディレクトリからの相対パスになります。

environment で指定した環境変数は、これらの値に上書きされます。

env_file: .env

env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env

Compose は環境変数で指定されたファイルの各行が 変数=値 の形式とみなします。#` で始まる行は無視され(例:コメント)、空白行として扱われます。

# 環境変数 Rails/Rack の設定
RACK_ENV=development

extends

現在のファイルや別のファイルから、他のサービスを拡張します。オプションで設定を上書きします。

以下は簡単な例です。2つのファイル common.ylm と development.yml があります。extends を使って development.yml のサービスを定義します。このサービスとは common.yml で定義されているものです:

common.yml
webapp:
  build: ./webapp
  environment:
    - DEBUG=false
    - SEND_EMAILS=false
development.yml
web:
  extends:
    file: common.yml
    service: webapp
  ports:
    - "8000:8000"
  links:
    - db
  environment:
    - DEBUG=true
db:
  image: postgres

ここでは、development.yml の web サービスは、common.yml の webapp サービスの設定を継承します。buildenvironment のキーと、ports と links 設定を追加します。新しい値を持つ環境変数(DEBGUG)が定義されると、既存のものを上書きします。
他の環境変数(SEND_EMAILS)はそのままです。

extends の詳細は、チュートリアルリファレンスをご覧ください。

labels

Docker labels を使ってコンテナにメタデータを追加します。配列やハッシュが使えます。

逆引き DNS の概念を使い、他のソフトウェアが使うラベルと衝突しないようにすることをお勧めします。

labels:
  com.example.description: "Accounting webapp"
  com.example.department: "Finance"
  com.example.label-with-empty-value: ""

labels:
  - "com.example.description=Accounting webapp"
  - "com.example.department=Finance"
  - "com.example.label-with-empty-value"

log driver

docker 実行時のオプションで(ドキュメントはこちら(英語)です) --log-driver を使い、ログ記録用のドライバを指定します。

現時点で使える値は json-filesyslognone です。暫くすると Docker エンジンにドライバが更に追加され、一覧が変わる可能性があります。

デフォルトの値は json-file です。

log_driver: "json-file"
log_driver: "syslog"
log_driver: "none"

net

ネットワーキング・モードを指定します。Docker クライアントで --net パラメータを指定したときと同じです。

net: "bridge"
net: "none"
net: "container:[name or id]"
net: "host"

pid

pid: "host"

PID モードを host PID モードにセットします。これにより、コンテナとホスト・オペレーティング・システム上の PID アドレス空間を共有します。ベアメタルマシンの名前空間などで、他のコンテナにアクセス・操作できるように、コンテナ起動時にこのフラグを使います。

dns

DNS サーバーを設定します。1つまたはリストで記述します。

dns: 8.8.8.8
dns:
  - 8.8.8.8
  - 9.9.9.9

cap_add, cap_drop

コンテナの性能を追加したり下げたりします。man 7 capabilities で詳細をご覧ください。

cap_add:
  - ALL

cap_drop:
  - NET_ADMIN
  - SYS_ADMIN

dns_search

DNS の search ドメインを設定します。1つまたはリストで記述します。

dns_search: example.com
dns_search:
  - dc1.example.com
  - dc2.example.com

devices

デバイス・マッピングの一覧です。Docker クライアントで作成時のオプション --device と同じ形式の使い方です。

devices:
  - "/dev/ttyUSB0:/dev/ttyUSB0"

security_opt

それぞれのコンテナ毎に、デフォルトのラベリング・スキーマを上書きします。

  security_opt:
    - label:user:USER
    - label:role:ROLE

working_dir, entrypoint, user, hostname, domainname, mem_limit, privileged, restart, stdin_open, tty, cpu_shares, cpuset, read_only

それぞれ単一の値を持つもので、docker runの対となります。

cpu_shares: 73
cpuset: 0,1

working_dir: /code
entrypoint: /code/entrypoint.sh
user: postgresql

hostname: foo
domainname: foo.com

mem_limit: 1000000000
privileged: true

restart: always

stdin_open: true
tty: true
read_only: true


docker-compose コマンドまとめ

この記事は最終更新日から1年以上が経過しています。(https://qiita.com/wasanx25/items/d47caf37b79e855af95f#version)

開発環境としてDockerを使ってるのですが、なんとなくコマンドを打っていて、あまりちゃんとコマンドを理解していないので、覚え書きとしてまとめてみようと思います。
dockerコマンドというよりdocker-composeを紹介します。

今回は以下のようなdocker-compose.ymlを参考にします。

docker-compose.yml
web:
  build: .
  environment:
    DISABLE_SPRING: "1" 
    DB_USERNAME: "root"
    DB_PASSWORD: "root"
    DB_HOST: "db"
  ports:
    - "3000:3000"
  volumes:
    - ".:/var/local/rails5_product"
  links:
    - "db"

db:
  image: mysql:5.6
  environment:
    MYSQL_ROOT_PASSWORD: "root"                                

Dockerfileも

Dokerfile
# rails5_product
FROM ruby:2.3.0
ENV LANG C.UTF-8

# Install Packages
RUN apt-get update -y && apt-get upgrade -y
RUN apt-get install -y \
      sudo \
      nodejs \
      build-essential \
      mysql-client 

# Application
ENV app     rails5_product
ENV deploy  /var/local/$app
ENV user    prod_dev

# User
RUN useradd -d /home/$user -m -s /bin/bash $user
RUN echo "$user:$user" | chpasswd
RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/$user
USER $user
ENV HOME /home/$user

# Work Directory
RUN sudo mkdir -p $deploy
RUN sudo chown -R $user:$user $deploy
WORKDIR $deploy

# Bundle Install
RUN sudo gem install bundler
ADD Gemfile $deploy/
ADD Gemfile.lock $deploy/
RUN sudo chown $user:$user Gemfile
RUN sudo chown $user:$user Gemfile.lock
RUN bundle install

EXPOSE 3000
CMD ["./bin/rails", "server", "-b", "0.0.0.0"]

環境

・ Ruby 2.3.0 (ベースとなるDockerイメージを使用しております。)
・ Ruby on Rails 5.0.0
・ Mac OS X El Capitan 10.11.5
・ Docker 1.12.0-rc4
・ docker-compose version 1.8.0-rc2
(Docker for Mac Beta を使用しております。)

build

サービスのビルドを実行します。
サービスとは「web」や「db」のことを指します。ymlファイルにimage:が書かれている場合はそのイメージ名がローカルになければ、リモートからプルしてきます。imageが書かれていない場合、buildに書かれているパスの(デフォルトは)Dockerfileを参考にしてイメージを構築します。

$ docker-compose build
db uses an image, skipping
Building web ......

また引数にサービス名を指定して、特定のサービスだけビルドすることも可能です。

bundle

DAB(Distributed Application Bundles)というのを作成します。これは事前に作成したイメージをdockerのregistryにpushしておく必要があります(ローカルにpushでも可)。

$ docker-compose bundle
WARNING: Unsupported key 'links' in services.web - ignoring
WARNING: Unsupported key 'volumes' in services.web - ignoring
Wrote bundle to rails5product.dab

作成されたファイルは以下のような内容です。

{
  "Services": {
    "db": {
      "Env": [
        "MYSQL_ROOT_PASSWORD=root"
      ], 
      "Image": "mysql@sha256:2897982d4c086b03586a1423d0cbf33688960ef7534b7bb51b9bcfdb6c3597e7", 
      "Networks": [
        "default"
      ]
    }, 
    "web": {
      "Args": [
        "bash", 
        "-c", 
        "rm -f tmp/pids/server.pid; ./bin/rails server -b 0.0.0.0"
      ], 
      "Env": [
        "DB_PASSWORD=root", 
        "DB_HOST=db", 
        "DB_USERNAME=root", 
        "DISABLE_SPRING=1"
      ], 
      "Image": "wataru0225/rails5_product@sha256:3fb6321b2c8edb2a3f74ca85574182802359a8d4106a9350406a6d5252a71a00", 
      "Networks": [
        "default"
      ], 
      "Ports": [
        {
          "Port": 3000, 
          "Protocol": "tcp"
        }
      ]
    }
  }, 
  "Version": "0.1"
}

config

docker-compose.ymlで書かれてる内容が表示されます。今回は、networksやvolumesは書いてないので空で表示されてます。

$ docker-compose config
networks: {}
services:
  db:
    environment:
      MYSQL_ROOT_PASSWORD: root
    image: mysql:5.6
    network_mode: bridge
  web:
    build:
      context: ~/rails5_product
    environment:
      DB_HOST: db
      DB_PASSWORD: root
      DB_USERNAME: root
      DISABLE_SPRING: '1'
    links:
    - db
    network_mode: bridge
    ports:
    - 3000:3000
    volumes:
    - ~/rails5_product:/var/local/rails5_product:rw
version: '2.0'
volumes: {}

create

構築されたサービスを参考にそのコンテナを作ります。ここで作られたコンテナは起動している状態ではありません。

$ docker-compose create
Creating rails5product_db_1
Creating rails5product_web_1

これもまた引数にサービス名を指定して、特定のサービスだけのコンテナを作ることも可能です。

down

docker-compose.ymlに書かれているサービスを参考にコンテナを停止し、そのコンテナとネットワークを削除します。
オプションで--rmi allをつけることでイメージも削除してくれます。

$ docker-compose down
Stopping rails5product_web_1 ... done
Stopping rails5product_db_1 ... done
Removing rails5product_web_1 ... done
Removing rails5product_db_1 ... done

events

コンテナからのイベントを受信します。コマンドを打つと、受信状態に入り特に動きはありません。別のタブでdockerコマンドを試すと動きが分かります。

$ docker-compose events

$ docker exec -it rails5product_web_1 /bin/bash
root@21896a731d87:/var/local/rails5_product#                                                               
$ docker-compose events
container exec_start: /bin/bash  21896a731d87e65c0725df989b8c2828d14850ece829897e057caa514e435f7f (image=rails5product_web, name=rails5product_web_1) 

exec

docker execコマンドと同等のことができます。引数にサービス名と実行するコマンドを指定して、実行します。

$ docker-compose exec web /bin/bash
root@3a0319c17621:/var/local/rails5_product# 

help

コマンドの一覧を表示します。基本はこちらを参考にすると良いでしょう。

images

対象のイメージの情報を表示します。

$ docker-compose images
     Container           Repository        Tag       Image Id      Size   
-------------------------------------------------------------------------
rails5product_db_1    mysql               5.6      cdfa8cc50c33   284 MB  
rails5product_web_1   rails5product_web   latest   42427affdec4   1.17 GB 

kill

コンテナを強制停止します。

$ docker-compose kill
Killing rails5product_web_1 ... done
Killing rails5product_db_1 ... done

logs

サービスのログを出力します。

$ docker-compose logs
Attaching to rails5product_web_1, rails5product_db_1
.....

また引数でサービス名を指定できるので、そうするとサービスごとにログを出力してくれます。

pause

サービスを一旦停止します。(一時停止したサービスは強制削除、強制開始ができずunpauseをしてからでないと作業ができなくなるので注意してください。)

$ docker-compose pause
Pausing rails5product_db_1 ... done
Pausing rails5product_web_1 ... done

port

割り当てているポートを表示します。引数でサービス名とポート番号が必要になります。

$ docker-compose port web 3000
0.0.0.0:3000

ps

コンテナの一覧を表示します。

$ docker-compose ps
       Name                      Command              State            Ports          
-------------------------------------------------------------------------------------
rails5product_db_1    docker-entrypoint.sh mysqld     Paused   3306/tcp               
rails5product_web_1   ./bin/rails server -b 0.0.0.0   Paused   0.0.0.0:3000->3000/tcp 

ちなみにdocker psでもコンテナ一覧表示ができます。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
430a9252b5ef        rails5product_web   "./bin/rails server -"   4 seconds ago       Up 2 seconds        0.0.0.0:3000->3000/tcp   rails5product_web_1
ace14a21fdca        mysql:5.6           "docker-entrypoint.sh"   4 seconds ago       Up 4 seconds        3306/tcp                 rails5product_db_1

pull

サービスのイメージをプルしてきます。今回書かれている内容だと、mysqlにしかimageが記載されてないので、mysqlのイメージのみpullしてきます。

$ docker-compose pull
Pulling db (mysql:5.6)...
5.6: Pulling from library/mysql

push

サービスのイメージをプッシュします。サービス名がwebの方ならpushができます。(dockerのregistryなどにpushする場合、事前に docker loginをしておく必要があります。)

$ docker-compose push web
Pushing web (wataru0225/rails5_product:latest)...
The push refers to a repository [docker.io/wataru0225/rails5_product]
dd109e1c2002: Preparing
9fb4d117f6f2: Preparing
17e7a11e646d: Preparing
d1223c4f56c0: Preparing
73b7de3ce7c8: Preparing
6e3fe9a92a13: Waiting
251e05a2e324: Waiting
1ad3dbeb7233: Waiting
..........

restart

コンテナを再起動します。

$ docker-compose restart
Restarting rails5product_web_1 ... done
Restarting rails5product_db_1 ... done

rm

停止中のコンテナを削除します。デフォルトだと[y/N]の確認があるのですが、-fオプションをつけることで、確認なしでコンテナを削除します。

$ docker-compose rm 
Removing rails5product_web_1 ... done
Removing rails5product_db_1 ... done

run

引数で指定したサービスのコンテナ内でコマンドを実行します。

$ docker-compose run web rails s
=> Booting Puma
=> Rails 5.0.0 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
..........

scale

サービスを実行するコンテナ数を指定します。サーバーの台数を増やしたりする時に使用します。
portsが被ると正常に実行できないので注意してください。

$ docker-compose scale web=2
Creating and starting rails5product_web_1 ... done
Creating and starting rails5product_web_2 ... done

start

サービスを開始します。これは既にコンテナがある状態でなければなりません。

$ docker-compose start
Starting db ... done
Starting web ... done

stop

サービスを停止します。

$ docker-compose stop
Stopping rails5product_web_1 ... done
Stopping rails5product_db_1 ... done

top

各コンテナのプロセス情報を表示します。

$ docker-compose top
rails5product_db_1
 PID    USER   TIME   COMMAND 
-----------------------------
26399   999    0:00   mysqld  

rails5product_web_1
 PID      USER     TIME                               COMMAND                              
------------------------------------------------------------------------------------------
26690   dockrema   0:00   bash -c rm -f tmp/pids/server.pid; ./bin/rails server -b 0.0.0.0 
26713   dockrema   0:03   {ruby} puma 3.4.0 (tcp://0.0.0.0:3000) [rails5_product]    

unpause

サービスの再開をします。pauseしている状態から復帰するのですが、pauseしている状態から復帰するにはこのコマンドが必要です。

$ docker-compose unpause
Unpausing rails5product_web_1 ... done
Unpausing rails5product_db_1 ... done

up

コンテナを作成して、起動します。オプションで-dをつけることでバックグラウンドで実行することができます。
またオプションで--buildをつけることで起動前にイメージも構築します。

$ docker-compose up
Creating rails5product_db_1
Creating rails5product_web_1
Attaching to rails5product_db_1, rails5product_web_1
.........

version

docker-composeのバージョンを表示します。

$ docker-compose version
docker-compose version 1.8.0-rc2, build c72c966
docker-py version: 1.9.0-rc2
CPython version: 2.7.9
OpenSSL version: OpenSSL 1.0.2h  3 May 2016

(※これは 2016年7月16日現在のバージョンになります。)

その他

up -d --buildをすれば、サービスのコンテナが立ち上がりサービスを開始してくれます。
またdocker-composeとコマンドを打つのが面倒な方は、エイリアスでfigとするのもお勧めします。
元はfigというツールだったようなので。(2014年7月にDocker社は、figを買収したようです。)

alias fig='docker-compose'

docker-composeはイメージ名とコンテナ名を自動で生成してくれます。ですが、railsとかだとGemとかを管理する時、ブランチを切ってbundleを実行したりしてしまうと、イメージ名に差はないのでまた新しくイメージをbuildしようとしてしまいます。差分を管理したいとかの運用法になると、自動生成はかえって便利でなくなってしまう恐れがありますね。(ベストプラクティスが思いついてはいません。。。)

参考リンク

https://docs.docker.com/compose/reference/
http://qiita.com/skyriser/items/2cf98b747ed6577cc5ee


Docker-ComposeでGitLabとRedmineとJenkinsを立ち上げる

この記事は最終更新日から1年以上が経過しています。(https://qiita.com/nexkeh/items/02a4d6c33d884bda1b23)

書店のコンピュータ関係の棚に、最近、Dockerという言葉をよく見かけるようになったので、年末年始にDockerについて調べてみました。
その中で、RedmineやらGitLabやらのイメージを取り込んで簡単に環境が構築できると知り、試しにやってみましたので、構築手順のメモを残します。

環境

  • CentOS Linux release 7.2.1511 (Core)

手順

OSの設定

CentOSのアップデート

とりあえず OSのアップデートを行います。

# yum update -y

ファイヤーウォールとSELinuxの無効化

必要なのか分かりませんがファイヤーウォールとSELinuxは無効にした方が良さそうです。

ファイヤーウォールとSELinuxの無効化
# systemctl disable firewalld
# vi /etc/selinux/config
...
SELINUX=disabled
...

再起動

設定変更後はいったん再起動を行います。

再起動
# reboot

OSバージョン

本記事掲載時のOSバージョンは以下のような感じです。

# cat /etc/redhat-release 
CentOS Linux release 7.2.1511 (Core) 

Dockerのインストール

CentOSでは、Dockerを"yum install -y docker"でインストール出来るようなのですが、この場合は最新バージョンがインストールされませんでした。
Dockerの公式サイトにある記述に従って、docker.repoファイルを作成します。

docker.repoファイルの作成
# 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=https://yum.dockerproject.org/gpg
EOF

ようやくDockerをインストールします。

dockerのインストール
# yum install docker-engine

なんかDockerのサービスを起動しておくようです。

Dockerサービスの開始
# service docker start
バージョンの確認
# docker -v
Docker version 1.9.1, build a34a1d5

Docker-Composeのインストール

Dockerでは1つのコンテナに1つの機能を持たせるのが一般的なようです。
たとえば、Redmine用のコンテナ、RedmineのMySQL用のコンテナ、GitLab用のコンテナ・・・などの感じです。
これらを一つ一つコマンドで起動させるのは面倒で仕方がないと思っていたら、当然、複数のコンテナを管理するDocker-Composeというツールがあるようなのでそちらを用います。
こちらもDockerの公式サイトに手順があるのでそのままです。

Docker-Composeを取得
# curl -L https://github.com/docker/compose/releases/download/1.5.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
実行権限を付与
# chmod +x /usr/local/bin/docker-compose

以下のコマンドを実行するとTabキーでの補完が有効になるようです。

Tabキーの補完の有効化
# curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose --version | awk 'NR==1{print $NF}')/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
バージョンの確認
# docker-compose version
docker-compose version 1.5.2, build 7240ff3
docker-py version: 1.5.0
CPython version: 2.7.9
OpenSSL version: OpenSSL 1.0.1e 11 Feb 2013

Docker-Composeで GitLabとRedmineとJenkinsの環境を用意する

Docker-Composeで一気に環境を用意します。
いろいろと調べた結果、以下のファイルを用意すればいけそうです。

docker-compose.yml

GitLabの部分はこちら
Redmineの部分はこちら
の記述を参考に、MySQLを使ったり、GITLAB_RELATIVE_URL_ROOTの設定を変更しています。
portsのオプションは、nginxでリバースプロキシを使ってアクセスできるようにしているため不要です。
その他のオプションは詳しく調べていません。

docker-compose.yml
gitlab-mysql:
  restart: always
  image: sameersbn/mysql:latest
  environment:
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production
  volumes:
    - /srv/docker/gitlab/mysql:/var/lib/mysql
gitlab:
  restart: always
  image: sameersbn/gitlab:8.3.2
  links:
    - gitlab-redis:redisio
    - gitlab-mysql:mysql
  environment:
    - DEBUG=false
    - TZ=Asia/Tokyo
    - GITLAB_TIMEZONE=Tokyo

    - GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphanumeric-string

    - GITLAB_HOST=
    - GITLAB_PORT=
    - GITLAB_SSH_PORT=
    - GITLAB_RELATIVE_URL_ROOT=/gitlab

    - GITLAB_NOTIFY_ON_BROKEN_BUILDS=true
    - GITLAB_NOTIFY_PUSHER=false

    - GITLAB_EMAIL=notifications@example.com
    - GITLAB_EMAIL_REPLY_TO=noreply@example.com
    - GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com

    - GITLAB_BACKUP_SCHEDULE=daily
    - GITLAB_BACKUP_TIME=01:00

    - SMTP_ENABLED=false
    - SMTP_DOMAIN=www.example.com
    - SMTP_HOST=smtp.gmail.com
    - SMTP_PORT=587
    - SMTP_USER=mailer@example.com
    - SMTP_PASS=password
    - SMTP_STARTTLS=true
    - SMTP_AUTHENTICATION=login

    - IMAP_ENABLED=false
    - IMAP_HOST=imap.gmail.com
    - IMAP_PORT=993
    - IMAP_USER=mailer@example.com
    - IMAP_PASS=password
    - IMAP_SSL=true
    - IMAP_STARTTLS=false
  volumes:
    - /srv/docker/gitlab/gitlab:/home/git/data
gitlab-redis:
  restart: always
  image: sameersbn/redis:latest
  volumes:
    - /srv/docker/gitlab/redis:/var/lib/redis
redmine-mysql:
  restart: always
  image: sameersbn/mysql:latest
  environment:
    - DB_USER=redmine
    - DB_PASS=password
    - DB_NAME=redmine_production
  volumes:
    - /srv/docker/redmine/mysql:/var/lib/mysql
redmine:
  restart: always
  image: sameersbn/redmine:latest
  links:
    - redmine-mysql:mysql
  environment:
    - TZ=Asia/Tokyo

    - REDMINE_PORT=
    - REDMINE_HTTPS=false
    - REDMINE_RELATIVE_URL_ROOT=/redmine
    - REDMINE_SECRET_TOKEN=

    - REDMINE_SUDO_MODE_ENABLED=false
    - REDMINE_SUDO_MODE_TIMEOUT=15

    - REDMINE_CONCURRENT_UPLOADS=2

    - REDMINE_BACKUP_SCHEDULE=
    - REDMINE_BACKUP_EXPIRY=
    - REDMINE_BACKUP_TIME=

    - SMTP_ENABLED=false
    - SMTP_METHOD=smtp
    - SMTP_DOMAIN=www.example.com
    - SMTP_HOST=smtp.gmail.com
    - SMTP_PORT=587
    - SMTP_USER=mailer@example.com
    - SMTP_PASS=password
    - SMTP_STARTTLS=true
    - SMTP_AUTHENTICATION=:login

    - IMAP_ENABLED=false
    - IMAP_HOST=imap.gmail.com
    - IMAP_PORT=993
    - IMAP_USER=mailer@example.com
    - IMAP_PASS=password
    - IMAP_SSL=true
    - IMAP_INTERVAL=30
  volumes:
    - /srv/docker/redmine/redmine:/home/redmine/data
jenkins:
  restart: always
  image: jenkins:latest
  environment:
    - JENKINS_OPTS=--prefix=/jenkins
  volumes:
    - /srv/docker/jenkins/jenkins:/var/jenkins_home
proxy:
  build: proxy
  links:
    - gitlab:gitlab
    - redmine:redmine
    - jenkins:jenkins
  ports:
    - "80:80"

Dockerfile

nginx用のDockerfile。docker-compose.ymlのproxyの部分で、このDockerfileを使ってnginxのイメージがビルドされます。

Dockerfile
# https://registry.hub.docker.com/_/nginx/
FROM nginx:latest

# 設定ファイルをコピー
COPY nginx.conf /etc/nginx/nginx.conf

# HTMLファイルをコピー
COPY index.html /usr/share/nginx/html/index.html

nginx.conf

通常だとコンテナ側のポートをホスト側のポートに割り当てるため、GitLabでは10080のポートだったり、Redmineでは10081のポートでアクセスすることになるようですが、http://127.0.0.1/gitlab などのようにアクセスしたかったので、nginxのリバースプロキシという機能を使ってみる。
docker-compose.ymlのproxyのlinksというオプションで書いた、gitlabやredmineの変数にnginx.confからアクセスできるらしい。
いろいろ試してみて以下のような感じでやりたいことが実現できた。

nginx.conf
user  nginx;
worker_processes  2;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
  worker_connections  1024;
}

http {
  include  /etc/nginx/mime.types;
  default_type  application/octet-stream;

  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
  access_log  /var/log/nginx/access.log  main;

  sendfile           on;
  keepalive_timeout  65;
  server_tokens      off;

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name 127.0.0.1;
    charset koi8-r;

    client_max_body_size 1024M;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto http;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-NginX-Proxy true;

    # static-html
    location / {
      index index.html;
      root /usr/share/nginx/html;
    }
    # gitlab
    location /gitlab {
      proxy_pass http://gitlab;
    }
    # redmine
    location /redmine {
      proxy_pass http://redmine;
    }
    # jenkins
    location /jenkins {
      proxy_pass http://jenkins:8080;
    }
  }
}

nginx.confは参考にしたサイトごとに書き方が違うため、上記が正しいかは自信がない・・・。

ディレクトリ構成

とりあえず、index.htmlは適当に作成し、上記で作成したファイルを以下のようなディレクトリ構成で配置する。

ディレクトリ構成
docker
├─ docker-compose.yml
└─ proxy
  ├─ Dockerfile
  ├─ nginx.conf
  └─ index.html

Jenkinsの共有ディレクトリの設定

なぜかJenkinsだけ、そのままだとホスト側の共有ディレクトリにコンテナ側から書き込むことができないため、chmodで1000を設定しておきます。

オーナーの変更
# mkdir -p /srv/docker/jenkins/jenkins
# chmod 1000 /srv/docker/jenkins/jenkins

Docker-Composeの実行

docker-compose.ymlを格納したディレクトリに移動し、Docker-Composeで一気にコンテナを用意します。

docker-composeの実行
# docker-compose up -d

アクセス

ブラウザから以下のアドレスでそれぞれの環境にアクセスすることができるようになります。

  • GitLab:http://127.0.0.1/gitlab
    • root/5iveL!fe
  • Redmine:http://127.0.0.1/redmine
    • admin/admin
  • Jenkins:http://127.0.0.1/jenkins

注意

まだ、実際の運用はしていませんので問題が起こる可能性があります。


Dockerコマンドをsudoなしで実行する方法

この記事は最終更新日から3年以上が経過しています。

なぜDockerコマンドにはsudoが必要なのか?

https://docs.docker.com/installation/ubuntulinux/#create-a-docker-group

The docker daemon binds to a Unix socket instead of a TCP port. By default that Unix socket is owned by the user root and other users can access it with sudo. For this reason, docker daemon always runs as the root user.

To avoid having to use sudo when you use the docker command, create a Unix group called docker and add users to it. When the docker daemon starts, it makes the ownership of the Unix socket read/writable by the docker group.

とのことで、dockerという名のグループを作ってユーザをそこに所属させればOKです。

やり方

# dockerグループがなければ作る
sudo groupadd docker

# 現行ユーザをdockerグループに所属させる
sudo gpasswd -a $USER docker

# dockerデーモンを再起動する (CentOS7の場合)
sudo systemctl restart docker

# exitして再ログインすると反映される。
exit


+ Recent posts