はじめに
Dockerの勉強をしたのでメモ
環境
Ubuntu Linux 24.04.2 LTS
Docker version 28.1.1, build 4eba377
インストール
Ubuntu上でCLIで動けばよいので、Docker公式の Docker Engineインストール方法 からインストール
「Install using the apt repository」という項目のスクリプトをコピペするだけでインストールできる。
基礎知識
- Dockerコンテナ内で起動するプログラムは、PID:1番が割り当てられている
- 「イメージ」はDockerHubなどからダウンロードしたり、自分で作ったりする。
持ち出すときはdocker container exportやdocker image saveなどでtarファイルを作る。 - イメージは「レイヤー」が重ね合わさってできている。
- 「Dockerfile」は、イメージにレイヤーを追加するときの作業指示書みたいなもの。
よく使うコマンド
コンテナの操作
- コンテナを起動してbashを使う
$ docker container run \ --name ubuntu \ #コンテナの名前を指定 --rm \ #コンテナを終了したら、コンテナを削除 --interactive \ # コンテナにターミナル(コンソール)を接続 --tty \ # コンテナにターミナル(コンソール)を接続 --publish 8080:80 \ #ホストマシンの8080番ポートをコンテナの80番ポートに紐づけ公開 --env PASSWORD='ABC' \ #環境変数を設定 ubuntu \ #コンテナに使用するイメージ名 bash \ # コンテナ内で実行するコマンド。ここではbashを起動している
コンテナの停止
$ docker container stop ubuntu
ubuntu は、コンテナ起動時に--name ubuntuで指定した名前
ほかにはCONTAINER IDも指定できる実行中のコンテナ一覧
$ docker container ls
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3ee91464c2bc ubuntu "bash" 7 seconds ago Up 6 seconds ubuntu
停止中のコンテナ一覧
$ docker container ls --allコンテナの停止
$ docker container rm ubuntu ubuntu -> コンテナ名。CONTAINER ID`でもよい起動中のコンテナの停止
$ docker containe rm --force ubuntuコンテナのコンソール出力の確認
$ docker container logs コンテナ名|コンテナID
※コンテナは起動中または停止中であることコンソール出力の継続監視であれば
$ docker container logs --follow コンテナ名起動中のコンテナで別のコマンドを実行
$ docker container exec \ ubuntu \ #コンテナ名 head -4 /etc/os-release # 実行したいコマンド(例)
イメージ関連
- ホストマシンに持っているイメージの一覧
$ docker image ls
$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE my-php pdo_mysql 0494e541a2c8 2 days ago 551MB
イメージの取得
$ docker image pull ubuntu:23.10イメージの詳細確認
$ docker image inspectコンテナ -> イメージ作成
$ docker container commit 作成元コンテナ名 作成後コンテナ名:タグ
例$ docker container commit ubuntu new-ubuntu:commit
※コンテナは起動中または停止中コンテナ -> tar
$ docker container export --output tarファイル名 コンテナ名
例$ docker container export --output export.tar ubuntu
※コンテナは起動中または停止中tar -> イメージ
$ docker image import tarファイル名 コンテナ名:tag
例$ docker image import export.tar new-ubuntu:import
※イメージ -> tar -> イメージ の方法では、レイヤが一つにまとまる。また元のメタデータは欠如するイメージ -> tar
$ docker image save --output tarファイル名 イメージ名:タグ
例$ docker image save --output save.tar ubuntu:22.04tar -> イメージ
docker image load --input tarファイル名
例$ docker image load --input save.tar
※docker image import と docker image load の違い
| image import | image load | |
|---|---|---|
| レイヤー | 残らない | 残る |
| メタデータ | 残らない | 残る |
| セットで使われるコマンド | container export | image save |
※docker container export -> コンテナから作ったtarファイル -> docker image importで読み込む
docker image load では読み込めない
※docker image save -> イメージから作ったtarファイル -> docker image loadで読み込む
docker image import でも読み込めるが...
ストレージ(ボリューム)の作成
Dockerで管理するストレージ(volume)と、ホストマシンのディレクトリをマウントする(bind)がある
volume(ボリューム)
Dockerで管理するストレージ(volume)
- ボリュームの一覧
` $ docker volume ls
ボリュームを作る
$ docker volume create --name my-volumeボリュームをコンテナ起動時にマウントする
$ docker container run --mount type=volume,source=my-volume,destination=my-volume イメージ名
-- mount でなく、短縮形-vも使える
docker container run -v my-volume:/my-volume イメージ名
- ボリュームの削除
$ docker image rm ボリューム名
bind(バインドマウント)
ホストマシンのディレクトリをマウントする(bind)
$ docker container run --mount type=bind,source=./my-bind,destination=/my-bind イメージ名
ネットワークの作成
コンテナ間の通信を行うための通信路を作る
ネットワークの一覧
$ docker network lsネットワークの作成
$ docker network create my-networkコンテナ起動時にネットワークをマウント
$ docker container run --network my-network イメージ名確認
$ docker container inspect コンテナ名 | less
Networksの項目に、マウントしたネットワーク名が記載されている
Docker Hub
Docker公式イメージはDocker Hubで探す
Dockerfile
- Dockerfile というファイル名に書く
FROM ubuntu:22.04 RUN apt-get update RUN apt-get instal -y vim ENV MYSQL_ROOT_PASSPORD=secret COPY ./aaa /home/ubuntu/aaa CMD ["cat", "/home/ubuntu/aaa"]
FROM -> 元になるイメージ名
RUN -> 実行するコマンド
ENV -> 環境変数(書式は[キー:値])
COPY -> イメージを作る際にファイルをコピーする
CMD -> コンテナ起動後に実行するコマンド
※apt ではなく apt-get を使う(apt-getのほうが余計なメッセージ出力が無いからとのこと)
- RUNなどの命令ごとに1レイヤ作られる
イメージサイズを小さくするため、コマンドをまとめたほうがいい
FROM ubunt:22.04 RUN apt-get update && apt-get install -y vim
- Dockerfileを元にイメージを作る
$ docker image build --tag my-ubuntu:22.04 .
--tag -> イメージ名とタグ名
. -> 今いるディレクトリ内のDockerfile ファイルを使用する 。
※--file ファイル名とすることで、イメージ作成に使うDockerfileを指定できる
例:$ docker image build --tag my-ubuntu:22.04 --file Dockerfile_renamed .
(--fileはファイル名を指定する。そのファイルが存在するパスは.で指定する)
Docker Compose
複数のコンテナの起動を、docker コマンドでなく設定ファイルで管理する
- ファイル名はcompose.yamlが推奨されている
よく使うコマンド
- コンテナの作成と起動 -> compose up
- コンテナの停止と削除 -> compose down
- コンテナの一覧 -> compose ps
- 起動中のコンテナでコマンドを実行 -> compose exec
例:
- コンテナの起動
$ docker compose up --detach --build
-- detach -> バックグラウンドで起動
-- build -> Dockerfileに基づいて、イメージのビルドも行う
コンテナの一覧表示
$ docker compose ps
$ docker container ls
※$ docker compose psは、compose.yamlのあるディレクトリまたはその配下のディレクトでしか実行できない
(他のプロジェクトのコンテナは表示されないようになっている)起動中のコンテナでコマンドを実行する
$ docker compose exec サービス名
$ docker compose exec app bash
※--interactive--ttyオプションは不要起動中のコンテナの停止
$ docker compose down
※ネットワークとコンテナが停止する。ボリュームは残る。
$ docker compose down --rmi all --volumes
--rmi all -> ビルドしたイメージを削除する
--volumes -> ボリュームを削除する
環境変数を使う
プロジェクトディレクトリに .env というファイルを作成して、環境変数に設定したいキーと値を書く
例:
$ cat .env APP_HOST_MACHINE_PORT=8000 DB_ROOT_PASSWORD=secret DB_USER=app DB_PASSWORD=pass1234 DB_DATABASE=sample DB_HOST_MACHINE_PORT=3306 MAIL_HOST_MACHINE_PORT=8025
compose.yamlファイルには、${キー名} という書式で書く
services:
app:
ports:
- "8000:8000"
-> "${APP_HOST_MACHINE_PORT}:8000"
環境変数を展開した
compose.yamlを確認する
$ docker compose convert変数にはデフォルト値をセットすることもできる
${APP_HOST_MACHINE_PORT:-8000}:8000(変数が未定義か空なら8000を設定する)変数にはエラーメッセージを表示できる
"MYSQL_PASSWORD=${DB_PASSWORD:?.envを見直してください}"(変数が未定義か空ならエラーメッセージを表示する)
まとめ
$ docker で個々のコンテナの動作を確認し、
$ docker compose で複数のコンテナを起動させるのね