【再読】プログラマのためのDocker教科書を読んだ

業務ではdockerを使ってないけれど、業界で流行っていることは抑えていたほうがいいと思ったので読みました。簡単に環境構築もできるし、プライベートでの開発や技術技術調査で積極的に使っていきたいなー。

本としては、Dockerのことだけを語っているわけではなく、システム・インフラの基礎知識や仮想化についても章を設けられているので、自分みたいな初心者でも知識を習得・再整理しながら読むことができる。一定の知識がある人ならば、すっ飛ばしてDockerについてだけ読むことももちろんできる。

基本的なコマンドの説明からDockerイメージを作成できるDockefile、複数コンテナの一元管理できるDocker Composeも章として設けてある。 この本を一通り読めば、Dockerについて理解できるし、わからなくなったときの辞書としても使えそう。

以下は自分が読んでメモした部分

Dockerの基本操作

DockerでHello world

まずはDockerでHello worldをやってみる

docker run ubuntu:latest /bin/echo 'Hello world'

このコマンドは、ubuntuのDockerイメージを起動し、Docker内部でHello worldを表示している。 runコマンドは意味的にも実行するだけかと思いきや、ローカル環境にDockerコンテナのもとになるubuntuの Dockerイメージがあるか確認してくれて、なければダウンロードまでしてくれる便利なコマンド

ubuntu:latestは最新バージョンを取ってきて、という命令です。 あとはechoコマンドでHello worldを表示しろというそのままの意味です。

runコマンドにはオプションがあり、よく使うものをまとめておく。 -it コンテナの中にログインして操作ができる iはコンテナの標準入力を開く、tはtty(端末デバイス)を使うとなる。

yoshitakuMBA:~ yoshitaku$ docker run -it centos /bin/bash
[root@274130fac9fa /]# 

仮にオプションを外してbashしてみても、コンテナの中には入れない。

yoshitakuMBA:~ yoshitaku$ docker run centos /bin/bash
yoshitakuMBA:~ yoshitaku$ 

-d コンテナをバックグラウンドで実行できる -p コンテナのポート番号とホストOSのポート番号をマッピングすることができる

docker run -d --name nginx -p 8080:80 nginx

この場合、バックグラウンドでnginxを起動し、ポート番号8080と80をマッピングしている

コンテナの起動・停止

dockerコンテナを作成・起動・停止するためのコマンドを書いておく

docker start <コンテナの識別子>
docker stop <コンテナの識別子>

コンテナの識別子を確認するためのコマンドは docker ps -adocker statsがある。 docker ps -a-aオプションを付けることで、起動停止問わずすべてのコンテナを表示できる docker statsは起動中のコンテナだけを表示することができる

起動しているDockerコンテナの操作

docker attachdocker execがある

Docker内部にログインするという意味では、どちらも同じ だけどコマンドが別れているのにはちゃんと意味がある。

https://qiita.com/RyoMa_0923/items/9b5d2c4a97205692a560

docker attachは、プロセス1に接続させてもらうのに対して、 docker execは、新しくプロセスを作成して、それを利用してコンテナ内部に入るイメージ

docker ps -a #コンテナIDを調べる。起動していなければ、IDを覚えておく
docker start <コンテナ識別子> #コンテナを起動
docker attach <コンテナ識別子>
docker ps -a #コンテナIDを調べる。起動していなければ、IDを覚えておく
docker start <コンテナ識別子> #コンテナを起動
docker exec -it centos /bin/bash

Dockerfileの基本

DockerfileはDockerイメージを作るときに使われる。

Dockerfileからイメージを作成するときはdocker buildコマンドを使う。

docker build -t [イメージ名]:[タグ名] [dockerfileが置いてあるディレクトリ]

dockerファイルのビルドの注意

dockerfileを引数に指定していたら、unable to prepare contextが発生。 unable to prepare contextはファイル名まで書いてしまっているエラー。 dockerfileをビルドする際は、置いてあるディレクトリまでで大丈夫。

基本構成

命令 引数の基本構文で成り立っている。

FROM命令

FROM命令は必ず記述しなければいけない必須項目 ベースとなるOSのことを書くところ。 FROM ubuntu:latest

MAINTAINER命令

必須ではないけど、誰が作ったかとか連絡先を書いておく。 Docker Hubのように公開する場合は、書いておいたほうがいい MAINTAINER yoshitaku

FROM ubuntu:latest

MAINTAINER yoshitaku

RUN命令

FROM命令で指定したベースイメージに対して、「アプリケーション・ミドルウェアのインストールをする」「環境構築のためのコマンドを実行する」と言った、コマンドを実行するときにRUN命令を使う。

RUN命令はDockerイメージを生成するときに実行される。 RUN apt-get update RUN apt-get install -y apache2 RUN apt-get install -y mysql-server

Docker Composeについて

Docker Composeは複数のコンテナを一元管理したいときに使われる。 実際のwebシステムでは一つのサーバが一つの機能を持って使われることが多く、Dockerを使ってwebシステム環境を再現したいときなどに使うと便利。

ド定番のwordpressをDockerComposeでやってみる webサーバとDBサーバと、データを格納する専用コンテナを作成する。 データを格納する専用コンテナは、標準的なLinuxコマンドをまとめたBusyBoxと呼ばれるアプリケーションがあるのでコレを使って構築する。

FROM busybox

VOLUME /var/lib/mysql

イメージの作成 docker build -t dataonly .

データ専用コンテナの起動 docker run -it --name dataonly dataonly

Docker Composeは「docker-compose.yml」にシステム内で稼働するサーバの設定をまとめて定義する。 docker-compose.ymlの書き方はyamlの形式で書く。 portsのxx:xxの形式は文字列にしないと、時刻表期とみなされてしまうらしいので注意 ちゃんとダブルクォートで囲む

webserver:
    image: wordpress
        ports:
            - "80:80"
        links:
            - "dbserver:mysql"
dbserver:
    image: mysql
        volumes_from:
            - dataonly
    environment:
            MYSQL_ROOT_PASSWORD: password

docker-compose upで下のログが出れば成功

Starting test_dbserver_1 ... done
Starting test_webserver_1 ... done
Attaching to test_dbserver_1, test_webserver_1
dbserver_1   | 2018-03-23T16:18:37.321903Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
dbserver_1   | 2018-03-23T16:18:37.324429Z 0 [Note] mysqld (mysqld 5.7.21) starting as process 1 ...
dbserver_1   | 2018-03-23T16:18:37.330983Z 0 [Note] InnoDB: PUNCH HOLE support available
dbserver_1   | 2018-03-23T16:18:37.331048Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
dbserver_1   | 2018-03-23T16:18:37.331055Z 0 [Note] InnoDB: Uses event mutexes
dbserver_1   | 2018-03-23T16:18:37.331060Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
dbserver_1   | 2018-03-23T16:18:37.331065Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.3
dbserver_1   | 2018-03-23T16:18:37.331069Z 0 [Note] InnoDB: Using Linux native AIO
dbserver_1   | 2018-03-23T16:18:37.332053Z 0 [Note] InnoDB: Number of pools: 1
dbserver_1   | 2018-03-23T16:18:37.332300Z 0 [Note] InnoDB: Using CPU crc32 instructions
dbserver_1   | 2018-03-23T16:18:37.335841Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
dbserver_1   | 2018-03-23T16:18:37.355688Z 0 [Note] InnoDB: Completed initialization of buffer pool
dbserver_1   | 2018-03-23T16:18:37.359681Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
dbserver_1   | 2018-03-23T16:18:37.375230Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
dbserver_1   | 2018-03-23T16:18:37.410157Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
dbserver_1   | 2018-03-23T16:18:37.410289Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
dbserver_1   | 2018-03-23T16:18:37.516884Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
dbserver_1   | 2018-03-23T16:18:37.517994Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
dbserver_1   | 2018-03-23T16:18:37.518044Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
dbserver_1   | 2018-03-23T16:18:37.518586Z 0 [Note] InnoDB: Waiting for purge to start
dbserver_1   | 2018-03-23T16:18:37.568983Z 0 [Note] InnoDB: 5.7.21 started; log sequence number 12318893
dbserver_1   | 2018-03-23T16:18:37.569887Z 0 [Note] Plugin 'FEDERATED' is disabled.
dbserver_1   | 2018-03-23T16:18:37.578776Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
dbserver_1   | 2018-03-23T16:18:37.580825Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
dbserver_1   | 2018-03-23T16:18:37.593695Z 0 [Warning] CA certificate ca.pem is self signed.
dbserver_1   | 2018-03-23T16:18:37.596636Z 0 [Note] InnoDB: Buffer pool(s) load completed at 180323 16:18:37
dbserver_1   | 2018-03-23T16:18:37.597075Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
dbserver_1   | 2018-03-23T16:18:37.597149Z 0 [Note] IPv6 is available.
dbserver_1   | 2018-03-23T16:18:37.597182Z 0 [Note]   - '::' resolves to '::';
dbserver_1   | 2018-03-23T16:18:37.597221Z 0 [Note] Server socket created on IP: '::'.
dbserver_1   | 2018-03-23T16:18:37.611096Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.611244Z 0 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.611261Z 0 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.612975Z 0 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.613019Z 0 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.613050Z 0 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.658200Z 0 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.658279Z 0 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
dbserver_1   | 2018-03-23T16:18:37.740459Z 0 [Note] Event Scheduler: Loaded 0 events
dbserver_1   | 2018-03-23T16:18:37.741266Z 0 [Note] mysqld: ready for connections.
dbserver_1   | Version: '5.7.21'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
webserver_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
webserver_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
webserver_1  | [Fri Mar 23 16:18:38.341326 2018] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.25 (Debian) PHP/7.2.3 configured -- resuming normal operations
webserver_1  | [Fri Mar 23 16:18:38.342818 2018] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'

localhostにブラウザでアクセスすれば、いつもの画面が出てくる

まとめ

  • Dockerについて一通りのことが学べた
  • Dockerfileの書き方がわかった。
  • docker-composeを使ってwordpressを構築できた

これからは、社内で使うハンズオン資料をdockerで作ってみたいと思います。