DockerのDの字も分からない状態を抜け出すためにやって良かったことをまとめてみる

# 概要

Dockerを触っていく上で、何を勉強したら良いかで行き詰まることが多かったので、勉強していて特に役に立ったな、と思ったものを備忘録がてら整理してみます。

# 対象読者

Dockerに入門したはいいけれど、インフラもLinuxも全然わからん、でも何とかしたい、というレベルの話が中心となっています。
k8sまで踏み込んだり、Dockerをバリバリ実務で使いこなすためのベストプラクティスなどなど、深い部分は対象外としています。むしろ、そういうのがあったら読みたいです。

また、本記事では、Webアプリの実行環境をDockerで構築できるようになるために必要な知識にフォーカスしています。そのため、データベースを利用した簡単なWebアプリをつくった経験があると、Dockerを勉強するモチベーションが高まるかもしれません。

# 前置き

1年ほど前に、ふとしたきっかけで、**Dockerやるか**と思い立ちます。Dockerは入門記事が充実しており、見よう見まねでとりあえず動かせないこともないところまでは、サクッと進みました。
しかし、当時はLinuxやインフラ系の知識が皆無だったこともあり、動作原理どころか、そもそも自分が何をやっているのかも曖昧で、入門から先は手も足も出ませんでした。

Dockerそのものの入門記事は数多くありましたが、`Dockerを理解するためにどんな知識が必要か`の全体像がまとまっているものは、中々見つけられませんでした。
Dockerは私にはまだ早いなぁ...と思い、でもやっぱりDockerわかるようになりたいなぁ...と気にかけながら、あれこれ色々手を出し、勉強していました。

まだまだDocker完全に理解した状態には程遠いですが、基本部分の理解に必要な前提知識はそれなりに補強できたのか、Dockerの動作が全くイメージできていない状態からは、なんとか脱出できた...はずです。

---

Dockerなんもわからん状態を辛うじて抜け出せたとはいえ、何をどこまでやれば、Dockerの苦手意識をなくせるかが分からず、手探りの状態が続くのは中々にしんどかったです。
ですので、備忘録がてら、これはやっておいて良かったな、と思ったものをまとめておこうと思います。
これさえやれば、Dockerはもう完璧!!...なんてことはありませんが、なにかの参考になれば幸いです。

以下では、本を中心に紹介していきます。このとき、それぞれについて、`何を学ぶことを目的とするか`を意識しておくとよいかもしれません。
目安となるかは分かりませんが、以下はやって良かったことの紹介に加え、何を学ぶことを目指して取り組んだかも、あわせて記述していきます。

# Linux

コンテナ内での操作はもちろんのこと、Dockerの仕組みを学ぶ上では、何よりLinuxの理解が欠かせません。
とは言え、Linux単体だけを見ても勉強する内容は非常に幅広く、何から手をつけるべきか、悩みやすい部分でもあります。
以下では、基礎的なコマンドや、コンテナ内の操作、そして、Dockerの動作原理を理解する上で、助けられた書籍を挙げていきます。

### [新しいLinuxの教科書](https://ozuma.hatenablog.jp/entry/20150605/1433516238)

* 学べること: シェルを中心としたLinuxの基本知識・コマンド

元々Linuxを扱う機会はぽつぽつとありましたが、書籍を利用してじっくり学ぶのは、これが初めてとなりました。
結論から言うと、最初にこの書籍から始めたのは、大正解だったと思っています。シェルとはなんぞやから始まり、雰囲気でなんとなく使っていたコマンドについて、一つ一つ丁寧に知識を積み上げるような形で紹介されているため、とても読みやすいです。

コンテナの中での操作は、大抵の場合、Linuxのシェル操作が前提知識として必須になります。まずはここからスタートすれば、コンテナに入っても何をしたらいいか分からず、しんどい思いをすることもなくなるかと思います。
Linuxの基礎がぎゅっと詰まっているので、これからも定期的に読み返していきたいと思います。

---

### [ゼロからはじめるLinuxサーバー構築・運用ガイド 動かしながら学ぶWebサーバーの作り方](https://www.amazon.co.jp/dp/B01HTKLXCW/?_encoding=UTF8&btkr=1)

* 学べること: シェル操作によるアプリケーション実行環境の構築方法

Dockerを学習するメリットとして、環境構築が容易になることがよく挙げられます。これを実感してこそ、Dockerを学ぶモチベーションも高まってきます。

そこで、シェル操作に慣れてきたところで、実際に本をベースに、手を動かしながら環境構築をやってみました。今のご時世なら、VPSやクラウドサービスなどを活用すれば、安価にサーバを構築することができます。
勉強がてら、まずはコンテナではなく、実際にサーバとして構築してみるとよいかと思います。
セキュリティ面で不安がある場合は、VMを利用してみるのもよいかもしれません。

この本は、サーバ構築に必要な知識を補強しながら、LAMP環境をつくり上げるまでを学べる構成になっています。あいだにネットワークの話が入り、そこでも説明はされていますが、もし詰まった場合は、先にネットワークを勉強してから再挑戦すると、つらくないかもしれません。

---

### [試して理解Linuxのしくみ ～実験と図解で学ぶOSとハードウェアの基礎知識](https://www.amazon.co.jp/dp/B079YJS1J1/?_encoding=UTF8&btkr=1)

* 学べること: カーネルを中心とした、Linuxの各種機能の基本動作原理

>Dockerはkernelを共有する

なんて言葉があるように、Dockerを深く知るには、カーネルの理解が重要です。しかし、カーネルを理解するためには、幅広い分野の深い知識・経験が必要となります。
カーネルをしっかり学習するのであれば、難しくて分厚い本に立ち向かう覚悟を持たなければなりませんが、Dockerに入門する段階であれば、こういった入門書1冊でも十分だと思います、きっと...。

少し話は逸れましたが、この本は、難しい概念を、豊富な図で分かりやすく説明されています。文章で少し迷子になっても、すぐにイメージを補強するための図で補ってくれるため、難しい本でよくある途中リタイアを防いでくれることでしょう。

更に、図解だけにとどまらず、プロセス管理やメモリ管理などを、実際にC言語で書かれたサンプルコードによって、イメージをコードと結びつけながら学ぶことができます。
この結びつきは、時間の掛かることではありますが、ただ字面を追っただけでは得られないレベルまで、理解を深めてくれます。

実際にこの本を読んだあとでは、Dockerの動作原理がかなりイメージしやすくなりました。メモリ管理の辺りからぐんぐん難易度が上がっていきますが、じっくり取り組む価値はおおいにあると思います。

※1 C言語自体の勉強は、[苦しんで覚えるC言語](https://9cguide.appspot.com/)がわかりやすくておすすめです。
※2 前半部分で既に難易度が高いと感じる場合は、「プログラムはなぜ動くのか」・「コンピュータはなぜ動くのか」を読んでおくと、立ち向かいやすくなるかもしれません

---

# ネットワーク

Dockerを扱う際、コンテナ間通信のイメージが掴みづらく、最初の頃は理解に苦戦していました。
当時はネットワーク関連の知識が非常に浅く、また、業務で携わる機会もほとんどなかったため、個人的に一番つまずいた部分だと感じています。

ネットワークそのものは言わずもがな、勉強する範囲が非常に広いです。ですが、Dockerのネットワークまわりを理解するのが目的であれば、レイヤー2とレイヤー3を中心に勉強すると、とっつきやすくなるかもしれません。


### [3分間ネットワーク基礎講座](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88-3%E5%88%86%E9%96%93%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E5%9F%BA%E7%A4%8E%E8%AC%9B%E5%BA%A7-%E7%B6%B2%E9%87%8E-%E8%A1%9B%E4%BA%8C/dp/4774143731)

* 学べること: レイヤー1～3を中心とした、ネットワーク関連の各用語の概要

ウェブサイトで公開されているものの書籍版です。レイヤー1〜レイヤー3を中心に、対話形式で各種用語について、図を交えながら書かれています。
ネットワーク関連の書籍を読んでいて、この辺りのレイヤーは、業務や趣味でも触る機会が中々なく、概要を理解するのに苦労していました。特に、最初の頃は、イーサネットの規格や、物理学のあれこれの話など、深く踏み入った話とあわせて解説されると、戸惑ってしまうことがよくありました。

対して、この書籍は、踏み込み過ぎず、かつ、浅すぎず、丁度いい塩梅で各用語について書かれているので、最初の一歩におすすめです。サクッと読める文量なので、まずはネットワーク関連の用語に慣れるためにも、数回繰り返し読んでみるのもありかもしれません。また、ウェブサイト版も書籍版とは色々異なる部分があるので、興味があったら目を通してみてください。


### [パケットキャプチャの教科書](https://www.amazon.co.jp/dp/B076CWFDB8/?_encoding=UTF8)

* 学べること: パケットと、図解による、ネットワーク通信の流れの具体的なイメージ

たとえばプログラムであれば、文法を学んだ後、実際にソースコードを書くことで、経験を通じて知識を定着させることができます。しかし、ネットワークに関しては、実際の通信を覗いたり、操作するための道程は、プログラムを書くときほど情報が充実しているとは言えません。

そんな中、この書籍に出会うことで、ネットワークへの苦手意識も少しだけマシになりました。構成自体はよくある各レイヤーについて解説したものではありますが、何と言っても、各レイヤーについて、実際のパケットの様子を、流れを丁寧に記述した図もあわせ、事細かに解説してくれている点がありがたいです。
各レイヤーのざっくりとした知識は前提として必要にはなりますが、繰り返し読むことで、ネットワークに関する知識を教科書的な段階から一歩先へ引き上げてくれるはずです。

また、本番サーバとしてDockerを利用する際には、HTTPS対応や、DNSなど、レイヤー1～3以外の知識も必要となるため、都度読み返すと、応用の際にもスムーズに学べるかもしれません。

※用語についていくのがしんどいと感じた場合は、「TCP/IPの絵本」から入るのもアリだと思います。

### [Linuxで動かしながら学ぶTCP/IPネットワーク入門](https://blog.amedama.jp/entry/linux-tcpip-book)

* 学べること network namespaceの概要と、TCP/IPの各レイヤーの実際の通信の様子のイメージ

最近出た本ではありますが、読んでいてとても面白かったので、ここで紹介します。
Dockerではnetwork namespaceなるものを使うことで、仮想的なネットワークを設定することができる、といった感じの説明をよく見ますが、実際のところ、これだけでは、いまいちピンと来ません。

この書籍では、実際にnetwork namespaceで仮想的なネットワークを作成するだけにとどまらず、イーサネットや、IPでの通信を、ネットワークインタフェースを設定するところから丁寧に解説してくれています。

TCP/IPの各レイヤについて、network namespaceで通信に必要な設定・インタフェースを構築し、tcpdumpで実際の通信を確認しながら、`通信ができるようになるまで`を段階的に見ることができます。
Linuxの基礎を学び、上で挙げたネットワークの書籍に目を通したあとで取り組んでみると、ネットワークによってコンピュータ同士が通信できるようになるまでの流れがより深く学べることでしょう。

また、network namespaceで実際にインタフェースを設定することで、Dockerのネットワーク周りの理解も、更に進むかと思います。

---

(余談)
ネットワークの入門書と言えば、「ネットワークはなぜつながるのか」や「マスタリングTCP/IP 入門編」が定番として挙げられています。これらの書籍は確かに分かりやすく書かれていますが、ネットワークの知識がほとんど無い状態で挑むとかなり苦労することになります。(私はここから入ってめちゃくちゃ苦労しました)

まずは上記で挙げた入門書に目を通し、何らかの形で実際にネットワーク関連の知識が必要となった際、取り組んでみると、十分に楽しめるのではないかと思います。

# Docker

Dockerの使い方を学ぶには、当然、Dockerそのものを勉強することも必要です。Dockerの入門情報は、Qiitaを始めとし、ネット上にたくさんの優れたものがあります。`Docker 入門`で検索し、良さそうだと思ったものをいくつか触っていけば、雰囲気はつかめるかと思います。
このとき、ただ読むだけでなく、実際に手を動かしながら、Dockerfileを書いてみたり、Docker Composeを使ってみたり、あれこれ試しながら、失敗したり、成功したり、といったことを経験するのが重要です。

最初のうちは各コマンドや、設定の記述が、なぜ必要なのかイメージが掴めず、苦労するかと思います。ですが、これまで挙げてきたもので基礎知識を身につけていれば、前提知識が足りず手も足も出ないということにはならないはずですので、少しずつでも理解を進められるはずです。

以下に、いくつか私が取り組んできたものを挙げますので、何から始めたら良いか迷っている場合は、練習問題がてら、触ってみるとよいかもしれません。

* C言語の実行環境
* Python + Pytestの実行環境
* create-react-appを利用したReactの実行環境
* デプロイされたWarファイルを実行するTomcat環境
* Django + RDBMSそれぞれをコンテナ化し、DjangoアプリのデータをDBに保存可能とする環境


このとき、大抵のものは便利なイメージとして、既に公開されていたりしますが、最初のうちは、勉強も兼ねて、好きなLinuxディストリビューションをベースイメージとして構築してみると、理解が深まるかと思います。

---

ただ、やはり体系的に学ぶ上では、本を活用したいものです。
以下では、Dockerの入門書について、いくつか読んできた中で、特に良かったものを紹介します。


### [マンガでわかるDocker](https://booth.pm/ja/items/825879)

* 学べること: Dockerとはなんぞや～Dockerfileの基本あたりまで

全3冊ありますが、入門段階では、1巻・2巻だけでも十分だと思います。漫画形式でDockerの用語について解説されているので、「イメージ」や「コンテナ」などの言葉の意味は分かっていても、頭の中でイメージしづらい状態から脱するのに適しています。
ネット上の入門記事とあわせて読めば、最初の一歩として十分な理解が得られるでしょう。

### [Docker Deep Dive](https://www.amazon.co.jp/dp/B01LXWQUFF/?_encoding=UTF8)

* 学べること: Dockerの基本的な概念の網羅・動作原理のさわり部分の理解

英語の書籍なので、一見難しそうに感じてしまいますが、難しい英単語や表現は使われていないので、英語がどうしようもないほど苦手でもなければ、ぜひ読んでみて頂きたいです。
Dockerの各種要素について、「概要」・「詳解」・「コマンド」形式で章立てて解説されており、ある章でいきなり難易度が跳ね上がることもないので、一歩ずつ確実に学ぶことができます。

ある程度手を動かした後に読んでみると、断片的に散らばっていた知識が明快な章立てにより、繋がることで、「Dockerなんも分からん」状態を抜け出せるはずです。
しっかりと内容を理解するには、Linuxやネットワークなど、幅広い知識が必要にはなりますが、これまで紹介したものを積み上げていけば、きっと立ち向かえることでしょう。


# その他

Dockerそのものの理解とは少しずれますが、これもやって良かったな、と思ったことを以下にいくつか紹介します。

### Vim

[Vim Masterclass](https://www.udemy.com/course/vim-commands-cheat-sheet/)

* 学べること: コンテナ内のファイル編集を手軽に行うための知識

コンテナに入ってちょっと設定ファイルなどを操作するとき、ホストからあれこれしたり、エディタの拡張機能などでも対応はできます。ですが、こういうときにサクッと操作できるツールがあればとても便利です。
そんなときに、Vimを勉強しておくと、コンテナの中でも快適に過ごせます。

Vimそのものについては、随所で熱く語られているため、詳細は割愛します。拡張機能ましましでカスタマイズするのでもなければ、上記のUdemyのコースで勉強すると、数時間で簡単な使い方を理解することができます。
英語ではありますが、字幕機能もありますし、何より練習問題がVimの基本操作を学ぶのに丁度いい形でつくられているので、Vimの良さを飽きることなく学べることでしょう。

### Git

[わかばちゃんと学ぶ Git使い方入門](https://www.amazon.co.jp/dp/B071D4D6XX/?_encoding=UTF%EF%BC%98)

[エンジニアのためのGitの教科書［上級編］ Git内部の仕組みを理解する](https://www.amazon.co.jp/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEGit%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8%EF%BC%BB%E4%B8%8A%E7%B4%9A%E7%B7%A8%EF%BC%BD-Git%E5%86%85%E9%83%A8%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B-%E6%B2%B3%E6%9D%91%E8%81%96%E6%82%9F-ebook/dp/B01AAIN85K)

* 学べること: Gitの基本コマンドとその仕組み

Gitそのものを知らなくてもDockerは理解できるかとは思います。しかし、Dockerで構築した環境で管理するアプリのソースコードは基本Gitで管理することとなるので、あわせて学んでおいて損はないです。

Gitはネット上はもちろんのこと、書籍もここに挙げた以外にも、素晴らしいものが充実しているので、迷子になるようなこともないかと思います。

---

# まとめ

ちょっと整理するか、ぐらいの軽い気持ちで書き始めたら、思ったよりも長くなってしまいました。
Dockerを単なるツールとして使うためであれば、ここまでやらなくても、このコマンドを叩けばこうなる、と暗記し、用意されている素敵なイメージを使うことで、それなりのことはできてしまいます。

ですが、個人的には、多少遠回りにはなっても、基礎からしっかり学んで、**なぜ**を追求していく方が良いと考えています。

これは優劣としてではなく、ただ単に、その方が楽しいからです。Dockerをきっかけに、ネットワークやLinuxに手を伸ばすようになり、1年ほど前よりもDockerはもちろんのこと、インフラ周り、Linuxのことが好きになりました。好きなものが増え、そこから更に深く学ぶと、知的好奇心が刺激され、それはそれは楽しいものです。

これ以上書くと脱線してしまうので、割愛しますが、この記事が少しでも楽しい学びの一助となれば幸いです。