Table of Contents

モチベーション

Dockerのライフサイクル

Dockerイメージを用意する

Dockerイメージを元に,コンテナを立ち上げる

DockerコンテナのPID=1問題

docker runで指定した<commnad>は,PID=1のプロセスとして実行される.PID=1なプロセスはカーネルから特別扱いされるため,プロセス自体がシグナルをハンドルするように実装されていなければ,シグナルは無視されてしまう.

例えば,docker kill -s TERM <container>を実行することで,PID=1のプロセスにSIGTERMを投げることができるが,PID=1のプロセスのシグナルのハンドルの仕方によって振る舞いが異なる.

PID=1のプロセスがシグナルをハンドルするように実装するのもよいが,プロセスがPID=1以外で実行されれば,シグナルを素直に受け付けるので,<command>で指定したプロセスをPID=1以外にするためには,docker runを実行する際に,--initオプションを指定すると良い.

# docker run -it centos bash
[root@a31d57ca765c /]# ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  1.5  0.1  12020  3348 pts/0    Ss   13:38   0:00 bash   <======== `bash`がPID=1で実行されている
root        14  0.0  0.1  47508  3520 pts/0    R+   13:38   0:00 ps -aux

# docker run -it --init centos bash
[root@52ec324240f8 /]# ps -axu
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  1.0  0.0    996     4 pts/0    Ss   13:39   0:00 /sbin/docker-init -- bash
root         7  0.0  0.1  12020  3336 pts/0    S    13:39   0:00 bash   <======== `bash`がPID=1以外で実行されている
root        16  0.0  0.1  44596  3388 pts/0    R+   13:39   0:00 ps -axu

起動中のコンテナを停止させる

停止したコンテナを立ち上げる

コンテナをrestartさせる

停止中のコンテナをDockerイメージとして保存する

Dockerイメージをtarで固めて持ち運ぶ

停止しているコンテナを破棄する

ローカルのDockerイメージを破棄する

コンテナとホスト間でファイルをコピーする

コンテナ内でstdout/stderrされたものを外部から見る

Docker for Mac

Linuxでは,Dockerエンジンをホスト上で直接実行しているが,Docker for Macでは,Mac上にVMを立ち上げてその上でDockerエンジンを実行している. 例えば,docker volume lsでvolume名を取得し,そのvolumeがmountされている場所をdocker volume inspect <volume name>で確認すると,以下のようなMountpointを取得することができる.ただし,MountpointはMac上には存在せず,VMからみたパスである.

$ docker volume ls
DRIVER    VOLUME NAME
local     xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
...
$ docker volume inspect xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[
    {
        "CreatedAt": "2019-12-21T05:10:05Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/_data",
        "Name": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "Options": null,
        "Scope": "local"
    }
]

Dockerfileの書き方

Dockerfileとは,docker buildのための手順書のようなもの.Dockerfileを元にオリジナルのDockerイメージをつくることができる.

FROM nginx:latest
ENV HOGE FUGA
ARG AHO=DEFAULT
RUN apt-get update && \
    apt-get install -y certbot python-certbot-nginx && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    ln -sf  /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    echo $AHO
WORKDIR /workspace
ADD nginx.conf /etc/nginx/
ADD default.conf /etc/nginx/conf.d/
EXPOSE 80 443

docker-compose.ymlでコンテナを複数立ち上げる

複数のコンテナをまとめて立ち上げたいときは,docker-composeを使う.

docker-compose.ymlを書く

version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - 8080:80
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./www/html:/var/www/html
    depends_on:
      - php

  php:
    build: 
      context: ./php
      args:
        - TZ=${TZ}
    container_name: php-fpm
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    volumes:
      - ./www/html:/var/www/html
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=db
      - DB_DATABASE=${DB_NAME}
      - DB_USERNAME=${DB_USER}
      - DB_PASSWORD=${DB_PASS}
      - TZ=${TZ}
    depends_on:
      - db

  db:
    image: mysql:5.7
    expose:
      - 9999
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
    environment:
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_PASS}
      - MYSQL_ROOT_PASSWORD=${DB_PASS}
      - TZ=${TZ}

docker-compose.ymlを元にコンテナを立ち上げたり止めたりする