手を動かしてみたらDockerをざっくりと理解できた件。

Dockerについては、

  1. コンテナ型の仮想化技術である
  2. アプリケーションの環境をコンテナに閉じ込めてポータブルにできる。
  3. そのため、ホスト OS上の1プロセスで動作するものである
  4. VMWareVirtualBoxのようなホストOSの上でゲストOSを動かすわけではないので、動作が軽い

これぐらいの知識がある程度で始めました。

特に最初の2つのイメージが湧かなかったので、その辺りを身をもって実感するためにいろいろと試してみました。


はじまりはいつもここから
https://docs.docker.com/docker-for-mac/


まずはインストール
https://docs.docker.com/docker-for-mac/install/

$ docker --version
Docker version 17.06.0-ce, build 02c1d87

OK

次にnginxを動かしてみる

$ docker run -d -p 80:80 --name webserver nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
94ed0c431eb5: Pull complete
9406c100a1c3: Pull complete
aa74daafd50c: Pull complete
Digest: sha256:788fa27763db6d69ad3444e8ba72f947df9e7e163bad7c1f5614f8fd27a311c3
Status: Downloaded newer image for nginx:latest
3728cb8621a5504423e833b7b8d14c02842a44b1886f1e150082f58d54205d0

ローカルにイメージがなければ、勝手にDocker Hubから Dockerイメージをダウンロードする模様

コンテナプロセスを確認してみる

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
3728cb8621a5        nginx               "nginx -g 'daemon ..."   4 minutes ago       Up 4 minutes        0.0.0.0:80->80/tcp   webserver

動いているのを確認


コンテナを止めて、再起動してみる

$ docker stop webserver
webserver
$ docker start webserver
webserver

webserverコンテナを削除してみる(nginxイメージは残る)

$ docker rm -f webserver
webserver
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              b8efb18f159b        7 days ago          107MB
hello-world         latest              1815c82652c0        7 weeks ago         1.84kB

一括でコンテナを削除

docker rm $(docker ps -aq)

イメージも削除してみる

$ docker rmi nginx
Untagged: nginx:latest
Untagged: nginx@sha256:788fa27763db6d69ad3444e8ba72f947df9e7e163bad7c1f5614f8fd27a311c3
Deleted: sha256:b8efb18f159bd948486f18bd8940b56fd2298b438229f5bd2bcf4cedcf037448
Deleted: sha256:ba49ddf19ae3c9d08d348b3f621faca9c2bf4030a28f249af512d76fc9010cb9
Deleted: sha256:7b8885a6166d207114b95dacfe115f9cf8fd023e69bd0d4d1ca30736cf03ca15
Deleted: sha256:eb78099fbf7fdc70c65f286f4edc6659fcda510b3d1cfe1caa6452cc671427bf

macでは~/Library/Containers/com.docker.docker/Data あたりにイメージファイルなどが保存される模様

テスト用のhello-world イメージを削除しようとすると、怒られる。

$ docker rmi hello-world
Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container 3e350518xxxx is using its referenced image 1815c826xxxx

実際には、

$ docker stop eager_shannon
$ docker rmi {image_id}

としないといけないといけない


ubuntu コンテナをベースにapache + php7環境のコンテナを作ってみる

公式のubuntuコンテナをダウンロード

$ docker pull ubuntu
; lampという名前のコンテナをubuntuイメージからdetachモードで作成してbashを起動
$ docker run -itd --name lamp ubuntu bash

; シェルに入る
$ docker attach lamp

; Dockerのubuntu コンテナにphp mysql apache2を入れてイメージを作成する
# apt-get update
# apt-get -y install apache2
# a2enmod ssl
# a2ensite default-ssl
# apachectrl restart
# apt-get install apt-file
# apt-file update
# apt-get install software-properties-common
# add-apt-repository ppa:ondrej/php
# apt-get update
# apt-get install php7.1
# apt-get install php7.1-mysql
# apt-get install php7.1-imagick
# apt-get install php7.1-mbstring
# apt-get install php7.1-bz2
# apt-get install php7.1-xml
# apt-get install php7.1-sqlite
# apt-get install php7.1-intl
# apt-get install php7.1-xdebug
# apt-get install php7.1-memcache
# apt-get install php7.1-redis
# apt-get install php7.1-mongo
# apt-get install php7.1-gd
# apt-get install vim
# apt-get install git
# vi /var/www/html/index.php
# apt-get install sysv-rc-conf
# exit 
; my-apache-php7という名前でコンテナをイメージとして作成
$ docker commit {container_id} my-apache-php7
; 一度containerを削除
$ docker rm {container_id}
MYSQLのコンテナを作成する
$ docker pull mysql/mysql-server
$ docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=secret -d mysql/mysql-server:5.7

#mysqlコンテナのIPアドレスを調べる

$ docker inspect mysql-container | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.3",
                    "IPAddress": "172.17.0.3",

#他のコンテナから利用できるようにgrantを発行

$ docker exec -it mysql-container mysql -uroot -p
mysql> grant all on *.* to root@"172.17.%" identified by "secret";
mysql> flush privileges;

#アプリケーション側からは下記のような形で接続できる

$link = mysqli_connect("172.17.0.3", "root", "secret", "mysql”); //php

#作成したイメージからコンテナを作成してapacheを起動

$ docker run -itd -p 8080:80 --name webserver my-apache-php7 apachectl -D FOREGROUND
#ソースファイルをデプロイ
$ docker exec -it webserver git clone https://github.com/chienowa/docker-test.git /var/www/html/app
# pullする場合
$ docker exec -it webserver bash -c "cd /var/www/html/app && git pull"
# ファイルコピーする場合(mysql接続用ファイルをコンテナにホストからコピー)
$ docker cp mysql.php 1349871fa1ff:/var/www/html/

これでなんとなく、Dockerイメージの作成、コンテナの使い方、ソースのデプロイ方法のイメージが掴めたかな!?



dockerのインストールからコンテナ利用を試行錯誤してみてわかったことをまとめてみました。

  • Dockerコンテナは1つのフォアグラウンドで動くサービスと、そのサービスが依存するライブラリ/モジュールとで構成されるものという理解が、一番ベストプラクティスに近い気がする
  • dockerのコンテナとはアプリケーション環境の複数のプロセスをまとめるものではなく、apache+phpとそのモジュールたち、rubyとgemとrails、など、1プロセスに必要な依存ソフトウェアをコンテナにまとめるのが正しい使い方という理解
  • 1コンテナ内でapachemysqlを二つのサービスを起動させることはできない
  • monitやsupervised を使えば複数のサービスを使えるが、本来的な使い方ではなさそう。
  • たとえばmysqlは別ポートで起動する1サービスなので、別コンテナとして利用するのが本来的な使い方。
  • DockerfileはDockerイメージをビルドするための Infra As a Codeみたいなもの(Vagrantfileに近い)→※今後試す
  • いろんなツールをインストールして、一つのDockerイメージを作り込む(イメージが重くなる)というよりは、軽いベースイメージを元に、Dockerfileで都度イメージを作成するためのもの
  • 本来的にはDockerfileを使ってテキストファイルでセットアップ手順を記述し、コンテナをビルドすると言う形が管理上好ましい
  • 各コンテナは172.17.0.x のようなプライベートIPを振られるので、それを使ってコンテナ間通信ができる。
  • 複数コンテナを管理する際はdocker compose を使ってyamlで複数のコンテナ管理を記述すれば、便利に管理できる!→※今後試す

つぎはAWS ECS上でコンテナを動かしてみようと思います。