UdemyでDockerを学ぶ③ 〜Section3〜(Docker Compose編)

リンクバル技術部の川畑です。開発環境をDockerに移行するため勉強中。前回の記事UdemyでDockerを学ぶ② 〜Section2〜では、Dockerイメージの管理などのレッスンが中心でした。今回はDockerコンテナでアプリケーションを起動したり、複数のDockerコンテナのリンク、Docker Composeを利用した複数Dockerコンテナの一元管理などのレッスンが中心となります。それでは見ていきましょう。

目次

「Section3: Create Dockerized Web Applications」の内容

Section3の内容は以下の通り。

  • 17.Dockerize a Simple Hello World Web Application
  • 18.Text Direction: Dockerize a Hello Web Application
  • 19.Implement a Simple Key-value Lookup Service
  • 20.Create Docker Container Links
  • 21.Automate Current Workflow with Docker Compose
  • 22.Trouble Shooting: Automate Current Workflow with Docker Compose
  • 23.Deep Dive into Docker Compose Workflow

17. Dockerize a Simple Hello World Web Application

  • Pythonのフレームワーク「Flask」を使って”Hello, World!”と表示させるアプリケーションを作成
  • コードはあらかじめGitHubリポジトリ

Gitリポジトリクローン

[bash] git clone -b v0.1 https://github.com/jleetutorial/dockerapp.git
cd dockerapp
[/bash]

Dockerfileの内容

  • Dockerfileに定義するユーザーはデフォルトユーザーとUIDが競合しないよう、常にUSERを定義することが推奨されている
[bash] FROM python:3.5
RUN pip install Flask==0.11.1
RUN useradd -ms /bin/bash admin
USER admin
COPY app /app
WORKDIR /app
CMD ["python", "app.py"] [/bash]

Dockerを使ってアプリケーションサーバ起動

[bash] ※Dockerイメージ作成
ubuntu@ubuntu-xenial:~/dockerapp$ docker build -t dockerapp:v0.1 .
Sending build context to Docker daemon 167.9 kB
Step 1 : FROM python:3.5
—>; 4e5ed9f6613e
Step 2 : RUN pip install Flask==0.11.1
—>; Using cache
—>; 3a0ebeae3c9f
Step 3 : RUN useradd -ms /bin/bash admin
—>; Using cache
—>; ef83ba62fdd6
Step 4 : USER admin
—>; Using cache
—>; e19ebff2acb4
Step 5 : WORKDIR /app
—>; Using cache
—>; 9d37bc0b4185
Step 6 : COPY app /app
—>; Using cache
—>; 2c9f1067bd55
Step 7 : CMD python app.py
—>; Using cache
—>; 02200eaeec10
Successfully built 02200eaeec10

※Dockerコンテナ起動
ubuntu@ubuntu-xenial:~/dockerapp$ docker run -d 02200eaeec10
540f7feb3929d7586f42d81d9479951439e73f145e67fb2dffd34c40cc6e356b

※Dockerコンテナをバックグラウンドで起動
ubuntu@ubuntu-xenial:~/dockerapp$ docker run -d -p 11088:5000 02200eaeec10
7868af91e20103195ac21750086fc279f4fa3f5b7752092407d50074384b750c
ubuntu@ubuntu-xenial:~/dockerapp$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7868af91e201 02200eaeec10 "python app.py" 30 seconds ago Up 30 seconds 0.0.0.0:11088->;5000/tcp zen_mirzakhani
540f7feb3929 02200eaeec10 "python app.py" About a minute ago Up About a minute berserk_swirles

※Dockerコンテナに接続
ubuntu@ubuntu-xenial:~/dockerapp$ docker exec -it 4d14d4b58248 bash
admin@4d14d4b58248:/app$ ls
app.py
admin@4d14d4b58248:/app$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
admin 1 0.5 2.4 102288 24500 ? Ss 04:32 0:00 python app.py
admin 6 0.1 0.3 21932 3628 ? Ss 04:33 0:00 bash
admin 19 0.0 0.2 19188 2360 ? R+ 04:33 0:00 ps aux
admin@4d14d4b58248:/app$
[/bash]

表示はこんな感じ

18. Text Direction: Dockerize a Hello Web Application

  • ファイルダウンロードのみ

19. Implement a Simple Key-value Lookup Service

  • Dockerで簡単なKey-valueシステムを作成

Gitチェックアウト

[bash] ubuntu@ubuntu-xenial:~/dockerapp$ git stash && git checkout v0.2
No local changes to save
Previous HEAD position was 905df5b… initial commit
HEAD is now at 81b086a… simple key value lookup
[/bash]

Dockerを使ってアプリケーションサーバ起動

[bash] ※Dockerイメージ作成
ubuntu@ubuntu-xenial:~/dockerapp$ docker build -t dockerapp:v0.2 .
Sending build context to Docker daemon 170.5 kB
Step 1 : FROM python:3.5
—>; 4e5ed9f6613e
Step 2 : RUN pip install Flask==0.11.1
—>; Using cache
—>; 3a0ebeae3c9f
Step 3 : RUN useradd -ms /bin/bash admin
—>; Using cache
—>; ef83ba62fdd6
Step 4 : USER admin
—>; Using cache
—>; e19ebff2acb4
Step 5 : WORKDIR /app
—>; Using cache
—>; 9d37bc0b4185
Step 6 : COPY app /app
—>; Using cache
—>; 52423858b1a9
Step 7 : CMD python app.py
—>; Using cache
—>; 86f70f2e4875
Successfully built 86f70f2e4875

※Dockerコンテナをバックグラウンドで起動
ubuntu@ubuntu-xenial:~/dockerapp$ docker run -d -p 11080:5000 dockerapp:v0.2
622b1380ffc6ea0b2905e1b4f32a3125958272267d21871185f06a1c4af7b45f
ubuntu@ubuntu-xenial:~/dockerapp$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
622b1380ffc6 dockerapp:v0.2 "python app.py" 3 minutes ago Up 3 minutes 0.0.0.0:11080->;5000/tcp nauseous_turing

※Dockerコンテナに接続
ubuntu@ubuntu-xenial:~/dockerapp$ docker exec -it 622b1380ffc6 bash
admin@622b1380ffc6:/app$ ls -alF
total 16
drwxr-xr-x 3 root root 4096 Mar 19 04:52 ./
drwxr-xr-x 1 root root 4096 Jun 2 22:22 ../
-rw-rw-r– 1 root root 563 Mar 19 04:49 app.py
drwxrwxr-x 2 root root 4096 Mar 19 04:49 templates/
admin@622b1380ffc6:/app$ exit
[/bash]

表示はこんな感じ

そしてここからRedisを使っていきます

20. Create Docker Container Links

  • DockerアプリのコンテナとRedisのコンテナをリンクしてKey-valueシステムを作成

Dockerコンテナリンクのイメージ

Gitチェックアウト

[bash] ubuntu@ubuntu-xenial:~/dockerapp$ git stash && git checkout v0.3
No local changes to save
Previous HEAD position was 81b086a… simple key value lookup
HEAD is now at 21cca93… introduce redis
[/bash]

Dockerを使ってアプリケーションサーバ起動

[bash] ※Dockerイメージ作成
ubuntu@ubuntu-xenial:~/dockerapp$ docker run -d –name redis redis:3.2.0
8424d5ae3e613a13a9bc62718f49a347685bb9e343beff401194ddc4bdf4bc29

ubuntu@ubuntu-xenial:~/dockerapp$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8424d5ae3e61 redis:3.2.0 "docker-entrypoint.sh" 39 seconds ago Up 39 seconds 6379/tcp redis

※Dockerイメージ作成
ubuntu@ubuntu-xenial:~/dockerapp$ docker build -t dockerapp:v0.3 .
Sending build context to Docker daemon 171 kB
Step 1 : FROM python:3.5
—> 4e5ed9f6613e
Step 2 : RUN pip install Flask==0.11.1 redis==2.10.5
—> Using cache
—> 807cc52a5625
Step 3 : RUN useradd -ms /bin/bash admin
—> Using cache
—> ea95aa9d64ba
Step 4 : USER admin
—> Using cache
—> 1247387a79e1
Step 5 : WORKDIR /app
—> Using cache
—> f1b0310122e5
Step 6 : COPY app /app
—> Using cache
—> 9c4800200cc7
Step 7 : CMD python app.py
—> Using cache
—> 4da6511a49cb
Successfully built 4da6511a49cb

※Dockerコンテナをバックグラウンドで起動
ubuntu@ubuntu-xenial:~/dockerapp$ docker run -d -p 11080:5000 –link redis dockerapp:v0.3
2c6d1e3b70356d1575cea849cd205a4b3801a1303939e172f21c5277544ee966
[/bash]

How container links work beind the scenes?

[bash] ubuntu@ubuntu-xenial:~/dockerapp$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0e9521c6c389 dockerapp:v0.3 "python app.py" 4 minutes ago Up 4 minutes 0.0.0.0:11088->;5000/tcp sleepy_engelbart
66862b73d651 redis:3.2.0 "docker-entrypoint.sh" 6 minutes ago Up 6 minutes 6379/tcp redis

※「/etc/hosts」を確認。Dockerコンテナ「redis」のコンテナ名とコンテナIDが設定されている。
ubuntu@ubuntu-xenial:~/dockerapp$ docker exec -it 2c6d1e3b7035 bash
admin@2c6d1e3b7035:/app$ cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 redis 8424d5ae3e61
172.17.0.3 2c6d1e3b7035
admin@2c6d1e3b7035:/app$ exit
exit

※Dockerコンテナ「redis」のIPアドレスを確認
ubuntu@ubuntu-xenial:~/dockerapp$ docker inspect 8424d5ae3e61 | grep IP
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"IPAMConfig": null,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,

※Dockerコンテナ「Redis」へのpingの確認
ubuntu@ubuntu-xenial:~/dockerapp$ docker exec -it 2c6d1e3b7035 bash
admin@2c6d1e3b7035:/app$ ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.075 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.098 msadmin@0e9521c6c389:/app$
[/bash]

Benefits of Docker Container Links(Dockerコンテナリンクの利点)

  • The main use for docker container links is when we build an application with a microservice architecture, we are able to run many independent components in different containers.(マイクロサービスアーキテクチャーを使用して異なるコンテナで多くの独立したコンポーネントを実行できる)
  • Docker creates a secure tunnel between the containers that doesn’t need to expose any ports externally on the container.(コンテナ間のセキュアな通信)

21. Automate Current Workflow with Docker Compose

Why Docker Compose?

  • Manual linking containers and configuring services become impractical when the number of containers grows.(コンテナの数が増えるにつれて全てのコンテナリンクを手動でするのは現実的でない)

Docker Composeの説明

  • https://docs.docker.com/compose/overview/
  • Docker ComposeはDockerコンテナリンクの設定を自動化するもの

Docker Composeのインストール手順

  • https://docs.docker.com/compose/install/

Docker Composeのymlファイル(docker-compose.yml)

[bash] version: ‘2’
services:
dockerapp:
build: .
ports:
– "11080:5000"
volumes:
– ./app:/app

redis:
image: redis:3.2.0
[/bash]

Docker Composeによる起動

[bash] ※Gitチェックアウト
ubuntu@ubuntu-xenial:~/dockerapp$ git stash && git checkout v0.4
No local changes to save
Previous HEAD position was 21cca93… introduce redis
HEAD is now at b3823ad… introduce docker compose

※Docker Composeバージョン確認
ubuntu@ubuntu-xenial:~/dockerapp$ docker-compose version
docker-compose version 1.11.2, build dfed245
docker-py version: 2.1.0
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t 3 May 2016

※Docker ComposeによるDockerコンテナリンクの起動
ubuntu@ubuntu-xenial:~/dockerapp$ docker-compose up
Starting dockerapp_redis_1
Recreating dockerapp_dockerapp_1
Attaching to dockerapp_redis_1, dockerapp_dockerapp_1
redis_1 | _._
redis_1 | _.-“__ ”-._
redis_1 | _.-“ `. `_. ”-._ Redis 3.2.0 (00000000/0) 64 bit
redis_1 | .-“ .-“`. “`\/ _.,_ ”-._
redis_1 | ( ‘ , .-` | `, ) Running in standalone mode
redis_1 | |`-._`-…-` __…-.“-._|’` _.-‘| Port: 6379
redis_1 | | `-._ `._ / _.-‘ | PID: 1
redis_1 | `-._ `-._ `-./ _.-‘ _.-‘
redis_1 | |`-._`-._ `-.__.-‘ _.-‘_.-‘|
redis_1 | | `-._`-._ _.-‘_.-‘ | http://redis.io
redis_1 | `-._ `-._`-.__.-‘_.-‘ _.-‘
redis_1 | |`-._`-._ `-.__.-‘ _.-‘_.-‘|
redis_1 | | `-._`-._ _.-‘_.-‘ |
redis_1 | `-._ `-._`-.__.-‘_.-‘ _.-‘
redis_1 | `-._ `-.__.-‘ _.-‘
redis_1 | `-._ _.-‘
redis_1 | `-.__.-‘
redis_1 |
redis_1 | 1:M 04 Jun 01:16:43.092 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1 | 1:M 04 Jun 01:16:43.093 # Server started, Redis version 3.2.0
redis_1 | 1:M 04 Jun 01:16:43.093 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add ‘vm.overcommit_memory = 1’ to /etc/sysctl.conf and then reboot or run the command ‘sysctl vm.overcommit_memory=1’ for this to take effect.
redis_1 | 1:M 04 Jun 01:16:43.093 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command ‘echo never > /sys/kernel/mm/transparent_hugepage/enabled’ as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
redis_1 | 1:M 04 Jun 01:16:43.093 * The server is now ready to accept connections on port 6379
dockerapp_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

※「docker ps」でコンテナ起動状況を確認
ubuntu@ubuntu-xenial:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c9f8d1a7b181 dockerapp_dockerapp "python app.py" 28 seconds ago Up 27 seconds 0.0.0.0:11080->5000/tcp dockerapp_dockerapp_1
33170006eaf2 redis:3.2.0 "docker-entrypoint.sh" 10 weeks ago Up 27 seconds 6379/tcp dockerapp_redis_1
[/bash]

Docker Composeの利点

  • Docker compose is a very handy tool to quickly get docker environment up and running.(Docker ComposeはDocker環境を素早く起動する)
  • Docker compose uses yaml files to store the configuration of all the containers, which removes the burden to maintain our scripts for docker orchestration.(Docker環境の構成管理を簡単に)

22. Trouble Shooting: Automate Current Workflow with Docker Compose

  • 本レッスンを進める時に発生したエラーの対処方法

23. Deep Dive into Docker Compose Workflow

  • 主にdocker-composeコマンドの説明

docker-composeコマンド

  • 「docker-compose up」:starts up all the containers.
  • 「docker-compose ps」:checks the status of the containers managed by docker compose.
  • 「docker-compose logs」:outputs colored and aggregated logs for the compose-managed containers.
  • 「docker-compose logs -f」:with dash f option outputs appended log when the log grows.
  • 「docker-compose logs dockerapp」:with the container name in the end outputs the logs of a specific container.
  • 「docker-compose stop」:stops all the running containers withouot removing them.
  • 「docker-compose rm」:removes all the containers.
  • 「docker-compose build」:rebuilds all the images.

※「docker-compose up」はbuildしないのでDockerfileのuserを変更しても反映されない(build時のユーザーが使用される)

おわりに

今回は主にDocker Composeを利用したDockerコンテナのの管理について学びました。ここまで来てとようやくDockerをどのように利用して開発環境で利用するかのイメージが湧くようになってきました。

リンクバルでは エンジニアを積極募集中 です。興味のある方のご応募お待ちしております。