🐟

Docker基礎 覚書

2021/11/24に公開

Docker基本操作

docker run

コンテナを作成し実行するコマンド。
Docker hubのページを参考に、下記コマンドでNginxのコンテナを作成。

$ docker run --name some-nginx -v /hoge/content:/usr/share/nginx/html -p 8080:80 nginx
$ docker run --name [コンテナ名] -v [Docker hostのディレクトリ]:[マウント先のコンテナ内のディレクトリ] -p [Docker hostのポート]:[コンテナのポート] イメージ名

docker runは何をやってくれているのか

docker run をもう少し詳しく見ていくと、pull, create, startをまとめて実行するコマンドと言える。
実態としては run で事足りてしまうことが多いが、解像度を上げるためそれぞれ簡単に見ていく。

docker pull
対象のイメージがDocker host へダウンロードされていない場合、Docker hub からイメージをダウンロードする。

$ docker pull nginx

docker create
pullされたイメージからコンテナを作成するコマンド。
ボリュームやポート、ネットワークの指定などはコンテナごとに定義するため、オプションをつけて指定をする。

$ docker create --name some-nginx -v /hoge/content:/usr/share/nginx/html:ro -p 8080:80 nginx

docker start
作成されたコンテナを起動させるコマンド。

$ docker start some-nginx

docker exec

docker exec を使うことで、起動されているコンテナの中に入ってコマンドを実行することができる。

$ docker exec some-nginx ls
$ docker exec [コンテナ名] [実行したいコマンド]

docker runとの違い
run: 新たにコンテナを起動してコマンドを実行。実行後はコンテナが終了される。
exec: 起動されているコンテナに入ってコマンドを実行。実行後もコンテナは稼働し続ける。

オプション

--rm

コンテナが終了したタイミングで、コンテナを自動的に削除する。
docker run を実行した後にゴミコンテナが残らない。

--dit

d
バックグラウンドで実行される。(デタッチされた状態)
it
コンテナを手元の端末から操作するためのオプション

docker attach
デタッチされたコンテナにアタッチする(入る)

$ docker attach some-nginx
$ docker attach [コンテナ名]

マウント

実行するコンテナと、保管したいデータは別々で管理することが推奨されている。
作成したボリュームやDocker hostのディレクトリをコンテナ内のディレクトリへマウントをすることで、保管したいデータをコンテナから切り離すことができる。

ボリュームマウント

Docker Engine上の領域をマウントする。
保管場所には名前をつけてDocker Engineで管理されるため、開発者は物理的な場所を意識する必要がなくなる。
DBのデータを保管する場所などに利用されることが多い。
下記コマンドでボリュームを作成することができる。

$ docker volume create mysqldata
$ docker volume create [ボリューム名]

作成したボリュームにマウントする(mysqlの場合)

$ -v mysqldata:/var/lib/mysql
$ -v [ボリューム名]:[マウント先のコンテナ内のディレクトリ]

※ マウント先のディレクトリはイメージごとに指定されている。

バインドマウント

Docker host 上の実際のディレクトリをマウントする。
作業ディレクトリの変更をDockerコンテナへ即時反映したいときに便利。

Docker host 上のディレクトリにマウントする(Nginxの場合)

-v /hoge/content:/usr/share/nginx/html
-v [Docker hostのディレクトリ]:[マウント先のコンテナ内のディレクトリ

※ マウント先のディレクトリはイメージごとに指定されている。

ネットワーク

Dockerが管理するネットワークには、bridge, host, noneの3種類があり、bridgeが最もよく利用されている。

bridge

ポート転送により、Docker host上の1つのIPアドレスに対して複数のコンテナを紐付けることができる。

$ -p 8080:80
$ -p 8081:80
$ -p [Docker hostのポート]:[コンテナのポート]

※ 各コンテナで受けることができるポートは、イメージごとに決められている(nginxの場合は80番ポート)

ネットワークを作成する

$ docker network create hoge-net
$ docker network create [ネットワーク名]

作成したネットワークをコンテナに設定する

--net hoge-net
--net [ネットワーク名]

docker-compose

コンテナに関する一連の操作をまとめて実行する仕組み。
定義ファイルとコマンドを使って、複数のコンテナの設定や操作をすることができる。

定義ファイル

docker-compose.yml を使用して複数のコンテナの定義を書くことができる。
よく利用される記述のイメージを掴むため、サンプルファイルを作成。
※ そのまま使って実際に動作するファイルではないです。

version: "3.6"

services:
  db:
    image: mysql:5.7
    network:
      - hoge_net
    environment:
      MYSQL_ROOT_PASSWORD: hoge_root_path
      MYSQL_DATABASE: hoge_db
      MYSQL_USER: hoge_db_user
      MYSQL_PASSWORD: hoge_db_password
    volumes:
      - mysql_data:/var/lib/mysql
  web:
    build: .
    volumes:
      - .:/app
    network:
      - hoge_net
    ports:
      - "8080:80"
    depends_on:
      - db

networks:
  hoge_net:
volumes:
  mysql_data:

コンテナ定義

services: 作成するコンテナ名
image: イメージ名
environment: 環境変数
volume: マウントするボリューム
ports: 利用するポート
dependent_on: 起動順序の制御
build: Dockerfile のパスを指定

ネットワーク定義

利用するネットワーク名を定義する。存在しない場合は新たに作成される。
ネットワーク名を省略した場合でも、各コンテナが通信できるようネットワークが自動で作成される。

ボリューム定義

利用するボリューム名を定義する。存在しない場合は新たに作成される。

Dockerfile

独自のイメージを作成する方法の1つにDockerfileがある。

定義ファイル

FROM: ベースになるイメージを指定する
RUN: イメージをbuildする際に実行されるコマンド
CMD:コンテナを起動するタイミングで実行されるコマンド
ENTRYPOINT: コンテナを起動するタイミングで実行されるコマンド
EXPOSE: どのポートを公開する意図なのかを通知する(EXPOSEだけでは実際にはポートを公開しない)
WORKDIR: RUN, CMD, ENTRYPOINT, COPY, ADDの作業ディレクトリを指定する

CMDとENTRYPOINTの違い

どちらもコンテナを起動するタイミングで実行されるコマンド。

CMD: docker run, createの実行時に指定されたコマンドの実行を上書きすることができる
ENTRYPOINT: 指定されたコマンドは強制的に実行される(オプションで --entry-pointを指定する場合を除く)

CMDもENTRYPOINTも、Dockerfile内で一度しか使えず複数箇所に記述されている場合は最後の記述のみ有効になる。

使い分けのポイントはいまいち理解できていない。

参考

GitHubで編集を提案

Discussion