どこでビルドしてもデプロイしてもImmutableインフラ(不変の)なので変更したい場合はDockerfileの方を変える
コンテナはOS上のDockerEngine上に配置する(コンテナは複数配置できる、Dockerfileさえあれば再現可)
DockerfileでなくてもDockerイメージでもいいが、Dockerは可搬性をもたらすのである
docker container run --name コンテナ名003 -d -p 8083:80 イメージ名httpd
■仮想NW
コンテナ間をつなぐ(ネットワークタグ名で紐づける感じ)
1)ブリッジネットワーク(デフォルト
同一の Docker Engine 上のコンテナ が互いに通信をする場合に利用する
デフォルト:
全てのコンテナ間をリンクする操作が必要
コンテナ間の通信は IP アドレスで
●(コレ使う)ブリッジネットワークを定義し作成:
相互通信は同じネットワークを割り当てるだけ
コンテナ間でDNS解決される
ネットワークでコンテナは隔離され隔離度が上がる
2)オーバーレイネットワーク
異なる Docker Engine 上のコンテナ が互いに通信をする場合に利用
docker network create ネットワーク名net001
↓
docker container run --name mysql001 -dit --net=net001 ~~~ イメージ名mysql
docker container run --name wordpress001 -dit --net=net001 -p 8085:80 -e WORDPRESS_DB_HOST=mysql001 ~~~ イメージ名wordpress
Docker仮想NW一覧
docker network ls
仮想NWの確認
docker network inspect net001
コンテナ間はservice_nemeで通信し、コンテナ名ではない
http://unco-sv:8000 で通信できる
各コンテナで同番ポートを使っていても問題はない
docker info プロキシ等が確認できる
.docker/config.json でプロキシやプロキシを使わないnoProxyを設定
■停止
docker stop コンテナ名
docker rm コンテナ名
docker network rm ネットワーク名
■コピー OS⇔コンテナ
docker cp コピー元 コピー先
例)docker cp /home/a.txt コンテナ名:/app/
■ボリュームのマウント
データをコンテナ内に置くとコンテナが消えるとデータも消えてしまう
永続化1)ボリュームマウント:DockerEngine上
永続化2)バインドマウント:OS上
永続化3)一時メモリマウント:(tmpfs)
■バインドマウント
docker volume create ボリューム名vol001
docker run --name コンテナ名httpd001 -d -p 8080:80 -v /home/a:/usr/local/apache/htdocs イメージ名httpd (OS側パス:コンテナ側パス、コンテナ側のパスをどこにすべきかはDockerイメージのドキュメントを見よ)
docker volume inspect vol001 (確認できる)
docker volume rm vol001
ホストディレクトリ共有ともいう
コンテナはrootで動作しているものが多く
ホスト共有しているDir/Fileにコンテナから変更するとrootで変更しPermissionが変わるそのためホストディレクトリ共有は本番に向かない
■ボリュームマウント
ちょい面倒らしいのでバインドマウントでいいのでは?
docker volume create ボリューム名vol001
docker run --name コンテナ名httpd001 -d -p 8080:80 -v ボリューム名vol001:/usr/local/apache/htdocs イメージ名httpd (OS側パス:コンテナ側パス)
docker volume inspect vol001 (確認できる)
docker volume rm vol001
Dockerボリューム共有ともいう
コンテナが削除されても明示的に消さない限り保持される
永続化したいパスを指定してマウントできる
(通常コンテナ内で作成されたデータは永続化しない)
■揮発的データを退避
docker cp コンテナ名:ファイルパス ホスト側退避パス
docker cp test-db-a:/opt/test.txt /tmp/config
消えるファイルをホスト側に退避したいときのコマンド
■ボリュームマウントの確認やOS側にバックアップ
アプリコンテナとは別のshellコンテナを用意してlsしたりtar.gz等する
Apacheコンテナ <-> vol001 <- Linuxコンテナ -> vol002バックアップ
マウントを2つ(DockerEngine上のマウント、OS上のマウント)
tar.gzコピーでDockerEngine上の指定フォルダにコピーするが其れはOS側にもマウントされている、最後のドットも要る
イメージは軽量Linuxのbusyboxを使用
docker run --rm -v vol001:/usr/local/apache/htdocs -v /home/b:/tmp busybox tar CXvf /tmp/bjk.tar.gz -C /usr/local/apache/htdocs .
■ログ
docker logs コンテナ名
docker logs -f コンテナ名 追従確認
docker exec -t コンテナ名 /bin/bash ログファイル等はこれで入り確認
■Appコンテナ(PHP)
docker container run \
--name app \ コンテナにappと名付る
--rm \ コンテナ停止時に自動削除
--detach \ バックグラウド実行
--interactive \ 対話可能なセッションに
--tty \ コンテナとのTTY接続しコマンド出力可
--mount type=bind,src=$(pwd)/src,dst=/src \ osにバインドマウント
--publish 18000:8000 \ ポートマッピング
--network docker-sample-network \ 仮想NWに割り当て
docker-php:app \ Dockerイメージの名前とタグ
php -S 0.0.0.0:8000 -t /src コンテナ内で実行するコマンド
※永続化バインドマウントos上
ホストマシンのディレクトリをコンテナ内のディレクトリにバインドマウント。ホストマシンのカレントディレクトリ($(pwd))の"src"ディレクトリが、コンテナ内の"/src"ディレクトリにマウントされます
※ポートマッピング
-p, --publishがコンテナのポートをホストマシンに公開するオプション
ホストマシンの18000ポートを通じてコンテナの8000ポートにアクセスさせる
ブラウザからhttp://localhost:18000 でphpにアクセス
※起動コマンド
PHPのビルトインウェブサーバを起動し、IPアドレス "0.0.0.0" およびポート "8000" でリクエストを受け付け、コンテンツを"/src"ディレクトリから提供します
■コンテナの詳細情報の確認
docker container inspect app
■DBコンテナ(MySQL)
docker container run \
--name db \
--rm \
--detach \
--platform linux/amd64 \
--env MYSQL_ROOT_PASSWORD=rootpassword \
--env MYSQL_USER=hoge \
--env MYSQL_PASSWORD=password \
--env MYSQL_DATABASE=event \
--mount type=volume,src=docker-db-volume,dst=/var/lib/mysql \
--mount type=bind,src=$(pwd)/docker/db/init.sql,dst=/docker-entrypoint-initdb.d/init.sql \
--network docker-sample-network \
--network-alias db \
docker-db:db
※仮想NWでのエイリアス名
dbと名付ける
■コンテナの疎通の確認
$ docker container exec --interactive --tty app ping db -c 3
appコンテナがdbに疎通できるかping
■アプリ
/// BANGBOO BLOG /// - GCP script 下の方に記載あり
■Dockerfile
ビルドしてイメージを作成
FROM イメージ名
COPY コピー元パス コピー先パス
RUN Linuxのコマンド
ENTRYPOINT イメージを実行するときのコマンド
CMD コンテナ起動時に実行する規定のコマンドを指定
例えばこのコマンドを実行するCMDは
$ go run /echo/main.go
↓空白で分割し配列化しCMD化される
CMD["go", "run", "/echo/main.go"]
ただCMDは下記のように実行中に上書き指定ができ echo yayの実行となる
docker container run $(docker image build -q .) echo yay
ONBUILD ビルドが完了したときに任意の命令を実行する
EXPOSE 通信を想定するポートをイメージの利用者に伝える
VOLUME 永続データが保存される場所をイメージ利用者に伝える
ENV 環境変数を定義する
WORKDIR RUN/CMD/ENTRYPOINT/ADD/COPYの際の作業ディレクトリ
SHELL ビルド時のシェルを指定
LABEL 名前やバージョンや制作者情報等を設定
USER RUN/CMD/ENTRYPOINT実行するユーザやグループを設定
ARG docker buildする際に指定できる引数を宣言
STOPSIGNAL docker stopの際にコンテナで実行しているプログラムに対して送信するシグナルを変更する
HEALTHCHECK コンテナの死活確認をするヘルスチェックをカスタマイズする
社内のDockerfileのベストプラクティスを公開します│FORCIA CUBE│フォルシア株式会社RUN adduser -D myuser && chown -R myuser /myapp
(-Dはデフォルト設定で追加している、-Rは指定dir以下を再帰的に所有権変更)
USER myuser
(以降のRUNやENTRYPOINT等のINSTRUCTIONを実行するユーザを指定)
Dockerセキュリティベストプラクティス トップ20:究極ガイドDockerfileの作り方を考え直したらすごく効率が上がった。 (zenn.dev)■ビルドでイメージを作成
Dockerfileや材料ファイルのあるフォルダパスを最後に指定、-tはタグでイメージ名
docker build -t img_httpd001 ./
ビルド後にdocker runが必要
docker container run -d --name cnt_httpd001 -v ${pwd}:/app img_httpd001:latest
↓これが便利
docker container run -rm --name cnt_httpd001 -v ${pwd}:/app img_httpd001:latest
■commitでコンテナからイメージを作成
コンテナにexecで幾つかインスコする操作をしてからイメージにする等ができる
docker commit httpd001 img_httpd001
■コンテナ/イメージはDockerEngine上から移動できない
saveするとファイル化され、できるようになる
docker save -o save_img_httpd001.tar img_httpd001
ファイルからイメージとして取り込みたいときはdocker load
ファイル化せずにパブリックならDocker hubへ登録してもよい、プライベートレジストリを作ってもよい
その中にそれぞれリポジトリを持つ > docker push レジストリ/リポジトリ名:バージョン
■コンテナに命令する
2つの方法がある
1)docker exec → docker container execに変わった
起動中のコンテナ内でコマンドを実行する
docker container exec [option] <container> command
ファイルを見る
docker container exec ubuntu1 cat ~/hello.txt
コンテナに接続してbashを使う
docker container exec --interactive --tty ubuntu1 bash
2)docker run に引数を付ける→ソフトウェア(apache)が動いていない状態になり改めてdocker startが必要
docker exec -it コンテナ名httpd001 /bin/bash
apt install mysql-server など対話でコンテナにインスコできる
exit 抜ける
■Docker compose
docker runコマンドの集合体、コンテナ等作って消すだけ(k8sはコンテナ等を管理する)
以前はdocker-composeコマンドで別ツールだったが今は統合済み
フォルダに1つだけdocker-compose.yml
基本はdocker runを実行せずにdocker composeしたい
手順は、1)Docker run方法で一応の検討>2)docker-compose.ymlの記述>3)docker composeコマンドの実行
docker run~~に対するdocker-compose.ymlとdocker composeコマンド の対比
1)docker run --name cnt_wordpress001 -dit --net=net001 -v wordpress001vol2:/var/www/html -p 8080:80 -e WORDPRESS_DB_HOST=mysql001 -e WORDPRESS_DB_NAME=wpdb001 -e WORDPRESS_DB_USER=wpu001 -e WORDPRESS_DB_PASSWORD=my-secret-pw wordpress
↓
2) docker-compose.ymlの記述
version: "3"
services:
cnt_wordpress001:
depends_on:
- cnt_mysql001
image: wordpress
networks:
- net001
volumes:
- wordpress001vol2:/var/www/html
ports:
- 8080:80
restart: always
environment:
WORDPRESS_DB_HOST=mysql001
WORDPRESS_DB_NAME=wpdb001
WORDPRESS_DB_USER=wpu001
WORDPRESS_DB_PASSWORD=my-secret-pw
cnt_mysql001:
image: mysql:5.7
networks:
- net001
volumes:
- mysql001vol1:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD=my-root-pw
MYSQL_DATABASE=wpdb001
MYSQL_USER=wpu001
MYSQL_PASSWORD=my-secret-pw
networks:
net001
volumes:
mysql001vol1:
wordpress001vol2:
/// restartの設定値(コンテナが停止した時にどうするか?)
no =何もしない
always =必ず再起動する
on-failure =プロセスが0以外のステータスで終了したときは再起動する
unless-stopped =停止していたときは再起動しないがそれ以外は再起動する
Bashで終了ステータスよる条件分岐 | Codebase Blog ※bashは前に実行されたコマンドの終了ステータスは「$?」で取得できるが慣習的にコマンドが正常終了した場合は0を返す
/// その他の定義項目
command =起動時の規定コマンドを上書きする
entrypoint =起動時のENTRYPOINTを上書きする
env_file =環境設定情報のファイルを読み込む
他 container_name / dns / eternal_links / extra_hosts / logging / network_mode etc.
3)docker compose コマンド
up=イメージDL、コンテナ/nw/volの作成・起動
down=コンテナとnwの停止と削除、volとイメージは残る
stop=削除せず停止のみ
docker compose -f /home/a/docker-compose.yml up -d
docker compose up -d --scale unco001=3 (コンテナ名はput-folder-name_unco001_1, put-folder-name_unco001_2, put-folder-name_unco001_3になる)
-f ファイルの場所(省略でカレントパス)
-d バックグラウンド実行
--build コンテナ開始前にビルド
--no-build イメージが見つからなくてもビルドしない
-t コンテナ停止のタイムアウト(デフォ10S)
--force-recreate 設定やイメージに変更が無くてもコンテナを再生成
--no-create コンテナが存在していれば再生成しない
--abort-on-container-exit コンテナが一つでも停止したら全てのコンテナを停止
--remove-orphans 定義ファイルで定義されていないコンテナを削除
--scale 同じコンテナを複数作る
docker compose -f /home/a/docker-compose.yml down
--rmi {all | local} 破棄後にイメージも削除、localの時はimageにカスタムタグが無いイメージのみを削除
-v volumesに記載されているボリュームを削除、但しexternalの指定を除く
--remove-orphans 定義ファイルで定義されていないコンテナを削除
docker compose -f /home/a/docker-compose.yml stop
コンテナを停止
■Docker composeはコンテナ名を勝手につける
docker-compose.yml内は下記の通り、DockerEngine上のコンテナ名は変わるがdocker-compose.yml内のコンテナ名は変わず指定できる
services:
unco001
~
unco002
namespaceで分離し
ファイル構造、ユーザーID、グループID、コマンド、ライブラリなど諸々を
ラップしコンテナ化し(単一の)プロセスとして動く
↓
Dockerがやっている仕事は少ない
区切ってコンテナ
それら仮想ネットワークで繋ぐ
ボリュームの永続化
Dockerfileでイメージからイメージを作成
Docker composeでdocker runを記述
docker execでコンテナを操作
etc.