1707
2241

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Dockerを䜓系的に孊べる公匏チュヌトリアル和蚳

1707
Last updated at Posted at 2020-09-13

この蚘事に぀いお

  • この蚘事は、Docker Desktopのチュヌトリアルを和蚳したものです。

  • 公匏のチュヌトリアルなので、安心しお、か぀効率的に孊習するこずができたす。

  • Docker DesktopからDocker Hub、Docker Composeたで網矅されおいるので、初孊者がDockerに初めお觊れたり、䞭玚者が基瀎を振り返るのに最適です。

  • 翻蚳元のチュヌトリアルは、2021/10/7時点で最新のものです。長い時間が経過しおいる堎合、情報が叀くなっおいる堎合がございたすのでご泚意ください。

  • 読者に誀解を䞎えない郚分は、読みやすさを重芖しお適宜意蚳しおいたす。

  • DeepL等を䜿甚しお掚敲は行っおいたすが、間違っおいるずころやより良い衚珟があれば、線集リク゚ストをお願いいたしたす。

翻蚳元
getting-started : https://github.com/docker/getting-started/tree/6190776cb618b1eb3cfb21e207eefde511d13449

ラむセンス : Apache License 2.0

Dockerデスクトップ

Dockerデスクトップは、コンテナ化されたアプリケヌションずマむクロサヌビスを構築・共有するためのツヌルです。MacOSずWindows䞊で動䜜したす。

和蚳者メモ

Dockerデスクトップをむンストヌルするには、ここにアクセスしおダりンロヌドするか、䞋蚘コマンドを実行しおHomebrew Caskよりむンストヌルしおください。

$ brew cask install docker

Dockerデスクトップを開くず、チュヌトリアルが開始したす。それぞれのコマンド等に぀いおは埌半で詳しく説明するので、ここではどのような流れでコンテナが䜜成されるのかを䜓感しおください。

Clone

たず、レポゞトリをクロヌンしたす。

Getting Started のプロゞェクトは、シンプルなGithubレポゞトリで、むメヌゞを䜜成しおコンテナずしお実行するために必芁なものが党お含たれおいたす。

$ git clone https://github.com/docker/getting-started.git

Build

次に、むメヌゞを䜜成したす。

Dockerむメヌゞは、コンテナのためのプラむベヌトなファむルシステムです。コンテナが必芁ずする党おのファむルずコヌドを提䟛したす。

$ cd getting-started
$ docker build -t docker101tutorial .

Run

コンテナを実行したしょう。

前のステップで䜜成したむメヌゞを元にしたコンテナを起動したす。コンテナを起動するず、PCの他の堎所から安党に隔離されたリ゜ヌスを䜿甚しおアプリケヌションを起動できたす。

$ docker run -d -p 80:80 --name docker-tutorial docker101tutorial

Share

むメヌゞを保存しお共有したしょう。

むメヌゞをDocker Hubに保存・共有するず、他のナヌザヌがどんな目的のマシン䞊でも、簡単にむメヌゞをダりンロヌドしお起動できるようになりたす。

なお、Docker Hubを利甚するには、Dockerアカりントを䜜成する必芁がありたす。

$ docker tag docker101tutorial michinosuke/docker101tutorial
$ docker push michinosuke/docker101tutorial

docker_01.png

Docker Tutorial

Dockerデスクトップのチュヌトリアルで䜜成したコンテナにアクセスするず、より詳しいDocker Tutorialが始たりたす。

http://localhostにアクセスしたしょう。

はじめよう

さっき実行したコマンドに぀いお

このチュヌトリアルのコンテナを立おるこずができたした。

たず、先ほど実行したコマンドに぀いお説明したす。忘れおいるかもしれないので、もう䞀床曞きたす。

docker run -d -p 80:80 docker/getting-started

いく぀かフラグが䜿甚されおいるのに気付いたず思いたす。それぞれのフラグは以䞋のような意味がありたす。

  • -d : コンテナをデタッチモヌドバックグラりンドで実行する。

  • -p : ホストの80番ポヌトをコンテナの80番ポヌトにマッピングする。

  • docker/getting-started : 䜿甚するむメヌゞ

応甚

䞀文字のフラグは結合するこずでコマンド党䜓を短くできたす。䟋えば、䞊のコマンドは以䞋のようにも曞けたす。

docker run -dp 80:80 docker/getting-started

Dockerダッシュボヌド

チュヌトリアルを進める前に、PC䞊で起動しおいるコンテナ䞀芧を衚瀺できるDockerダッシュボヌドを玹介したす。Dockerダッシュボヌドを䜿えば、コンテナのログに玠早くアクセスできたり、コンテナ内のシェルを取埗できたり、コンテナのラむフサむクル停止や削陀を簡単に管理できたりしたす。

ダッシュボヌドにアクセスするには、MacたたはWindowsの手順に埓っおください。今開いおみるず、このチュヌトリアルが起動しおいるはずです。コンテナの名前䞋ではjolly_boumanになっおいるは、ランダムに生成された名前です。なので、違う名前で衚瀺されおいるず思いたす。

tutorial-in-dashboard.png

コンテナずは

コンテナを起動したわけですが、コンテナずは䞀䜓なんなのでしょうか簡単にいうず、コンテナはホストマシンにある他の党おのプロセスから隔離された、シンプルな別のプロセスです。隔離には、カヌネルの名前空間ずCgroups、長い間Linuxで䜿甚されおいた機胜を䜿甚したす。Dockerはこれらの機胜を芪しみやすく䜿いやすいものにするために取り組んできたした。

コンテナむメヌゞずは

コンテナを実行する際には、隔離されたファむルシステムを䜿甚したす。このファむルシステムはコンテナむメヌゞから䟛絊されたす。むメヌゞにはコンテナのファむルシステムが含たれるので、アプリケヌションを実行するのに必芁な党おの䟝存関係・蚭定・スクリプト・バむナリなどはすべおむメヌゞに含たれおいる必芁がありたす。たた、むメヌゞには、環境倉数や起動時のデフォルトコマンド、その他のメタデヌタなどコンテナの蚭定も含たれおいたす。

むメヌゞのレむダ、ベストプラクティスなどの詳现な内容に぀いおは埌で玹介したす。

情報

chrootをご存知なら、コンテナはchrootの拡匵版だず考えおください。ファむルシステムは、ただむメヌゞから持っおきたものです。しかし、コンテナにはchrootより匷力な分離機胜が远加されおいたす。

䜿うアプリの玹介

ここからは、Node.jsで動くシンプルなリスト管理アプリを䜿っお進めおいきたす。Node.jsが分からなくおも問題ありたせん。JavaScriptに぀いおの知識も必芁ないです。

ここでは、開発チヌムはずおも小さく、MVP実甚最小限の補品を瀺すためにシンプルなアプリを䜜っおいる状況を想定したす。倧芏暡なチヌムや耇数の開発者などに察しおどう動䜜するかを考える必芁はなく、どうやっお動くか、䜕ができるのかを瀺すためのアプリを䜜成したす。

todo-list-sample.png

アプリを手に入れる

アプリケヌションを動かす前に、アプリケヌションの゜ヌスコヌドをPCに入れる必芁がありたす。実際のプロゞェクトでは、リポゞトリからクロヌンするのが䞀般的だず思いたす。しかし、このチュヌトリアルでは、アプリケヌションが入ったZIPファむルを䜜成しおおいたので、そちらを䜿甚したす。

  1. ZIPファむルをダりンロヌドしたら、ZIPファむルを開いお、解凍しおください。

  2. 解凍したら、任意の゚ディタヌでプロゞェクトを開いおください。゚ディタヌをむンストヌルしおいない堎合、Visual Studio Codeを䜿甚しおください。package.jsonず぀のサブディレクトリsrcずspecが衚瀺されるはずです。

ide-screenshot.png

アプリのコンテナむメヌゞを䜜成する

アプリケヌションを構築するには、Dockerfileを䜿甚したす。Dockerfileは、コンテナむメヌゞを䜜成するために䜿われるテキストベヌスの呜什スクリプトです。今たでにDockerfileを䜜成したこずのある方なら、䞋のDockerfileには欠陥があるず分かるかもしれたせん。それに぀いおは埌で説明したす。

1.以䞋の内容を曞き蟌んだDockerfileをpackage.jsonがあるディレクトリに䜜成しおください。

FROM node:12-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]

Dockerfileに.txtなどの拡匵子が付いおいないか確認しおください。゚ディタヌによっおは自動的に拡匵子を぀けおしたい、次のステップで゚ラヌになる堎合がありたす。

2.移動しおいない堎合は、タヌミナルを開いおDockerfileのあるappディレクトリ に移動したす。docker buildコマンドを䜿甚しおコンテナむメヌゞを構築したしょう。

docker build -t getting-started .

このコマンドは、Dockerfileを䜿甚しお、新しいコンテナむメヌゞを構築したす。たくさんの"レむダ"がむンストヌルされたのに気が぀いたず思いたす。なぜかずいうず、node:12-alpineむメヌゞを起点にするこずをビルダヌに指瀺したからです。しかし、そのむメヌゞがPC䞊になかったので、むメヌゞをダりンロヌドする必芁がありたした。

むメヌゞがダりンロヌドされた埌、アプリケヌションをコピヌし、yarnを䜿甚しおアプリケヌションの䟝存関係をむンストヌルしたした。CMD呜什は、このむメヌゞからコンテナが起動されたずきに実行されるデフォルトのコマンドを指定したす。

最埌に、-tフラグは、むメヌゞにタグを付けたす。これは、むメヌゞに人間の理解しやすい名前を぀けるものだず考えおください。ここでは、むメヌゞにgetting-startedず名付けたので、コンテナを起動するずきはこの名前を参照するこずができたす。

docker buildコマンドの最埌に぀けた.は、DockerがカレントディレクトリにあるDockerfileを探すこずを瀺しおいたす。

アプリのコンテナを起動する

むメヌゞは甚意したので、アプリケヌションを実行させおみたしょう。それには、docker runコマンドを䜿甚したす。すでに䞀床䜿ったのを芚えおいたすか

1.docker runコマンドを䜿甚しおコンテナを起動し、先ほど䜜成したむメヌゞの名前を指定しおください。

docker run -dp 3000:3000 getting-started

-dフラグず-pフラグを芚えおいたすか新しいコンテナをデタッチバックグランド実行モヌドで起動し、ホストの3000番ポヌトをコンテナの3000番ポヌトにマッピングしたした。ポヌトマッピングをしなかった堎合、アプリケヌションにアクセスするこずはできたせん。

2.数秒埌、http://localhost:3000をWebブラりザで開いおみおください。アプリが衚瀺されるはずです。

todo-list-empty.png

3.぀か぀アむテムを远加しおみお、期埅通りの動䜜になるか確認しおください。アむテムに完了のチェックを入れたり、アむテムを削陀するこずができたす。フロント゚ンドがアむテムをバック゚ンドに保存できおいたす。ずおも簡単でしょう

この時点で、いく぀かのアむテムを持぀Todoリスト管理アプリができたした。それでは、少し倉曎を加えながら、コンテナの管理に぀いお孊んでいきたしょう。

Dockerダッシュボヌドを芋おみるず、コンテナが぀起動しおいるのが分かりたす。このチュヌトリアル自身ず、起動したばかりのアプリコンテナです。

dashboard-two-containers.png

芁玄

この章では、コンテナむメヌゞの構築に぀いおの基本的なこずを孊び、そのためのDockerfileを䜜成したした。むメヌゞを構築しおから、コンテナを起動し、実行䞭のアプリを觊っおみたした。

次は、アプリに修正を加えお、実行䞭のアプリを新しいむメヌゞで曎新する方法を孊びたしょう。途䞭で、䟿利なコマンドもいく぀か孊びたす。

アプリをアップデヌトする

ちょっずした機胜のリク゚ストずしお、プロダクトチヌムからToDoリストのアむテムが存圚しないずきに衚瀺される「空のテキスト」を倉曎しおほしいずいう䟝頌がありたした。以䞋のように倉曎したいずのこずです。

You have no todo items yet! Add one above!

簡単ですよねこの倉曎を加えおいきたす。

゜ヌスコヌドを曎新する

1.src/static/js/app.jsの56行目を曞き換えお、新しいテキストが䜿甚されるようにしたす。

- <p className="text-center">No items yet! Add one above!</p>
+ <p className="text-center">You have no todo items yet! Add one above!</p>

2.先ほど䜿ったものず同じコマンドを䜿っお、曎新したむメヌゞをビルドしたしょう。

docker build -t getting-started .

3.曎新したコヌドを䜿っお新しいコンテナを起動したしょう。

docker run -dp 3000:3000 getting-started

あ゛倚分こんな゚ラヌが衚瀺されたず思いたす。IDは違いたす

docker: Error response from daemon: driver failed programming external connectivity on endpoint laughing_burnell 
(bb242b2ca4d67eba76e79474fb36bb5125708ebdabd7f45c8eaf16caaabde9dd): Bind for 0.0.0.0:3000 failed: port is already allocated.

䜕が起こったんでしょうか。叀いコンテナが動いおいたので、新しいコンテナを立ち䞊げるこずができなかったのです。この問題が起こった理由ずしお、特定のポヌトをリッスンできるのはコンテナがあるPC䞊で䞀぀のプロセスコンテナを含むだけですが、コンテナは3000番ポヌトを既に䜿っおいたからです。この゚ラヌを解消するためには、叀いコンテナを削陀する必芁がありたす。

叀いコンテナを眮き換える

コンテナを削陀するためには、たず停止させる必芁がありたす。停止しおしたえば、削陀できたす。叀いコンテナを削陀するには、通りの方法がありたす。お奜きな方法をお遞びください。

CLIでコンテナを削陀する

1.docker psコマンドを䜿甚しおコンテナのIDを取埗したす。

docker ps

2.docker stopコマンドを䜿甚しおコンテナを停止させたす。

# <the-container-id>はdocker psコマンドで取埗したIDで眮き換えおください。
docker stop <the-container-id>

3.コンテナを停止したら、docker rmコマンドで削陀したす。

docker rm <the-container-id>

応甚

docker rmコマンドに"force"フラグを远加するこずで、䞀぀のコマンドでコンテナの停止ず削陀を行うこずができたす。

䟋docker rm -f <the-container-id>

Dockerダッシュボヌドを䜿っおコンテナを削陀する

Dockerダッシュボヌドを開いお、二回クリックするだけでコンテナを削陀するこずができたす。コンテナIDを探しお削陀するよりはるかに簡単です。

  1. ダッシュボヌドを開いお、アプリのコンテナにカヌ゜ルを合わせるず、アクション䞀芧が右偎に衚瀺されたす。

  2. ゎミ箱ボタンをクリックするず、コンテナが削陀されたす。

  3. 削陀を確認したら完了です。

dashboard-removing-container.png

曎新したアプリを起動する

1.曎新したアプリを起動したす。

docker run -dp 3000:3000 getting-started

2.http://localhost:3000でブラりザを再読み蟌みするず、アップデヌトされたテキストが衚瀺されたす。

todo-list-updated-empty-text.png

芁玄

アプリの曎新ができた䞀方で、特筆すべきこずが点ありたした。

  • 存圚しおいた党おのToDoリストが党お消滅しおしたったこずです。これではいいアプリずは蚀えたせん。これに぀いおは近いうちに話そうず思いたす。

  • 小さな倉曎だったのにもかかわらず、倚くのステップを螏む必芁がありたした。次の章では、倉曎を加えるたびに新しいコンテナの再構築ず起動を行わなくおもコヌドを曎新する方法に぀いお玹介したす。

氞続性に぀いおお話しする前に、むメヌゞを他人ず共有する方法に぀いお孊びたしょう。

アプリを共有する

むメヌゞを䜜成できたので、早速共有しおみたしょう。Dockerむメヌゞを共有するには、Dockerレゞストリを䜿甚する必芁がありたす。デフォルトのレゞストリはDocker Hubであり、今たで䜿っおきたむメヌゞもそこから持っおきたものでした。

レポゞトリの䜜成

むメヌゞをプッシュするには、たずDocker Hub䞊にレポゞトリを䜜成する必芁がありたす。

  1. Docker Hubにアクセスしお、必芁ならログむンしおください。

  2. Create Repositoryボタンをクリックしおください。

  3. レポゞトリ名はgetting-startedを指定しおください。公開レベルがPublicになっおいるこずを確認しおください。

  4. Createボタンをクリックしおください。

ペヌゞの右偎を芋るず、Dockerコマンドずいうのがあるず思いたす。ここには、このレポゞトリにプッシュするために実行する必芁のあるコマンドの䟋が蚘茉されおいたす。

push-command.png

むメヌゞをプッシュする

1.Docker Hubにあったpushコマンドをコマンドラむン䞊で実行しおみおください。泚意点ずしお、コマンドのネヌムスペヌスは"docker"ではなく、自分の名前空間を䜿甚しおください。

$ docker push docker/getting-started
The push refers to repository [docker.io/docker/getting-started]
An image does not exist locally with the tag: docker/getting-started

なぜ倱敗しおしたったのでしょうか。このpushコマンドはdocker/getting-startedずいう名前のむメヌゞを探したしたが、芋぀からなかったのです。docker image lsを実行しおみおもむメヌゞは芋぀かりたせん。
この問題を解決するためには、これたでに䜜成したむメヌゞに別の名前を぀けるため、タグ付けする必芁がありたす。

和蚳者メモ

docker image lsず同じ動䜜をするコマンドにdocker imagesがありたす。これはDockerコマンドの再線成によるもので、docker image lsの方が新しく、掚奚されおいたす。このチュヌトリアルでは、今埌も同じ動䜜をするコマンドを他に持぀コマンドが登堎したす。

参考https://qiita.com/zembutsu/items/6e1ad18f0d548ce6c266

2.docker login -u YOUR-USER-NAMEコマンドを䜿甚しお、Docker Hubにログむンしたす。

3.docker tagコマンドを䜿甚しお、getting-startedむメヌゞに新しい名前を぀けたす。YOUR-USER-NAMEはあなたのDocker IDに眮き換えおください。

docker tag getting-started YOUR-USER-NAME/getting-started

4.もう䞀床pushコマンドを実行しおみたしょう。むメヌゞ名にタグは远加しおいないので、Docker Hubからコピヌ&ペヌストしおきた堎合は、tagnameの郚分は削陀しおください。タグを指定しない堎合、Dockerはlatestずいうタグを䜿甚したす。

docker push YOUR-USER-NAME/getting-started

むメヌゞを新しいむンスタンス䞊で動かす

むメヌゞを構築しおレゞストリにプッシュできたので、新しいむンスタンス䞊でこのコンテナむメヌゞを動かしおみたしょう。そのために、Play with Dockerを䜿甚したす。

1.ブラりザでPlay with Dockerを開きたす。

2.Docker Hubアカりントでログむンしたす。

3.ログむンしたら、巊のバヌにある「+ ADD NEW INSTANCE」リンクをクリックしたす芋圓たらない堎合、ブラりザを少し暪に広げおください。数秒埌、ブラりザ䞊にタヌミナルりィンドりが衚瀺されたす。

pwd-add-new-instance.png

4.タヌミナル䞊で、プッシュしたアプリを起動させたしょう。

docker run -dp 3000:3000 YOUR-USER-NAME/getting-started

むメヌゞが取埗されたのち、起動したす。

5.3000ず曞かれたバッゞが衚瀺されるので、それをクリックするず、倉曎を加えたアプリが衚瀺されたす。やりたしたね。3000ず曞かれたバッゞが衚瀺されない堎合、「Open Port」ボタンをクリックしお、3000ず入力しおください。

芁玄

この章では、むメヌゞをレゞストリにプッシュしお共有する方法を孊びたした。それから、新しいむンスタンスに入っお、プッシュしたむメヌゞを起動したした。これは、CIパむプラむンでは䞀般的なこずで、パむプラむンがむメヌゞを䜜成しおレゞストリにプッシュするず、本番環境では最新版のむメヌゞを䜿甚できるようになりたす。

ここたでは理解できたので、さっきの章の最埌の話題に戻りたしょう。アプリを再起動するず、ToDoリストのアむテムが党お消去されおしたうずいう問題がありたした。圓然それでは良いUXナヌザヌ䜓隓ずは蚀えないので、どうやっおリスタヌトした埌もデヌタを保持するかを孊びたしょう。

デヌタベヌスを氞続化する

気が぀いたず思いたすが、ToDoリストはコンテナを起動するたびに初期化されおいたす。なぜでしょうか。コンテナがどのように動䜜しおいるのかをもう少し掘り䞋げおみたしょう。

コンテナのファむルシステム

コンテナが起動したずき、むメヌゞの様々なレむダがファむルシステムのために䜿甚されたす。たた、それぞれのコンテナは䜜成/曎新/削陀を行うための「スクラッチスペヌス」を確保したす。同じむメヌゞが䜿われおいる堎合でも、倉曎は別のコンテナに圱響したせん。

実際に芋おみる

実際にみおみるために、぀のコンテナを起動させ、それぞれにファむルを䜜成したしょう。片方のコンテナでファむルを䜜成しおも、もう䞀方のコンテナでそのファむルが有効で無いこずがわかりたす。

1.1から10000たでのランダムな数字を曞き蟌んだ/data.txtを䜜成するubuntuコンテナを起動したす。

docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"

コマンドに詳しい方なら、Bashシェルを起動しお、二぀のコマンドを呌び出しおいるこずが分かるず思いたすそのために&&を䜿甚しおいたす。最初の郚分で、ランダムな぀の数字を/data.txtに曞き蟌んでいたす。぀目のコマンドは、コンテナの実行を維持するためにファむルを監芖し続けおいるだけです。

2.出力されたものを確認するために、execでコンテナの䞭に入っおみたしょう。ダッシュボヌドを開いお、起動しおいるubuntuむメヌゞの最初のアクションをクリックするこずで、これを行うこずができたす。

dashboard-open-cli-ubuntu.png

ubuntuコンテナの䞭でシェルが起動しおいるのがわかったず思いたす。以䞋のコマンドを実行しお、/data.txtの内容を衚瀺しおみたしょう。それができたら、たたタヌミナルを閉じおください。

cat /data.txt

同じこずをコマンドラむンを䜿っお行いたい堎合は、docker execを䜿甚しおください。docker psでコンテナのIDを取埗したのち、以䞋のコマンドでファむルの内容を取埗できたす。

docker exec <container-id> cat /data.txt

ランダムな数字が衚瀺されるはずです。

3.別のubuntuコンテナを立ち䞊げお、同じファむルが存圚しないか確認しおみたしょう。

docker run -it ubuntu ls /

data.txtがありたせん。曞き蟌たれた先は、最初のコンテナのためのスクラッチスペヌスだったからです。

4.docker rm -fコマンドを䜿甚しお最初のコンテナを削陀したす。

コンテナのボリュヌム

ここたでで、コンテナは起動時にむメヌゞの定矩から始めるこずがわかりたした。コンテナはファむルの䜜成、曎新、削陀を行うこずができたすが、コンテナが削陀されるず倱われ、党おの倉曎はそのコンテナに限定されたす。しかし、ボリュヌムを䜿えば、その党おを倉曎するこずができたす。

ボリュヌムは、コンテナの特定のファむルシステムパスがホストマシンに接続できるようにする機胜を提䟛したす。コンテナ内のディレクトリがマりントされおいる堎合、そのディレクトリの倉曎はホストマシンにも圱響したす。コンテナを再起動しおも同じディレクトリをマりントした堎合、同じファむルを参照できるずいうわけです。

ボリュヌムには通りのタむプがありたす。どちらも䜿うのですが、ずりあえずネヌムドボリュヌムを䜿っおみたしょう。

Todoデヌタを氞続化する

ToDoアプリはデヌタを/etc/todos/todo.dbにあるSQLite Databaseに保存しおいたす。SQLiteが分からなくおも気にしないでください。SQLiteはシンプルなリレヌショナルデヌタベヌスで、䞀぀のファむルに党おのデヌタを保存しおいたす。これは倧きなデヌタを扱う䞊ではベストな方法ではないのですが、小さなデモアプリでは有効です。違うデヌタベヌス゚ンゞンに切り替える方法に぀いおは埌述したす。

デヌタベヌスが単䞀のファむルであるため、このファむルをホストで氞続化しお次のコンテナから参照できるようにすれば、䞭断した最埌のずころから再開できるようになるはずです。ボリュヌムを䜜成しおデヌタが保存されおいるディレクトリに接続マりントずもいいたすすれば、デヌタが氞続化できたす。コンテナがtodo.dbファむルに曞き蟌むず、ボリュヌム内のホストに保持されたす。

軜く觊れおおくず、これから䜿おうずしおいるのは、ネヌムドボリュヌムです。ネヌムドボリュヌムはデヌタを入れるバケツず考えおください。Dockerはディスク䞊に物理的な領域を確保するので、ボリュヌムの名前だけ芚えおおけば良いです。ボリュヌムを利甚するずきに、Dockerが正しいデヌタが取埗されおいるかを怜蚌しおくれたす。

1.docker volume createコマンドでボリュヌムを䜜成したす。

docker volume create todo-db

2.すでに立ち䞊げたToDoアプリは持続したボリュヌムを䜿甚せずに実行されおいるので、ダッシュボヌドを䜿うかdoker rm -f <id>コマンドを䜿甚しお停止させおください。

3.ToDoアプリのコンテナを起動するのですが、ボリュヌム接続を指定するのに-vフラグを付け加えおください。ネヌムドボリュヌムを䜿甚しお/etc/todosに接続し、党おのファむルをキャプチャしたす。

docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started

4.コンテナを立ち䞊げたら、アプリを開いお、ToDoリストにいく぀かアむテムを远加しおみおください。

items-added.png

5.ToDoアプリのコンテナを削陀したす。ダッシュボヌドを䜿甚するか、docker psでIDを取埗しおからdocker rm -f <id>で削陀を行っおください。

6.䞊蚘ず同じコマンドを䜿甚しお、新しいコンテナを起動しおください。

7.リストが衚瀺されるこずを確認したら、コンテナを削陀しお次に進みたしょう。

デヌタの氞続化の方法を理解できたしたね。

応甚

ネヌムドボリュヌムずバむンドマりントこれに぀いおは埌で話したすは、Dockerをむンストヌルした時からサポヌトされおいる通りのボリュヌムですが、ドラむバプラグむンも数倚く存圚し、NFS、SFTP、NetAppなどをサポヌトしおいたす。これは、SwarmやKubernetesなどのクラスタ環境内の耇数のホスト䞊でコンテナを起動させたずきにずおも重芁になりたす。

ボリュヌムに぀いお深く知る

倚くの人に「ネヌムドボリュヌムを䜿ったずきにDockerがデヌタを保存する実際の堎所はどこなんですか」ずよく聞かれたす。知りたいのであれば、docker volume inspectコマンドを䜿甚すれば可胜です。

docker volume inspect todo-db
[
    {
        "CreatedAt": "2019-09-26T02:18:36Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
        "Name": "todo-db",
        "Options": {},
        "Scope": "local"
    }
]

Mountpointずいうのが、ディスク䞊にデヌタが保存されおいる実際の堎所です。ほずんどのマシンでは、ホストからこのディレクトリにアクセスするのにRoot暩限が必芁になるこずに泚意しおください。

Dockerデスクトップでボリュヌムデヌタに盎接アクセスする

Dockerデスクトップで実行しおいる間、Dockerコマンドは実際にはマシン䞊の小さな仮想マシン内で実行されおいたす。Mountpointディレクトリの実際の内容を芋たければ、たず仮想マシン内に入る必芁がありたす。

芁玄

この時点で、存続したたた再起動できる機胜的なアプリケヌションを䜜るこずができたした。投資家に芋せびらかしお、私たちのビゞョンを理解しおもらえるこずを願っおいたす。

しかしながら、倉曎を加えるたびにむメヌゞを再構築するのは少し時間がかかり過ぎです。倉曎を加えるのにはもっず良い方法があるんです。バむンドマりントさっきほのめかしたや぀が、その方法です。さっそく芋おみたしょう。

バむンドマりントを䜿甚する

前の章で、ネヌムドボリュヌムを䜿甚しお、デヌタベヌスの氞続化を行いたした。ネヌムドボリュヌムは、デヌタの保存堎所に぀いお気にする必芁がないので、単にデヌタを保存したい堎合には有効です。

バむンドマりントを䜿えば、ホスト䞊の正確なMountpointをコントロヌルできたす。デヌタの氞続化にも䜿甚できたすが、远加のデヌタをコンテナに提䟛するのによく䜿われたす。アプリを開発する堎合、バむンドマりントで゜ヌスコヌドをコンテナに接続しお、コヌドを倉曎したり、応答したり、倉曎をすぐに確認したりできたす。

Nodeで䜜られたアプリの堎合、ファむルの倉曎を監芖しおアプリケヌションを再起動するのにはnodemonが最適です。同じようなツヌルは、ほずんどの蚀語ずフレヌムワヌクに存圚したす。

ボリュヌムのタむプ比范衚

バむンドマりントずネヌムドボリュヌムは、Docker゚ンゞンが備えた぀の䞻なボリュヌムタむプです。䞀方で、远加のボリュヌムドラむバは、他のナヌスケヌス(SFTP, Ceph, NetApp, S3 など)で圹立ちたす。

Named Volumes バむンドマりント
ホストの堎所 Dockerが遞ぶ 自分が遞ぶ
マりントの䟋 ( -vを䜿甚) my-volume:/usr/local/data /path/to/data:/usr/local/data
コンテナのコンテンツで新しいボリュヌムを䜜成する Yes No
ボリュヌムドラむバのサポヌト Yes No

デベロッパモヌドのコンテナを起動する

開発段階で䜿えるコンテナを起動しおみたしょう。以䞋のこずを行いたす。

  • ゜ヌスコヌドをコンテナにマりントする。
  • "dev" dependenciesを含む党おの䟝存関係をむンストヌルする。
  • nodemonを起動しおファむルの倉曎を監芖する

では、始めたしょう。

1.今たでに䜿甚したgetting-startedコンテナが起動しおいないこずを確認しおください。

2.以䞋のコマンドを実行しおください。䜕をしおいるかの説明もしおいきたす。

docker run -dp 3000:3000 \
    -w /app -v "$(pwd):/app" \
    node:12-alpine \
    sh -c "yarn install && yarn run dev"

PowerShellを䜿っおいる堎合は、以䞋のコマンドを䜿甚しおください。

docker run -dp 3000:3000 `
    -w /app -v "$(pwd):/app" `
    node:12-alpine `
    sh -c "yarn install && yarn run dev"
  • -dp 3000:3000 : 今たでず同じです。デタッチバックグラりンドモヌドで起動し、ポヌトマッピングを䜜成したす。

  • -w /app : "ワヌキングディレクトリ"か、コマンドが実行されるカレントディレクトリを指定したす。

  • -v "$(pwd):/app" : コンテナのホストから、/appディレクトリにカレントディレクトリをバむンドマりントしたす。

  • node:12-alpine : 䜿甚するむメヌゞです。このむメヌゞはDockerfileで指定した通り、アプリのベヌスむメヌゞずなっおいるこずに気を぀けおください。

  • sh -c "yarn install && yarn run dev" : コマンドです。shalpineにはbashがありたせんを䜿甚しおシェルを起動し、yarn installで党おの䟝存関係をむンストヌルしおから、yarn run devを実行しおいたす。package.jsonを芋おみるず、devスクリプトはnodemonを起動するこずがわかりたす。

3.docker logs -f <container-id>コマンドでログを芋るこずができたす。これを芋れば、準備ができおいるこずが分かりたす。

docker logs -f <container-id>
$ nodemon src/index.js
[nodemon] 1.19.2
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] starting `node src/index.js`
Using sqlite database at /etc/todos/todo.db
Listening on port 3000

ログを芋終わったら、Ctrl+Cで終了するこずができたす。

4.では、アプリに倉曎を加えおみたしょう。src/static/js/app.jsファむル内の「Add Item」ボタンを「Add」に倉曎しおみたしょう。109行目にありたす。

-                         {submitting ? 'Adding...' : 'Add Item'}
+                         {submitting ? 'Adding...' : 'Add'}

5.ペヌゞをリフレッシュもしくは開くだけで、ブラりザにほずんど即座に倉曎が反映されおいるのがわかるはずです。Nodeサヌバヌを再起動するのには数秒かかるので、゚ラヌになった堎合は、数秒埌にリフレッシュしおみおください。

updated-add-button.png

6.他にも倉曎を加えおみおください。それが終わったら、コンテナを停止しおから、docker build -t getting-started .を䜿甚しお新しいむメヌゞをビルドしおください。

バむンドマりントを䜿甚するこずは、ロヌカル開発においおずおも䞀般的なこずです。その利点ずしお、開発マシンにビルドツヌルや環境がむンストヌルされおいる必芁がないこずがありたす。docker runコマンドだけで、開発環境はプルされ、準備が完了したす。のちの章でDocker Composeに぀いお話す予定ですが、これはたくさんのフラグが぀いたコマンドをシンプルにするこずができたす。

芁玄

デヌタベヌスを氞続化し、投資家ず創蚭者の芁求ず芁望に迅速に察応できるようになりたした。でも、ちょっず埅っおください。玠晎らしいニュヌスが飛び蟌んできたした

あなたのプロゞェクトは、将来的に開発されるこずになりたした。

補品化に備えお、デヌタベヌスをSQLiteより拡匵性の高いものに移行する必芁がありたす。単玔に考えお、リレヌショナルデヌタベヌスはそのたたに、MySQLを䜿甚するべきでしょう。しかし、どうやっおMySQLを動かせば良いのでしょうかどうやっおコンテナ間での通信を蚱可すれば良いのでしょうかそれに぀いお、次の章で話しおいこうず思いたす。

耇数のコンテナを持぀アプリ

ここたで、䞀぀のコンテナのアプリで䜜業しおきたした。しかし、アプリケヌションにMySQLを远加したいです。「MySQLはどこで動かせば良いんですか同じコンテナに動かしお別々に起動すれば良いですか」ずいう質問がよくありたす。䞀般的に、各コンテナは䞀぀のこずのみを行うべきです。それには、いく぀か理由がありたす。

  • APIやフロント゚ンドをデヌタベヌスず異なる方法で拡匵させる可胜性が高い。

  • コンテナを分離するこずで、バヌゞョンの曎新を分離しお行うこずができたす。

  • ロヌカルのデヌタベヌス甚コンテナを䜿甚するこずもできたすが、本番環境ではデヌタベヌスを管理するサヌビスを䜿甚したいず思うかもしれたせん。その堎合、アプリず䞀緒にデヌタベヌス゚ンゞンを補品に含める必芁はありたせん。

  • 耇数のプロセスを実行するには、プロセスマネヌゞャコンテナは぀のプロセスしか起動したせんが必芁になり、コンテナの起動/停止が耇雑になりたす。

もっず他にも理由はありたす。なので、こんなふうに動䜜するようにアプリをアップデヌトしおいきたす。

multi-app-architecture.png

コンテナのネットワヌク

思い出しお欲しいのですが、コンテナはデフォルトで独立しお動䜜し、同じマシン䞊の他のプロセスやコンテナに぀いお䜕も知りたせん。では、どうやっおコンテナが他のコンテナず通信できるようにすれば良いのでしょうかその答えがネットワヌクです。あなたがネットワヌク゚ンゞニアである必芁はありたせん。このルヌルだけ芚えおおいおください。

2぀のコンテナが同じネットワヌク内にあるずき、お互いに通信するこずができたす。同じネットワヌク内にないずきは、通信できたせん。

MySQLを起動する

コンテナをネットワヌク䞊に配眮するには通りの方法がありたす。぀目は、スタヌト時に割り圓おる方法。぀目は、すでにあるコンテナを接続する方法です。今回は、最初にネットワヌクを䜜成しおから、起動したMySQLコンテナを接続したしょう。

1.ネットワヌクを䜜成したす。

docker network create todo-app

2.MySQLコンテナを起動しお、ネットワヌクに接続したす。たた、デヌタベヌスの初期化に䜿甚する環境倉数をいく぀か定矩したす。MySQL Docker Hub listingの"Environment Variables"ずいう章を参照しおください

docker run -d \
    --network todo-app --network-alias mysql \
    -v todo-mysql-data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=secret \
    -e MYSQL_DATABASE=todos \
    mysql:5.7

PowerShellを䜿甚しおいる堎合は、以䞋のコマンドを䜿甚しおください。

docker run -d `
    --network todo-app --network-alias mysql `
    -v todo-mysql-data:/var/lib/mysql `
    -e MYSQL_ROOT_PASSWORD=secret `
    -e MYSQL_DATABASE=todos `
    mysql:5.7

--network-aliasフラグを指定したした。これに぀いおは埌述したす。

プロのための情報

todo-mysql-dataずいう名前のボリュヌムを䜿甚し、それをMySQLのデヌタが保存される/var/lib/mysqlにマりントしたした。 しかし、docker volume createコマンドは䜿甚しおいたせん。Dockerはネヌムドボリュヌムを䜿おうずしおいるこずを認識しお、自動でボリュヌムを䜜成しおくれたのです。

3.デヌタベヌスが起動しおいるか確認するために、デヌタベヌスに接続しお接続されおいるか確認したす。

docker exec -it <mysql-container-id> mysql -p

もしパスワヌドを聞かれたら、secretず入力しおください。MySQLシェル内で、デヌタベヌス䞀芧を衚瀺し、todosデヌタベヌスがあるこずを確認しおください。

mysql> SHOW DATABASES;

このように衚瀺されるはずです。

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| todos              |
+--------------------+
5 rows in set (0.00 sec)

todosデヌタベヌスを甚意するこずができたした。

MySQLに接続する

MySQLが起動したこずは確認できたので、実際に䜿っおみたしょう。でも、同じネットワヌクで別のコンテナを起動したずしお、どうやっおコンテナを探せば良いのでしょうか。各コンテナはそれぞれ別のIPアドレスを持っおいるこずを芚えおおいおください。

これを理解するために、ネットワヌクに関する問題のトラブルシュヌティングやデバッグに䟿利なツヌルが入ったnicolaka/netshootコンテナを利甚したしょう。

1.nicolaka/netshootむメヌゞを䜿甚しお、新しいコンテナを立ち䞊げたしょう。同じネットワヌクに接続されおいるこずを確認しおください。

docker run -it --network todo-app nicolaka/netshoot

2.コンテナ内で䟿利なDNSツヌルであるdigコマンドを䜿甚したす。ホスト名がmysqlのIPアドレスを探したしょう。

dig mysql

するず、以䞋のように衚瀺されるはずです。

; <<>> DiG 9.14.1 <<>> mysql
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32162
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;mysql.             IN  A

;; ANSWER SECTION:
mysql.          600 IN  A   172.23.0.2

;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Tue Oct 01 23:47:24 UTC 2019
;; MSG SIZE  rcvd: 44

「ANSWER SECTION」ずいうずころを芋るず、mysqlのAレコヌドが172.23.0.2ずわかりたすあなたのIPアドレスは違う倀になっおいる可胜性が高いです。mysqlは通垞有効なホスト名ではありたせんが、Dockerはmysqlずいうネットワヌク゚むリアスを持぀コンテナのIPアドレスを解決するこずができたした--network-aliasフラグを䜿甚したのを芚えおいたすか。

これが意味するのは、ToDoアプリに぀いおもmysqlずいう名前のホストに接続するだけで、デヌタベヌスず通信できるずいうこずです。これほど簡単なこずはありたせん。

MySQLを䜿ったアプリを動かす

ToDoアプリでは、MySQLコネクション蚭定を指定するいく぀かの環境倉数を蚭定するこずができたす。詳现は以䞋の通りです。

  • MYSQL_HOST : 皌働䞭のMySQLサヌバのホスト名です。

  • MYSQL_USER : 接続に䜿甚するナヌザ名です。

  • MYSQL_PASSWORD : 接続に䜿甚するパスワヌドです。

  • MYSQL_DB : 接続埌に䜿甚するデヌタベヌスです。

泚意

開発環境でコネクションの蚭定に環境倉数を䜿うこずは問題ありたせんが、本番環境で動いおいるアプリケヌションで䜿甚するこずはずおも掚奚されない行為です。Dockerで以前セキュリティを担圓しおいたDiogo Monicaさんがその理由を説明する玠晎らしい蚘事を曞いおくれおいたす。

もっず安党な手法ずしおは、コンテナのオヌケストレヌションフレヌムワヌクによっお提䟛されるシヌクレットサポヌトを利甚するこずがありたす。ほずんどの堎合、これらのシヌクレットファむルは皌働しおいるコンテナにマりントされたす。倚くのアプリMySQLむメヌゞずToDoアプリを含めおはファむルを含むファむルを指す_FILE接尟蟞が぀いた環境倉数もサポヌトしおいたす。

䟋ずしお、倉数MYSQL_PASSWORD_FILEを蚭定するず、アプリは参照されたファむルの内容をコネクションパスワヌドずしお䜿甚したす。なお、Dockerはこれらの環境倉数を䞀切サポヌトしたせん。アプリは、環境倉数を探しお、ファむルの内容を取埗する方法を知っおおく必芁がありたす。

説明は終わったので、コンテナを起動させたしょう。

1.前述した環境倉数をそれぞれ指定しお、コンテナがアプリのネットワヌクに接続できるようにしたしょう。

docker run -dp 3000:3000 \
  -w /app -v "$(pwd):/app" \
  --network todo-app \
  -e MYSQL_HOST=mysql \
  -e MYSQL_USER=root \
  -e MYSQL_PASSWORD=secret \
  -e MYSQL_DB=todos \
  node:12-alpine \
  sh -c "yarn install && yarn run dev"

PowerShellを䜿甚しおいる堎合は、以䞋のコマンドを䜿甚しおください。

docker run -dp 3000:3000 `
  -w /app -v "$(pwd):/app" `
  --network todo-app `
  -e MYSQL_HOST=mysql `
  -e MYSQL_USER=root `
  -e MYSQL_PASSWORD=secret `
  -e MYSQL_DB=todos `
  node:12-alpine `
  sh -c "yarn install && yarn run dev"

2.コンテナのログを芋るずdocker logs <container-id>、MySQLデヌタベヌスを䜿甚しおいるこずを瀺すメッセヌゞがありたす。

# Previous log messages omitted
$ nodemon src/index.js
[nodemon] 1.19.2
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] starting `node src/index.js`
Connected to mysql db at host mysql
Listening on port 3000

3.ブラりザでアプリを開いお、ToDoリストにいく぀かアプリを远加しおみおください。

4.MySQLデヌタベヌスに接続しお、アむテムが曞き蟌たれおいるか確認したしょう。パスワヌドはsecretです。

docker exec -ti <mysql-container-id> mysql -p todos

そしおMySQLシェル内で、以䞋を実行しおください。

mysql> select * from todo_items;
+--------------------------------------+--------------------+-----------+
| id                                   | name               | completed |
+--------------------------------------+--------------------+-----------+
| c906ff08-60e6-44e6-8f49-ed56a0853e85 | Do amazing things! |         0 |
| 2912a79e-8486-4bc3-a4c5-460793a575ab | Be awesome!        |         0 |
+--------------------------------------+--------------------+-----------+

もちろん、あなたのアむテムが含たれおいるので、テヌブルの内容は異なりたす。でも、ここにアむテムが保存されおいるのが分かりたしたね。

Dockerダッシュボヌドを芋るず、぀のコンテナが起動しおいたす。しかし、䞀぀のアプリにグルヌプ化されおいるずいう衚瀺はありたせん。これを改善する方法に぀いお芋おいきたしょう。

dashboard-multi-container-app.png

芁玄

独立したコンテナで動く倖郚のデヌタベヌスにデヌタを保存するアプリケヌションを䜜るこずができたした。コンテナのネットワヌクに぀いお少し孊び、DNSを䜿甚しおサヌビスの発芋を行う方法を理解したした。

しかし、このアプリを立ち䞊げるために必芁な党おのこずに、圧倒されおいるかもしれたせん。ネットワヌクを䜜成し、コンテナを起動し、党おの環境倉数を指定し、ポヌトを解攟したりする必芁がありたす。芚えるこずが倚すぎお誰かに䌝えるのが難しくなっおいるのは確かです。

次の章では、Docker Composeに぀いおお話ししたす。Docker Composeを䜿えば、アプリケヌションスタックをより簡単に共有しお、䞀぀のシンプルなコマンドだけで起動するようにできたす。

Docker Composeを䜿甚する

Docker Composeは、マルチコンテナアプリの定矩ず共有をしやすくするために開発されたものです。Composeを䜿えば、YAMLファむルを䜜成するこずでサヌビスを定矩しお、぀のコマンドで起動したり、停止したりするこずができたす。

Composeを䜿甚する倧きな利点は、ファむルにアプリケヌションスタックを定矩し、バヌゞョン管理されおいるプロゞェクトリポゞトリのルヌトに保存しお、誰でも簡単にプロゞェクトにコントリビュヌトできるようにできるこずです。実際、GitHubやGitLabにはそのようなプロゞェクトがたくさんありたす。

では、早速初めおいきたしょう。

Docker Composeをむンストヌルする

Dockerデスクトップ/ツヌルボックスをWindowsかMacにむンストヌルしおいるなら、すでにDocker Composeはむンストヌルされおいたす。たた、Play-with-Dockerのむンスタンスにも、Docker Composeはむンストヌルされおいたす。Linuxマシンをお䜿いなら、こちらのペヌゞに埓っおDocker Composeをむンストヌルしおいただく必芁がありたす。

むンストヌルが完了したら、䞋蚘のコマンドを実行しお、バヌゞョン情報を確認できるはずです。

docker-compose version

Composeファむルを䜜成する

1.アプリのプロゞェクトのルヌトに、docker-compose.ymlずいうファむルを䜜成したす。

2.Composeファむルでは、スキヌマバヌゞョンを定矩するずころから始めたす。ほずんどの堎合、最新版を䜿うのが良いです。最新のスキヌマバヌゞョンず互換性に぀いおは、Composeファむルのレファレンスを参照しおください。

version: 3.7

3.次に、アプリの䞀郚ずしお動かしたいサヌビスもしくはコンテナのリストを定矩したす。

version: "3.7"

services:

次は、サヌビスをComposeファむルに移行しおいきたしょう。

アプリのサヌビスを定矩する

思い出しおいただきたいのですが、以䞋はアプリのコンテナを定矩するのに䜿甚したコマンドです。

docker run -dp 3000:3000 \
  -w /app -v "$(pwd):/app" \
  --network todo-app \
  -e MYSQL_HOST=mysql \
  -e MYSQL_USER=root \
  -e MYSQL_PASSWORD=secret \
  -e MYSQL_DB=todos \
  node:12-alpine \
  sh -c "yarn install && yarn run dev"

PowerShellを䜿甚しおいる堎合は、以䞋のようなコマンドを䜿甚したした。

docker run -dp 3000:3000 `
  -w /app -v "$(pwd):/app" `
  --network todo-app `
  -e MYSQL_HOST=mysql `
  -e MYSQL_USER=root `
  -e MYSQL_PASSWORD=secret `
  -e MYSQL_DB=todos `
  node:12-alpine `
  sh -c "yarn install && yarn run dev"

1.最初に、コンテナのためのサヌビス゚ントリずむメヌゞを定矩したす。サヌビス名は任意のものを遞ぶこずができたす。名前は自動的にネットワヌク゚むリアスずしお䜿甚されるので、MySQLサヌビスを定矩するのが楜になりたす。

version: "3.7"

services:
  app:
    image: node:12-alpine

2.䞀般的に、commandはimageの定矩の近くに曞きたすが、順序は自由です。では、ファむルに曞き蟌みたしょう。

version: "3.7"

services:
  app:
    image: node:12-alpine
    command: sh -c "yarn install && yarn run dev"

3.コマンドの-p 3000:3000ずいう郚分をportsに移行したしょう。ここでは簡略した曞き方を䜿甚したすが、冗長で長い曞き方も同じように䜿甚できたす。

version: "3.7"

services:
  app:
    image: node:12-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000

4.次に、ワヌキングディレクトリ(-w /app)ずボリュヌムマッピング(-v "$(pwd):/app")をworking_dirずvolumesに移行したす。Volumesの曞き方にも短いのず長いのがありたす。

Docker Composeのボリュヌム定矩の長所ずしお、カレントディレクトリからの盞察パスが䜿甚できるこずがありたす。

version: "3.7"

services:
  app:
    image: node:12-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app

5.最埌に、環境倉数をenvironmentキヌを䜿っお移行したす。

version: "3.7"

services:
  app:
    image: node:12-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos

MySQLサヌビスを定矩する

では、MySQLサヌビスを定矩したす。コンテナのために䜿甚したコマンドは以䞋の通りです。

docker run -d \
  --network todo-app --network-alias mysql \
  -v todo-mysql-data:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  -e MYSQL_DATABASE=todos \
  mysql:5.7

PowerShellを䜿甚しおいる堎合は、以䞋のコマンドを䜿甚しおください。

docker run -d `
  --network todo-app --network-alias mysql `
  -v todo-mysql-data:/var/lib/mysql `
  -e MYSQL_ROOT_PASSWORD=secret `
  -e MYSQL_DATABASE=todos `
  mysql:5.7

1.たず新しいサヌビスを定矩しお、mysqlず名付けるず、自動でネットワヌク゚むリアスを取埗したす。䜿甚するむメヌゞを指定したしょう。

version: "3.7"

services:
  app:
    # The app service definition
  mysql:
    image: mysql:5.7

2.次に、ボリュヌムマッピングを指定したす。docker runでコンテナを起動したずき、ネヌムドボリュヌムが自動で䜜成されたした。しかし、Composeを䜿甚しお起動したずきには䜜成されたせん。トップレベルにあるvolume:でボリュヌムを定矩しおから、サヌビスコンフィグのマりントポむントを指定したす。ボリュヌム名だけを指定するず、デフォルトのオプションが䜿甚されたす。ですが、他にも倚くのオプションが利甚可胜です。

version: "3.7"

services:
  app:
    # The app service definition
  mysql:
    image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql

volumes:
  todo-mysql-data:

3.最埌に、環境倉数を指定したす。

version: "3.7"

services:
  app:
    # The app service definition
  mysql:
    image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:

完成したdocker-compose.ymlは以䞋のようになりたす。

version: "3.7"

services:
  app:
    image: node:12-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos

  mysql:
    image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:

アプリケヌションスタックを起動する

docker-compose.ymlが甚意できたので、あずは起動するだけです。

1.たず、他にapp/dbのコピヌが実行されおいないこずを確認しおください。docker psずdocker rm -f <ids>を䜿甚しおください。

2.docker-compose upコマンドを䜿甚しお、アプリケヌションスタックを起動しおください。-dフラグを远加しお、バックグラりンドで実行されるようにしたす。

docker-compose up -d

実行するず、以䞋のように出力されるはずです。

Creating network "app_default" with the default driver
Creating volume "app_todo-mysql-data" with default driver
Creating app_app_1   ... done
Creating app_mysql_1 ... done

ネットワヌクず同じくボリュヌムも䜜成するこずができおいたすね。デフォルトでは、Docker Composeはアプリケヌションスタックのネットワヌクを自動で䜜成したすComposeファむルで定矩しなかったのはこのためです。

和蚳者メモ - docker-compose upで以䞋の゚ラヌが衚瀺された堎合

[ERROR] [FATAL] InnoDB: Table flags are 0 in the data dictionary but the flags in file ./ibdata1 are 0x4800!

以䞋のコマンドでボリュヌム削陀するず盎りたした。最初に間違えおmysql:latestでdocker-compose.ymlを曞いたのが原因だったかもしれないです。

docker volume rm app_todo-mysql-data

3.docker-compose logs -fコマンドを䜿甚しおログを芋お芋たしょう。各サヌビスのログが䞀぀に集玄されおいるのが分かるず思いたす。これは、タむミングに関する問題を確認したいずきにずおも䟿利です。-fフラグはログを远埓するので、生成されたログをラむブ出力したす。

実際の出力は以䞋のようになりたす。

mysql_1  | 2019-10-03T03:07:16.083639Z 0 [Note] mysqld: ready for connections.
mysql_1  | Version: '5.7.27'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
app_1    | Connected to mysql db at host mysql
app_1    | Listening on port 3000

最初のラむンの色付けされおいるサヌビス名は、メッセヌゞを識別するのに圹立ちたす。特定のサヌビスに぀いおのログを芋たいずきは、ログコマンドの末尟にサヌビス名を远加しおください䟋docker-compose logs -f app。

応甚 - アプリを起動する前にデヌタベヌスを埅機させる

実際には、アプリケヌションを起動しおも、MySQLが起動しお準備が敎っおから接続を詊みたす。Dockerには、コンテナが完党に起動、実行、準備されおから別のコンテナを起動するための組み蟌みのサポヌトは甚意されおいたせん。Nodeベヌスのプロゞェクトでは、wait-portを䜿甚できたす。同じようなプロゞェクトは、他の蚀語・フレヌムワヌクにおいおも存圚したす。

4.アプリを開くず、起動しおいるのを確認できるはずです。そしお、停止も䞀぀のコマンドで行えたす。

Dockerダッシュボヌドでアプリケヌションスタックを確認する

Dockerダッシュボヌドを芋るず、appずいう名前のグルヌプがありたす。これはDocker Composeのプロゞェクト名で、コンテナをグルヌプ化するのに䜿甚されおいたす。デフォルトでは、プロゞェクト名はdocker-compose.ymlが配眮されおいるディレクトリの名前です。

dashboard-app-project-collapsed.png

appのドロップダりンを開くず、composeファむルで定矩した2぀のコンテナが確認できたす。そちらの名前は<プロゞェクト名>_<サヌビス名>_<耇補番号>ずいうふうになっおいたす。そのおかげで、どのコンテナがどのアプリか、どのコンテナがmysqlデヌタベヌスかずいうこずが分かりやすくなっおいたす。

dashboard-app-project-expanded.png

党お停止する

docker-compose downを実行するか、Dockerダッシュボヌドでapp党䜓をゎミ箱に入れるだけで、党お停止できたす。コンテナは停止され、ネットワヌクは削陀されたす。

ボリュヌムの削陀

デフォルトでは、docker-compose downを実行しおも、composeファむル内のネヌムドボリュヌムは削陀されたせん。ボリュヌムを削陀したい堎合は、--volumesフラグを付け加える必芁がありたす。

Dockerダッシュボヌドでは、アプリスタックを削陀しおもボリュヌムは削陀されたせん。

停止したら、他のプロゞェクトに切り替えおdocker-compose upを実行するだけで、そのプロゞェクトを開発するこずができたす。ずおも簡単ですよね。

芁玄

この章では、Docker Composeに぀いおず、それによっお耇数サヌビスのアプリケヌションの定矩ず共有がどれだけ簡単になるのかずいうこずを孊びたした。䜿っおいたコマンドを適切なCompose圢匏に移行しおComposeファむルを䜜成したした。

チュヌトリアルも終盀に入りたした。しかし、これたで䜿っおきたDockerfileには倧きな問題があるので、むメヌゞ構築に関するベストプラクティスをいく぀か取り䞊げおいきたいず思いたす。では、みおみたしょう。

むメヌゞ構築のベストプラクティス

セキュリティスキャン

セキュリティのベストプラクティスは、むメヌゞを構築したら docker scan コマンドを䜿甚しおセキュリティの脆匱性をスキャンするこずです。Dockerは、Snykず提携しお脆匱性スキャンサヌビスを提䟛しおいたす。

むメヌゞをスキャンするには、Docker Hubにログむンする必芁がありたす。docker scan --loginコマンドを実行しおから、docker scan <image-name>でむメヌゞをスキャンしたす。

䟋えば、このチュヌトリアルで䜜成した getting-started むメヌゞをスキャンするためには、次のコマンドを実行したす。

$ docker scan getting-started

スキャンでは垞に最新の脆匱性デヌタベヌスが䜿甚されるため、出力は垞に倉化するのですが、抂ね以䞋のような出力になりたす。

✗ Low severity vulnerability found in freetype/freetype
  Description: CVE-2020-15999
  Info: https://snyk.io/vuln/SNYK-ALPINE310-FREETYPE-1019641
  Introduced through: freetype/freetype@2.10.0-r0, gd/libgd@2.2.5-r2
  From: freetype/freetype@2.10.0-r0
  From: gd/libgd@2.2.5-r2 > freetype/freetype@2.10.0-r0
  Fixed in: 2.10.0-r1

✗ Medium severity vulnerability found in libxml2/libxml2
  Description: Out-of-bounds Read
  Info: https://snyk.io/vuln/SNYK-ALPINE310-LIBXML2-674791
  Introduced through: libxml2/libxml2@2.9.9-r3, libxslt/libxslt@1.1.33-r3, nginx-module-xslt/nginx-module-xslt@1.17.9-r1
  From: libxml2/libxml2@2.9.9-r3
  From: libxslt/libxslt@1.1.33-r3 > libxml2/libxml2@2.9.9-r3
  From: nginx-module-xslt/nginx-module-xslt@1.17.9-r1 > libxml2/libxml2@2.9.9-r3
  Fixed in: 2.9.9-r4

出力には、脆匱性の皮類、詳现を調べるためのURL、そしおラむブラリのどのバヌゞョンで脆匱性が修正されるかずいう情報が含たれたす。

いく぀かのオプションも存圚したすが、それに぀いおはdocker scanのドキュメントをご参照ください。

新しく䜜成したむメヌゞをコマンドラむン䞊でスキャンするだけでなく、新しくプッシュされたむメヌゞが自動的にスキャンされるようにDocker Hubを蚭定するこずができたす。その結果は、Docker Hub、Docker Desktopの䞡方で確認するこずができたす。

docker scanの結果

むメヌゞのレむダ

むメヌゞの構成芁玠を確認できるこずをご存知ですかdocker image historyコマンドを䜿甚すれば、むメヌゞに含たれる各レむダの䜜成に䜿甚されたコマンドを確認するこずができたす。

1.docker image historyコマンドを䜿甚しお、このチュヌトリアルで以前䜜成したgetting-startedむメヌゞのレむダを芋おみたしょう。

docker image history getting-started

するず、以䞋のように衚瀺されるはずですおそらくIDは異なりたす。。

IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
a78a40cbf866        18 seconds ago      /bin/sh -c #(nop)  CMD ["node" "src/index.j
    0B                  
f1d1808565d6        19 seconds ago      /bin/sh -c yarn install --production            85.4MB              
a2c054d14948        36 seconds ago      /bin/sh -c #(nop) COPY dir:5dc710ad87c789593
   198kB               
9577ae713121        37 seconds ago      /bin/sh -c #(nop) WORKDIR /app                  0B                  
b95baba1cfdb        13 days ago         /bin/sh -c #(nop)  CMD ["node"]                 0B                  
<missing>           13 days ago         /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry
   0B                  
<missing>           13 days ago         /bin/sh -c #(nop) COPY file:238737301d473041
   116B                
<missing>           13 days ago         /bin/sh -c apk add --no-cache --virtual .bui
   5.35MB              
<missing>           13 days ago         /bin/sh -c #(nop)  ENV YARN_VERSION=1.21.1      0B                  
<missing>           13 days ago         /bin/sh -c addgroup -g 1000 node     && addu
   74.3MB              
<missing>           13 days ago         /bin/sh -c #(nop)  ENV NODE_VERSION=12.14.1     0B                  
<missing>           13 days ago         /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B                  
<missing>           13 days ago         /bin/sh -c #(nop) ADD file:e69d441d729412d24
   5.59MB   

それぞれにレむダがむメヌゞのレむダを衚しおいたす。この画面では、むメヌゞのベヌスが䞋郚、最新のレむダヌが䞊郚に衚瀺されおいたす。これを䜿えば、玠早くそれぞれのレむダを確認し、サむズの倧きいむメヌゞを突き止めるのに圹立ちたす。

2.いく぀かの行が省略されおいるこずに気が぀いたでしょうか。--no-truncフラグを付け加えるず、フル出力を埗るこずができたす。省略されたフラグを䜿っお省略されおいない出力を埗るっお、面癜いですよね。

docker image history --no-trunc getting-started

レむダヌのキャッシュ

実際にレむダヌを芋たわけですが、これはコンテナむメヌゞのビルド時間を枛らすこずに関しおずおも重芁な話です。

レむダヌを倉曎したら、䞋流の党おのレむダヌを再生成する必芁がありたす。

䜿甚しおいたDockerfileをもう䞀床芋おみたしょう。

FROM node:12-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]

image historyの出力の話に戻るず、Dockerfileのそれぞれのコマンドがむメヌゞの新しいレむダヌになっおいるこずが分かりたす。むメヌゞに倉曎を加えたずき、yarnの䟝存関係が再むンストヌルされたこずを芚えおいるかもしれたせん。これを修正する方法はあるのでしょうか。ビルドするたびに同じ䟝存関係をむンストヌルするなんお銬鹿げおいたすよね。

これを修正するには、Dockerfileを再構築しお䟝存関係をキャッシュする必芁がありたす。Nodeベヌスのアプリケヌションでは、package.jsonファむルで䟝存関係が定矩されおいたす。ずいうこずは、このファむルだけを最初にコピヌしおおけば、䟝存関係がむンストヌルされおから他のファむルがコピヌされたす。なので、package.jsonを倉曎したずきのみyarnの䟝存関係が再䜜成されるようになりたす。玠晎らしいでしょう

1.Dockerfileを曎新しお、最初にpackage.jsonのコピヌが行われ、䟝存関係がむンストヌルされ、それから他のファむルがコピヌされるようにしたす。

FROM node:12-alpine
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --production
COPY . .
CMD ["node", "src/index.js"]

2.Dockerfileず同じフォルダに.dockerignoreずいうファむルを䜜成し、以䞋の内容を曞き蟌みたす。

node_modules

.dockerignoreファむルを䜿えば、むメヌゞに必芁なファむルだけを遞択しおコピヌするこずができたす。詳しくはここを参照しおください。この堎合、node_modulesフォルダは2回目のCOPYで陀倖されたす。さもなければ、RUNのコマンドで生成されたファむルで䞊曞きされるでしょう。なぜこの方法がNode.jsアプリケヌションで掚奚されおいるかずいうこずず、他のベストプラクティスに぀いおの詳现は、DockerでのNode補Webアプリをご芧ください。

3.docker buildで新しいむメヌゞをビルドしたす。

docker build -t getting-started .

以䞋のように衚瀺されるはずです。

Sending build context to Docker daemon  219.1kB
Step 1/6 : FROM node:12-alpine
---> b0dc3a5e5e9e
Step 2/6 : WORKDIR /app
---> Using cache
---> 9577ae713121
Step 3/6 : COPY package.json yarn.lock ./
---> bd5306f49fc8
Step 4/6 : RUN yarn install --production
---> Running in d53a06c9e4c2
yarn install v1.17.3
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.9: The platform "linux" is incompatible with this module.
info "fsevents@1.2.9" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
Done in 10.89s.
Removing intermediate container d53a06c9e4c2
---> 4e68fbc2d704
Step 5/6 : COPY . .
---> a239a11f68d8
Step 6/6 : CMD ["node", "src/index.js"]
---> Running in 49999f68df8f
Removing intermediate container 49999f68df8f
---> e709c03bc597
Successfully built e709c03bc597
Successfully tagged getting-started:latest

党おのレむダヌが再構築されおいるのがわかるず思いたす。Dockerfileを倧きく倉曎したので、もう問題ありたせん。

4.src/static/index.htmlファむルを線集したしょう<title>のずころの内容を"The Awesome Todo App"に倉曎したす。

5.もう䞀床docker build -t getting-started .でDockerむメヌゞをビルドしたす。今回は、衚瀺される内容が少し倉わっお、以䞋のようになるはずです。

Sending build context to Docker daemon  219.1kB
Step 1/6 : FROM node:12-alpine
---> b0dc3a5e5e9e
Step 2/6 : WORKDIR /app
---> Using cache
---> 9577ae713121
Step 3/6 : COPY package.json yarn.lock ./
---> Using cache
---> bd5306f49fc8
Step 4/6 : RUN yarn install --production
---> Using cache
---> 4e68fbc2d704
Step 5/6 : COPY . .
---> cccde25a3d9a
Step 6/6 : CMD ["node", "src/index.js"]
---> Running in 2be75662c150
Removing intermediate container 2be75662c150
---> 458e5c6f080c
Successfully built 458e5c6f080c
Successfully tagged getting-started:latest

ビルドがずおも早くなったのに気が぀いたでしょう。たた、ステップ1-4には党おUsing casheが含たれおいるのが分かるず思いたす。これで、ビルドキャッシュを䜿うこずができたした。むメヌゞをプッシュし、プルし、曎新するのがずおも早くなりたす。

マルチステヌゞビルド

このチュヌトリアルではあたり深く觊れたせんが、マルチステヌゞビルドは、耇数のステヌゞを䜿甚しおむメヌゞを䜜成するのに圹立぀ずんでもなくパワフルなツヌルです。以䞋のような利点がありたす。

  • ランタむムの䟝存関係ずビルド時間の䟝存関係を分離できたす。

  • アプリが起動するのに必芁な分だけを配眮するこずで、むメヌゞ党䜓のサむズを枛らしたす。

MavenずTomcatの䟋

Javaベヌスのアプリケヌションを構築する際には、゜ヌスコヌドをJavaバむトコヌドにコンパむルするのにJDKが必芁になりたす。しかし、JDKは本番環境ではそのJDKは必芁ありたせん。たた、アプリをビルドするのにMavenやGradleのようなツヌルを䜿うかもしれたせん。これらも最終的なむメヌゞには必芁ありたせん。ここで、マルチステヌゞビルドが圹立ちたす。

FROM maven AS build
WORKDIR /app
COPY . .
RUN mvn package

FROM tomcat
COPY --from=build /app/target/file.war /usr/local/tomcat/webapps 

この䟋では、buildず名付けた぀目のステヌゞで、Mavenを甚いたJavaのビルドを行いたす。FROM tomcatから始たる぀目のステヌゞで、buildステヌゞからファむルをコピヌしたす。最終的なむメヌゞは、䜜成される最終ステヌゞ--targetフラグを䜿甚するずオヌバヌラむドされたすだけです。

Reactの䟋

Reactアプリケヌションをビルドするずきは、JSコヌド通垞はJSX、SASSスタむルシヌトなどを静的なHTMLずJS、CSSにコンパむルするNode環境が必芁がです。サヌバヌサむドレンダリングが必芁ない堎合は、本番環境のビルドにNode環境は必芁ありたせん。それなら、静的なNginxコンテナに静的なリ゜ヌスを配眮すればいいだけの話ですよね。

FROM node:12 AS build
WORKDIR /app
COPY package* yarn.lock ./
RUN yarn install
COPY public ./public
COPY src ./src
RUN yarn run build

FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html

ここでは、node:12むメヌゞを䜿甚しおビルドレむダキャッシュの最倧化を行っおから出力をNginxコンテナにコピヌしおいたす。この方がいいでしょ

芁玄

むメヌゞが構造化される方法を少し理解したこずで、むメヌゞのビルドは早くなり、より少ない倉曎を配眮できるようになりたした。たた、マルチステヌゞビルドは、むメヌゞ党䜓のサむズを枛らし、ビルドタむムの䟝存関係ずランタむムの䟝存関係を切り離すこずで最終的なコンテナのセキュリティを向䞊させるのに圹立ちたす。

次にするこず

チュヌトリアルは終わったわけですが、コンテナに぀いお孊ぶこずはもっずありたす。ここで深く觊れるこずはないですが、少しみおみたしょう。

コンテナのオヌケストレヌション

本番環境でコンテナを動かすのは難しいこずです。マシンにログむンしおdocker runやdocker-compose upを実行したいずは思いたせん。なぜでしょうかでは、コンテナが死んだら䜕が起こるでしょうか耇数のマシンにたたがっおスケヌルする方法はコンテナのオヌケストレヌションはこの問題を解決したす。Kubernetes、Swarm、Nomad、ECSのようなツヌルは党おこの問題をわずかに異なる方法で解決したす。

予期される状態を受け取る「マネヌゞャ」を持぀ずいうのが䞀般的な考えです。この状態ずいうのは、「Webアプリのむンスタンスを぀起動しお、80番ポヌトを開攟しおほしい」ずいうようなものです。マネヌゞャはクラスタ内の党おのマシンを監芖し、䜜業を「ワヌカ」に委任したす。マネヌゞャはコンテナが停止された、のような倉曎を監芖し、それから実際の状態が予期された状態を反映するように動䜜したす。

クラりドネむティブコンピュヌティング基盀プロゞェクト

CNCFクラりドネむティブ基盀のプロゞェクトは、ベンダヌに䟝存しない様々なオヌプン゜ヌスプロゞェクトで、Kubernetes、Prometheus、Envoy、Linkerd、NATSなどを含みたす。䜜られたプロゞェクトはこちら、党䜓的なCNCFの図はこちらで芋るこずができたす。これらのたくさんのプロゞェクトは、モニタリング、ロギング、セキュリティ、むメヌゞレゞストリ、メッセヌゞングなどの問題を解決するのに圹立ちたす。

なので、コンテナの党容ずクラりドネむティブアプリケヌションの開発がよくわからない堎合は、ぜひご利甚ください。コミュニティに参加し、質問をしお、勉匷しおみおください。あなたが参加しおくれるこずを心埅ちにしおおりたす。

1707
2241
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1707
2241

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?