Slide 1

Slide 1 text

エキサイトHD 2022年度新卒技術研修 D o c k e r 講 義 + ハ ン ズ オ ン ~ d o c k e r f i l e の 読 み 方 か ら コ ン テ ナ の 起 動 、 操 作 ま で ~

Slide 2

Slide 2 text

自己紹介 ・文系出身 趣味でちょこっとrails触ってました ・業務では フレームワークを使わない、 いにしへのピュアなPHPシステムを触っ ています iXIT株式会社 テクノロジー戦略室 エンジニアリンググループ 新卒2年目 趣味はゲーム 休日はほぼスプラトゥーンに溶かし ています(スプラ3が楽しみです) エペは少しだけ 大学時代は、芸術工学部で音楽(オ ーケストラのマネジメント)につい て勉強してました レガシーな舞台芸術業界をDXしたい 野望があります 渡邊 都

Slide 3

Slide 3 text

技術研修、配属後の業務で支障なくDocker 環境を使いこなせるようになる 今 日 の ゴ ー ル 配属されてから、業務用のローカル環境を、用意さ れたドキュメント・Dockerfileをもとに構築できる 構築中のトラブルシューティングが出来る ローカル環境の立ち上げ、ボリュームについて理解 し、基本的なコマンドが扱える コンテナが立ち上がらない… コンテナ同士が通信できない… こ こ を 目 指 し て く だ さ い →

Slide 4

Slide 4 text

目次 01 Dockerってなぁに コンテナの仕組み 02 Dockerfileの読み方 03 docker compose 04 Docker環境構築の ベストプラクティス 05

Slide 5

Slide 5 text

補足:今回のハンズオンで想定して いる環境 Nginx (web) Laravel (app) mysql (db) 9000 80 3306 tech_training 3000 Nuxt フロントとバックエンドのリポジトリが分かれている(別々のdocker-compose.ymlで立ち上げ る) フロント⇔バックエンドの通信のために、「tech_trainning」という同じネットワーク内に置かれ ている ※資料内では便宜的に、左側をフロント側、右側をAPI側(バックエンド側)と呼んでいます

Slide 6

Slide 6 text

01 Dockerって なぁに

Slide 7

Slide 7 text

D o c k e r は 軽 量 仮 想 化 技 術 0 1 . D o c k e r っ て な ぁ に プロセス プロセス ゲストOS ゲストOS 仮想化ソフトウェア ホストOS プロセス プロセス コンテナ コンテナ リソースを共有 仮想マシン コンテナ技術 仮想マシン(VMなど) …1台のサーバーを多数のサーバーに変えるための物理ハードウェアの抽象概念 Docker(コンテナ) …ハードウェアでなくOSシステムの仮想化。アプリケーション層の抽象概念。

Slide 8

Slide 8 text

Dockerを利用する意義 ・環境の共通化(可用性) ・開発環境の標準化 ・CI/CDの促進 環境の共通化(可用性) アプリケーションの実行環境を、ホストにある他のプロセスから隔離する(仮想化) →本番環境と同じような環境をローカルにも再現する。どこに持って行ってもOSレベルで同じ 依存関係を再現。 開発環境の標準化 同じDockerfileを使えば、誰のマシンでも同じ環境を構築できる CI/CDの促進 dockerの可用性を活かした、AWSのECSやcircleCI等のツールとの親和性(コンテナごとデプロイ) D o c k e r は 何 の た め に 0 1 . D o c k e r っ て な ぁ に

Slide 9

Slide 9 text

準備物の確認 ・Dockerのデスクトップツールはインストールされていますか? ・適当なシェル(ターミナルでもphp stormやVSコード付属のものでも)とエディタを起動し ておいてください ※本資料では、講義に利用したdocker-compose.ymlなどのファイルは公開致しませんのでご了 承ください ※フロント・APIを別リポジトリ構築するパターンについて、下記を参考にしておりますので、 ネットワーク関連のdockerコマンドを試したい場合は下記を参考にして下さい https://zenn.dev/nagi125/articles/7d01336868c79654b4af ハ ン ズ オ ン : p a r t 0 0 1 . D o c k e r っ て な ぁ に

Slide 10

Slide 10 text

02 コンテナの 仕組み

Slide 11

Slide 11 text

dockerイメージ スナップ ショット スナップ ショット スナップ ショット dockerfile dockerイメージ プロセス D o c k e r コ ン テ ナ の ラ イ フ サ イ ク ル 0 2 . コ ン テ ナ の 仕 組 み プロセス commit build ローカル Docker Hub pull start rm commit run stop down 停止中コンテナ 起動中コンテナ コンテナ破棄 (compose up)

Slide 12

Slide 12 text

API側のイメージをビルドしてみましょう ・docker compose build(docker-compose.ymlで定義されたコンテナの 一括ビルド) (単体コンテナのbuildは、docker buildですが、今回は、API環境の3コン テナを一気にビルドしたいため) ハ ン ズ オ ン : p a r t 1 0 2 . コ ン テ ナ の 仕 組 み

Slide 13

Slide 13 text

ハ ン ズ オ ン : p a r t 1 たまにやる失敗 「docker compose」系のコマンドを打つディレクトリが違う →「docker-compose 」系のコマンドはdocker-compose.ymlがあるディレクトリで実 行しましょう 「なにも触ってないのに急にコマンド効かなくなったんだけど?!」と思ったらまず カレントディレクトリを疑って下さい 0 2 . コ ン テ ナ の 仕 組 み API側のイメージをビルドしてみましょう ・docker compose build(docker-compose.ymlで定義されたコンテナの 一括ビルド)

Slide 14

Slide 14 text

D o c k e r イ メ ー ジ と コ ン テ ナ 0 2 . コ ン テ ナ の 仕 組 み Dockerイメージは動作環境テンプレート Dockerfileをビルドすることで生成される Docker Hubから入手(Pull)してくることも可能 Dockerコンテナの実行に必要なLinuxファイルシステムとメタ情報を含む

Slide 15

Slide 15 text

Dockerイメージは動作環境テンプレート Dockerfileをビルドすることで生成される Docker Hubから入手(Pull)してくることも可能 Dockerコンテナの実行に必要なLinuxファイルシステムとメタ情報を含む D o c k e r イ メ ー ジ と コ ン テ ナ 0 2 . コ ン テ ナ の 仕 組 み Dockerコンテナの実行に必要な Linuxファイルシステムとメタ情報を含む とは

Slide 16

Slide 16 text

D o c k e r の 仕 組 み 0 2 . コ ン テ ナ の 仕 組 み dockerはOSの仮想化= 端的に言うと、Linuxカーネルを共有している カーネル目線では、コンテナ一つ一つは単なる Linuxのプロセス OSっぽい挙動に必要なライブラリと、それを動 かすカーネルをホストから流用することでOSの ようなふるまいをするコンテナができている 衝突を防ぐために、namespaceやcgroupsといっ たLinuxカーネルの機能を利用してプロセスを隔 離 Linuxカーネル ubuntuの ライブラリ群 centOSの ライブラリ群 Dockerイメージ としてパッケージ化 ubuntuが起動 してるわけじゃないけど ubuntuっぽい動きをする Dockerデーモン Dockerホスト(隔離された空間) (ホストPCなんだけど) クライアント Docker CLI ①「docker run」して! ②了解!

Slide 17

Slide 17 text

D o c k e r イ メ ー ジ の レ イ ヤ ー 構 造 0 2 . コ ン テ ナ の 仕 組 み Docker イメージは、Dockerfile に記述された RUN や ADD 命令などを実行した結 果、ファイルシステム上に加えられた変更をレイヤとして生み出す

Slide 18

Slide 18 text

Dockerの「ユニオンファイルシステム」 D o c k e r イ メ ー ジ の レ イ ヤ ー 構 造 0 2 . コ ン テ ナ の 仕 組 み 読み込み専用のイメージレイヤー (Dockerイメージ) 読み書き可能なコンテナレイヤー ファイルA ファイルB ファイルC ファイルC ファイルA ファイルB 仮想的な、一つのファイルシステム

Slide 19

Slide 19 text

読み込み専用のイメージレイヤー (Dockerイメージ) ファイルA ファイルB 読み書き可能なコンテナレイヤー ファイルC 読み書き可能なコンテナレイヤー ファイルC Dockerが軽量な理由の一つ「ユニオンファイルシステム」 D o c k e r イ メ ー ジ の レ イ ヤ ー 構 造 0 2 . コ ン テ ナ の 仕 組 み 読み書き可能なコンテナレイヤー ファイルC 共有しているイメージレイヤーに対する コンテナ上のファイルの更新は 「コピーオンライト」 コンテナ内にコピーされ、変更が反映 レイヤー構造的に上位にあるため 「ファイルA'」が優先 ファイルA'

Slide 20

Slide 20 text

0 2 . コ ン テ ナ の 仕 組 み Docker イメージ内のレイヤー構造は 「docker history」 コマンドで確認できる Docker イメージは、Dockerfile に記述された RUN や ADD 命令などを実行した結 果、ファイルシステム上に加えられた変更をレイヤとして生み出す docker history {イメージ名、イメージID} イメージの一覧:docker images buildkit.dockerfileとコメントがついているところが、dockerfileの記載によって実行さ れた部分です ハ ン ズ オ ン : p a r t 2

Slide 21

Slide 21 text

dockerイメージ スナップ ショット スナップ ショット スナップ ショット dockerfile dockerイメージ プロセス D o c k e r コ ン テ ナ の ラ イ フ サ イ ク ル プロセス commit build ローカル Docker Hub pull start rm commit run stop down 停止中コンテナ 起動中コンテナ コンテナ破棄 (compose up) ←ここの中身を 確認しました

Slide 22

Slide 22 text

D o c k e r イ メ ー ジ の レ イ ヤ ー 構 造 0 2 . コ ン テ ナ の 仕 組 み Docker イメージ内のレイヤー構造は 「docker history」 コマンドで確認できる Docker イメージは、Dockerfile に記述された RUN や ADD 命令などを実行した結 果、ファイルシステム上に加えられた変更をレイヤとして生み出す 欲しい実行環境を得るために、必要なものを、 必要なだけDockerfileに書いて積み重ねてるんだなぁ、という理解で大丈夫です では実際にDockerfile を読んでみましょう→

Slide 23

Slide 23 text

03 Dockerfileの 読み方

Slide 24

Slide 24 text

D o c k e r f i l e は 怖 く な い 0 3 . D o c k e r f i l e の 読 み 方 実行環境に必要なものってなんだと思いますか? WebサーバーならApacheとかNginXとか… gitやVimもあった方が便利 PHPを動かしたいなら、PHPそのものと関連パッケージ 上記のパッケージを管理する、パッケージ管理システムも要りますね DBならDBMSが必要 『ホストPCとコンテナ内のファイルシステムは別』ということは、エディタで書いた ソースや設定ファイルをコンテナ内にコピーしてやる必要もあります

Slide 25

Slide 25 text

D o c k e r f i l e は 怖 く な い 実行環境に必要なものってなんだと思いますか? WebサーバーならApache gitやVimもあった方が便利 PHPを動かしたいなら、PHPそのものと関連ライブラリ ↑ このライブラリを管理する、パッケージ管理システムも要りますね DBならDBMSが必要 『ホストPCとコンテナ内のファイルシステムは別』ということは、エディタで書いた ソースや設定ファイルをコンテナ内にコピーしてやる必要もあります これらをいい感じにまとめて書いている 指示書です 0 3 . D o c k e r f i l e の 読 み 方

Slide 26

Slide 26 text

D o c k e r f i l e 読 ん で み よ う 今回の研修に使用するPHPコンテナの例 FROM:ベースにするイメージの指定 一から全部必要なものを書き出すのは大変なので、 定番の環境はdocker hubに定番のイメージがあることが多いです (公式のイメージを積極的に利用しましょう) COPY:ホストからコンテナ内にファイルをコピー 左の例では、php.iniなどの設定ファイルをコピーしています RUN:指定したコマンドを実行する aptやyarmなどパッケージを取ってくるためのパッケージ管理ツールで 必要なライブラリに更新をかけたり、インストールすることが多いで す WORKDIR:ワークディレクトリ(カレントディレクトリ)を指定 他によく使うもの VOLUME:コンテナで作成したデータをホストのファイルシステムを マウントしてデータを置く (コンテナ内の変更がホストにも反映されるディレクトリを指定) 0 3 . D o c k e r f i l e の 読 み 方 --from=composerはマルチステージビルドです 公式のcomposerイメージから、composerを取ってきています 手元で/api/docker/php/Dockerfileを開きながら聞いてください

Slide 27

Slide 27 text

04 docker compose

Slide 28

Slide 28 text

web app DB docker compose の役割 よくある環境:web、app、DBの3つのコンテナを同時に動かす 一つずつ docker runで起動するとが面倒 コンテナ間通信のために環境を整える必要がある ymlファイルと、docker composeコマンドで手軽に、複数コンテナを動かすことができ る 0 4 . d o c k e r c o m p o s e

Slide 29

Slide 29 text

Dockerのブリッジネットワークの (簡単な)概念図 ホストマシン 仮想NIC コンテナ1 コンテナ2 仮想ブリッジ (docker0) (veth1) (veth2) (eth0:veth1peer) (eth0:veth2peer) 仮想NIC (eth0) Dockerホスト docker composeでは、デフォルトでコンテナ起動時にブリッジネットワークを組む 0 4 . d o c k e r c o m p o s e

Slide 30

Slide 30 text

docker composeの何が便利なのか? ホストマシン 仮想NIC コンテナ1 コンテナ2 仮想ブリッジ (docker0) (veth1) (veth2) (eth0:veth1peer) (eth0:veth2peer) 仮想NIC Dockerホスト 経路2が使える ドメインの指定にコンテナ名が使える コンテナのIPアドレスは(固定化の設定を入れなければ)コンテナ起動するたびに変わります host.docker.internalは、コンテナ→ホストの指定であることを覚えておきましょう(dockerでちょっと古い資料を 漁っていると目にします) appからdbへの接続がうまくいかない…時はどういう経路をたどっているか確認しましょう コンテナ間通信をしたい時の通信の経路 経路1:コンテナ1→ホストマシン→コンテナ2 経路2:コンテナ1→コンテナ2 ブリッジネットワークがあると ポイント 0 4 . d o c k e r c o m p o s e

Slide 31

Slide 31 text

d o c k e r - c o m p o s e . y m l の 中 身 手元で/api/docker-compose.ymlを開きながら聞いてください 今回の研修に使用するAPI側のdocker-compose.ymlの例 services: 各コンテナの定義 build: dokcerイメージをビルドする際の設定 dokcerfile:dockerfileのパス image:でdocker hub上にあるイメージ名を指定することも可能 context: ビルド時に起点とするディレクトリ dockerfile内で相対パスでCOPY等書いているとき、これ記載しておくと書きやすいときがあります (デフォルトではDockerfileがあるディレクトリが起点になるので、構造が複雑な時は注意しましょう) volumes Dockerfileの所で説明したvolumeと同じです。ホスト、コンテナ間でファイル共有(コンテナが破棄されて も永続化)できるところを指定しています 書き方は、ホスト側パス:コンテナ側パス ports ポートの指定 environment 環境変数の設定 0 4 . d o c k e r c o m p o s e

Slide 32

Slide 32 text

API側のコンテナを起動してみましょう APIのリポジトリのdocker-compose.ymlのあるディレクトリで docker compose up できましたか? バックグラウンドで実行したい場合 docker-compose up -d ※始めて立ち上げるときは、落ちた時エラーログなど見れた方が便利なので、 docker compose up (-dを付けない)推奨です ハ ン ズ オ ン : p a r t 3   基 本 操 作 0 4 . d o c k e r c o m p o s e

Slide 33

Slide 33 text

dockerイメージ スナップ ショット スナップ ショット スナップ ショット dockerfile dockerイメージ プロセス D o c k e r コ ン テ ナ の ラ イ フ サ イ ク ル プロセス commit build ローカル Docker Hub pull start rm commit run stop down 停止中コンテナ 起動中コンテナ コンテナ破棄 (compose up) ←この操作です

Slide 34

Slide 34 text

起動中のコンテナの状態を見るには コンテナを停止させたい 停止中も含めて見たいとき コンテナを停止・破棄 イメージをビルドしなおす(Dockerfileの中身を変えた時など) イメージの確認 docker ps docker compose stop docker ps -a docker compose down docker compose build (イメージが存在しない時、docker compose upしたときに自動でbuildが走ります) 単体コンテナの時 docker build (Dockerfileのあるパスやdockerhubのイメージ名) docker images ハ ン ズ オ ン : p a r t 3   基 本 操 作 0 4 . d o c k e r c o m p o s e

Slide 35

Slide 35 text

コンテナを起動した後そのコンテナに対してコマンドを実行する時はrun 起動中のコンテナに対してコマンドを実行したい時はexec コンテナに入るとは? 起動しているコンテナ内で、LINUXの操作をしたい→bashやshを起動したい 起動しているコンテナに対して、コマンド実行を行う時は下記の構文になります docker-compose exec {コンテナ名} {command} コンテナ内に入って作業する時 docker compose exec {コンテナ名} bash {コンテナ名}はdocker-compose.ymlで指定したservices名 もしくは、docker psで確認できるコンテナID 補足:docker run と execを混同しないようにしましょう ※単にコマンドを実行しようと思ってrunして満足すると、起動中のコンテナがどんどん増え ていきます ハ ン ズ オ ン ハ ン ズ オ ン : p a r t 3   基 本 操 作

Slide 36

Slide 36 text

ハンズオン:part3 ネットワーク 「tech_training」に、ちゃんと4つ全てのコンテナが繋がっているか見てみましょう ネットワークのリスト docker network ls デフォルトでは下記の3つがあるかと思います bridge(よく使うもの) host(Docker ホストマシンと同じネットワークインタフェース、IP アドレスを持つ) none(ネットワーク接続無) 説明は長くなるので割愛しますが、気になる人は下記を読んでみてください https://qiita.com/TsutomuNakamura/items/ed046ee21caca4a2ffd9 0 4 . d o c k e r c o m p o s e

Slide 37

Slide 37 text

Dockerのhostネットワークの (簡単な)イメージ ホストマシン 仮想NIC コンテナ1 コンテナ2 仮想ブリッジ (docker0) (veth1) (veth2) (eth0:veth1peer) (eth0:veth2peer) 仮想NIC (eth0) Dockerホスト 0 4 . d o c k e r c o m p o s e 仮想NIC (eth0)

Slide 38

Slide 38 text

ネットワークの詳細を確認するとき docker network inspect {NETWORK ID or ネットワーク名} "Containers": { 以下に今、対象のネットワークに繋がっているコンテナの一覧があります 同じネットワーク内にないと、ドメイン名をコンテナ名にしたコンテナ間通信ができないの で、注意しましょう 今回はフロントとAPIにdocker-compose.ymlが分かれています 片方のdocker-compose.ymlファイルからネットワークの記述をコメントアウトし、 docker-compose down→upでコンテナを作り直して、別のネットワークに置きましょう 例えば、フロント側のネットワークの記述を消したとき、APIコンテナ内でフロントのコンテ ナに向けて「curl」を叩いた時の結果はどう変わるでしょうか? ハンズオン:part3 ネットワーク 0 4 . d o c k e r c o m p o s e

Slide 39

Slide 39 text

ホスト(ドメイン)がサービス名 ホスト(ドメイン)がコンテナ名 appコンテナ内からdbコンテナのmysqlに入ってみましょう appコンテナに入る docker compose exec app bash ホストの指定方法は下記のようにいくつかの書き方があります mysql -hdb -uuser -p DB名 mysql -hapi_db_1 -uuser -p DB名 mysql -h{コンテナID} -uuser -p DB名 mysql -h{プライベートIPアドレス} -uuser -p DB名 ハンズオン:part3 ネットワーク 0 4 . d o c k e r c o m p o s e ※プライベートIPアドレスは、 docker network inspect {NETWORK ID or ネットワーク名} で確認しましょう

Slide 40

Slide 40 text

プログラムのソース(DockerfileでCOPYする荒業もありますが、反映のたびにコンテナを作り直す必要があ ります。面倒くさいですね。) DBのデータ デバッグに使うようなログファイル(コンテナの中で生成されるファイルで、ホストからも見たいもの) キャッシュ ホスト・コンテナ間のファイル共有は、ボリュームを使って行います コンテナ内部にデータ(ファイル)を保存しても、dockerイメージで定義した以外のデータはコンテナ破棄すると 消える(※ユニオンファイルシステムの図を思い出してください。) データを永続化したいときは、コンテナの外にデータを置く必要がある その場所のことを、ボリュームと呼ぶ ボリュームに含めたいもの ボリュームに含めなくていいもの コンテナ本体にマウント(-v)すると、コンテナ内部からアクセスできるようになる ホスト・コンテナ間のファイル共有 0 4 . d o c k e r c o m p o s e

Slide 41

Slide 41 text

ホスト・コンテナ間のファイル共有 ホストのディレクトリ(ファイル) ホストで ls で見えるモノ Docker の リソースとしての Volume docker volume ls で見えるモノ 補足:ボリュームには2種類あります 1. 2. 2は、ホストから中身は見えなくても良いけど、永続化をしたい時に使います(DBのデータとか) 0 4 . d o c k e r c o m p o s e

Slide 42

Slide 42 text

ハンズオン:part4 ボリューム 適当なボリュームを作ってみましょう API側のディレクトリに適当なフォルダを作成 mkdir test フォルダに移動して、適当なファイルを作る cd test touch test.txt コンテナに入り、testというディレクトリが見えないのを確認しましょう docker-composeのvolumes:に一行足してみます - ./test/:/コンテナのルートディレクトリ/test/ docker compose down→ upでコンテナを作り直すと、 /testが見えるようになっているのを確認しましょう 0 4 . d o c k e r c o m p o s e

Slide 43

Slide 43 text

05 Dockerの ベストプラクティス

Slide 44

Slide 44 text

Dockerのベストプラクティス 既存のDockerイメージはガンガン使いましょう 環境はなるべくスリムに docker-compose.ymlの個人的な設定、差分は別ファイルに切り出しましょう なるべく公式が提供しているものを選びましょう 要件が足りなければ、既存のイメージをベースとして、必要なところだけDockerfileとして書き足しま しょう 環境が複雑だと、エラーが出た時の特定がしんどくなるうえ、 Dockerイメージの容量もどんどん膨らみます パスなどは誰がどこにおいても動作する書き方を心がける ポートの指定が個人で違う場合は、環境変数に切り出したり、docker-compose.override.ymlを利用し ましょう チームで共有しているファイル(dockerfileやdocker-compose.yml)に手を加えたいときは、レビュ ーを通しチーム全体で変えるようにしましょう 0 5 . D o c k e r の ベ ス ト プ ラ ク テ ィ ス

Slide 45

Slide 45 text

06 おまけ

Slide 46

Slide 46 text

その他、基本的なコマンド 起動時のログを見たい docker logs コンテナをバックグラウンドで起動 docker compose up -d 使っていないイメージの削除 docker image prune 何度か、buildすると前のバージョンのイメージ等ゴミファイルがたまる image pruneは、タグを持たず、他のコンテナからも参照されないイメージを削除する 最新のイメージにはlatestがついており、新しいのができると外れてになる docker container prune コンテナも、毎回downで破棄していればいいが、stopだけで放置すると、docker psにも出てこず、忘れ去られる 定期的に掃除しましょう 参考 https://docs.docker.jp/config/pruning.html 0 6 . お ま け