【Docker入門】生まれて初めてWindowsからコンテナ上に開発環境を立ち上げる

※現在進行形で勉強しているDockerに関する記事です。毎週日曜日更新予定。
質問などへの対応も日曜日に記事へ反映されるのでお気軽にお問い合わせください。
[お問い合わせは質問箱へ](https://peing.net/ja/eieio81810)

～お願い～
役立ったな～って思ったらTwitterをフォローしたり、私宛てに気になっているビジネスやサービス、技術の名前をひとことでも詳しくでもいいので教えにきてください。


##はじめに
私は駆け出しエンジニアである。自分の未熟さすらも如何ほどかわからない。



なぜそう感じるのか。

それは「わからないところがわからない」からである。

これでは人に質問することも、わからない技術が何か調べることもできないだろう。
当記事をは自分用の備忘録である。
だが、読む人で以下のどれかに当てはまる場合は私と状況が似ているため読み進めても損はないだろう。

 - 開発はしたことがあるけどDockerを触ったことはない。
 - 断片的な情報を集めてDockerを始めるのが面倒くさい
 - わからんところがわからん

こういった人に読み進めてもらえて、わからないところが出たときに質問などをもらえたら嬉しく思う。自分が直面しているトラブルが、自分だけのものではないということを実感できるからだ。

では本題に進もう。

##0.開発に至った経緯

ざっくり書くとこんな感じである。
【経緯】
仕事で開発するの楽しい～→休日も開発したいなぁ→せっかくだから仕事の領域とは違う領域の開発でもやってみるか→なぜか手元にあるC言語の本をやろう→環境構築って手間だしせっかく新しいPCにしたのに環境を汚すの嫌だなぁ…→この際Dockerを初めてみるか！

開発が楽しくなりPCを新調したものの、過去にあった

 - ローカルの環境がめっちゃ汚くなる
→見栄えが悪い、ストレスがたまる、ファイルを探すときに邪魔

 - どこにファイルが作られたのかわからない
→かなりストレス、ファイルを参照しなければならないときにWebで調査する必要が出てくる、関係ないファイルも精査する必要が出てくる

 - 自分の開発環境で実践できる知識かわからない（VS Codeを使ったgitの記事を見ながらVS 2019で対応しようとした）
→2度手間が何度も発生する。若干のストレス

という問題には恒久的な対応を施したいと思っていた。

そこでDockerを使うにあたり、次の3点をゴールに掲げた。

 - 開発に関係するソースを1つのディレクトリに集約すること
 - 休日の趣味開発をするために環境構築の手間を減らすこと
 - 開発ソースのバージョン管理ができるようになること

※※※
疑問が生まれるたびに解決していくスタイルで開発を進めているため、ゴールには中々辿り着きません。

##1.Dockerってなに？

Dockerについては「箱庭っぽいやつ」程度の認識しか持っていなかった。

```text:Google検索
Docker
```

Dockerにコンテナ型の仮想化技術を使われていることは知っていたが、今までの仮想化技術（ハイパーバイザ型というらしい）と何が違うのか、さっぱりわからなかった。調べてみた結果、

https://www.pasonatech.co.jp/workstyle/column/detail.html?p=2675

記事によるとどうやらコンテナ型はハイパーバイザ型（仮想化技術）と違ってゲストOSが存在しないようだ。

###コンテナ型とハイパーバイザ型って？

**普通の開発**
🤷‍♂️＜開発するぞ。さ、開発をするために部品集めだ
🚀部品１（パッケージとか）
🛸部品２（ソースとか）
🚨部品３（なんか色々）
………
……
…
🤷‍♂️＜バージョン管理とか環境の再構築とかしんどいなぁ
パソコン1台毎に違いが出てくる。しんどい

**コンテナ型**
🤷‍♂️＜開発するぞ。さ、開発をするために部品集めだ
箱の中に入れておこう
■■■■■■■■■
■■🚀🛸🚨■■
■■■■■■■■■
………
……
…
🤷‍♂️＜管理はしやすくなったぞ。でもMacで作られた箱はWindowsでほぼ使えないなぁ

**ハイパーバイザ型**
🤷‍♂️＜開発するぞ。さ、開発をするために部品集めだ
PCの中にPCを立ち上げよう
💻
■■■■■■■■■
■■🚀🛸🚨■■
■■■■■■■■■
………
……
…
🤷‍♂️＜完璧だ！…けどさすがに動作が遅いなぁ

###Dockerってどうなってるの？

まずDockerにはWindows版、Mac版、Linux版がある。
Dockerコンテナ上ではLinuxカーネルが動作するようになっている。

https://ararabo.com/2020-06-21/?p=10833

Linux版DockerにおいてはホストOSがLinuxだから何も言うことはない。100%コンテナ型仮想化である。
Windows版DockerはWindowsがWSL2（Windows Subsystem for Linux 2）に命令を出し、それを受け取ったWSL2がDockerを動かす仕組みになっている。コンテナ型とハイパーバイザ型のハイブリッドである。
Mac版Dockerも似たような感じであるが、あまり詳しくないので割愛する。

http://docs.docker.jp/engine/installation/mac.html#id2

https://qr.ae/pGkCVk

###Windows版とMac版はVMWareでも良くない？
やっていることとしてはVMWareと大差ない。それでもDockerを使う人が増えているのは「各OSがLinuxカーネルに対応し始めている（容量の小さなゲストOSみたいな存在がいるイメージ）」「ゲストOSを作る必要がない」「環境の構成をシェアして各PCで同じ環境をビルドすることができる」など、軽量かつ共有が容易な点にある。

https://qr.ae/pGkM6K

感想ベースの理由なため、使うかどうかは各自の感覚で判断すれば良い。
今回、Dockerの仕組みを理解したことで私は今後開発を続けていくために使ってみたいと感じたため、使うことにした。

##2.Docker使ってみよう
自分の使ってるPCのOSでどうやったらDockerを使うことができるのか。私が使っているのはWindows10である。

```text:Google検索
Docker Windows10
```

公式のドキュメントを見つけることができた。
Windows10のEdition毎に導入方法が違うようだ。自分のWindowsのEditionが何なのか調べる必要がある。また、Docker Desktop for Windowsを動かすためのシステム要件もEdition毎に違うらしい。

```text:Windows　詳細情報
Windows検索バーで「設定」と検索　→　アプリ「設定」を開く　→　システム　→　詳細情報

>>> デバイスの仕様
デバイス名	HOGE-HOGE
プロセッサ	Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz   2.90 GHz
実装 RAM	16.0 GB (15.9 GB 使用可能)
デバイス ID	XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
プロダクト ID	XXXXX-XXXXX-XXXXX-XXXXX
システムの種類	64 ビット オペレーティング システム、x64 ベース プロセッサ
ペンとタッチ	このディスプレイでは、ペン入力とタッチ入力は利用できません

>>> Windowsの仕様
エディション	Windows 10 Home
バージョン	20H2
インストール日	‎2021/‎07/‎06
OS ビルド	19042.1052
エクスペリエンス	Windows Feature Experience Pack 120.2212.2020.0

```

私が使っているPCはWindows 10 Homeであることが分かった。

https://docs.docker.jp/docker-for-windows/install-windows-home.html

とりあえずインストールを行なって実行することはできそうだ。

###チュートリアルを実行せよ
Dockerにもチュートリアルが存在する。
インストールからチュートリアルまでの実行には以下の記事が役に立った（チュートリアル以降はDocker Composeなどの概念がわからないためやっていない）

https://qiita.com/zaki-lknr/items/db99909ba1eb27803456

チュートリアルの名前は「Quick Start Guide」とも呼ばれる。Windows10の右下ウィジェットにある「隠れているインジケーターを表示します」（ヘ）からクジラ🐋のアイコンを右クリックすることでいつでも開くことができる。
私はうっかりチュートリアルの途中でDockerを閉じてしまい、もう一度チュートリアルを始めるために苦労した。

チュートリアルのコマンドの意味があまりよくわからないため、コマンド内容をコピペしてそれぞれ調べた。

```powershell:Docker_Tutorial_1
PS > docker run --name repo alpine/git clone \
https://github.com/docker/getting-started.git
#---------#
# docker run --name repo hogehoge -> hogehogeという名前のコンテナを作成する
# clone -> gitからリポジトリをクローンする
# \ -> 記事を書く人が改行を知らせるための記号府。コマンド入力の際は不要
# git-url -> 略
#---------#
```

間違えて改行記号もコマンドに入力してしまうと、gitからcloneが行われず、やり直しをする必要が出てくるため手入力する人は要注意。

https://teratail.com/questions/89029

###docker runしたコンテナはWindowsのどこに作られる？
改めてTutorial_1 を実行した直後、lsコマンドを入力してもPowerShellが反応をしなかったことが気になった。これは、Windows上にコンテナが作成されていないことを意味する
作ったコンテナはどこに格納されているのだろうか。エクスプローラから格納されたディレクトリに移動したときはコンテナが存在しなかった。

この疑問に対するヒントは、次のチュートリアルに用意されていた。

```powershell:Docker_Tutorial_2
PS > docker cp repo:/git/getting-started/ .
#---------#
# docker cp repo:/path/ . -> コンテナのフォルダをローカル（カレントディレクトリ）にコピーする
#---------#
```

これを実行した後にWindowsエクスプローラ上で「getting-started」フォルダを見つけることができた。ここから、wsl2とwindowsではファイルを格納している場所が違う可能性が見えてくる。wsl上のファイルが参照できないことは酷く不便なため、Windwos上からwslのファイルを参照できるようにしたい。

```text:Google検索
windows wsl2 ファイル 場所
```

調べた結果、wslのファイルを参照することは非常に容易であった。
エクスプローラー上から開くことも可能である。パスの指定がドライブから始まらないため、C:\やD:\で検索できなかっただけであった。

https://snowsystem.net/other/windows/wsl2-ubuntu-explorer/

エクスプローラー上からは以下のようにパスを入力することでwsl上のファイルにアクセスすることができる。これらのうち、Dockerファイルは\\wsl$\docker-desktop\tmp\docker-desktop-root\mnt\host\c\Users\ユーザ名\自分で作ったディレクトリ名など…にある。

![スクリーンショット 2021-07-11 211411.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219263/11ced095-6764-122b-c7c0-0bbc2bc34327.png)

今後、コンテナにアクセスするためにはディレクトリの

 - フォルダのパーミッションを変更してエクスプローラー上からアクセスする（最初はwslを使用）
 - wslコマンドを入力し、Linuxと同様の操作でコンテナを参照する
 - ↑をやりつつ、exploreコマンドを有効化してwslからエクスプローラーを開く（参考記事見てね）
 - Docker Desktop for Windows からコンテナ一覧を見て、雰囲気を察する

の3パターンに分かれていくことだろう。場所がわかれば満足である。
疑問が解決したため、引き続きDockerのチュートリアルを進めていく。

```powershell:Docker_Tutorial_3
PS > cd getting-started
PS > docker build -t docker101tutorial .
#---------#
# cd dir -> 指定したディレクトリへ移動する。今回はリポジトリへ。
# docker build -t hoge . -> 現在いるディレクトリにhogeという名前でイメージを作成する
#---------#
```

このチュートリアルではalpine/gitイメージから生まれたrepoコンテナ……のおかげでcloneすることができたgetting-startedリポジトリを使ってdocker101tutorialという名前のDockerのイメージを作成する（理解し間違えてる可能性が高いのでご指摘お待ちしてます）。作られたイメージは「docker images」で確認することができる。
次のチュートリアルでは新しいコンテナを作成する。

```powershell:Docker_Tutorial_4
PS > docker run -d -p 80:80 --name docker-tutorial docker101tutorial
#---------#
# docker101tutorialイメージからdocker-tutorialという名前のコンテナを作成しバックグラウンド
# かつポート80番（コンテナ-Windows）で動かせるようにする。
#---------#
```

最初に作ったrepoコンテナはバックグラウンドでは動かないということになる。恐らくrepoコンテナを起動したら、他のコンテナは動かせないのだろう（たぶん認識違いなので要検証）。
次のコマンドでチュートリアルは最後となる。作ったコンテナをWebに共有するタスクである。

```powershell:Docker_Tutorial_5
PS > docker tag docker101tutorial ユーザ名/docker101tutorial
PS > docker push ユーザ名/docker101tutorial
```

これでDocker Hubに、作ったイメージを共有することができた。Git Hubのように。

https://hub.docker.com/r/eieio81810/docker101tutorial

コマンドの意味が分からんくなったときの参考

https://rubytomato.hateblo.jp/entry/2021/01/09/230402


##C言語の開発環境を整えよう
チュートリアルの時点で意味がよくわからなくて苦労した。ここから先はDockerの概念をフワッとでも理解していて、なおかつDockerチュートリアルみたいな、Dockerの基本操作をとりあえずやってみた人向けの内容となっている。
まだやってないのに目次から飛んできてしまった哀れな子羊（Windows10Homeユーザ）はとりあえず1からチュートリアルやっとくといいよ（私はやった）。

```text:Google検索
Docker チュートリアル Windows
```

やれ【1】

https://docs.docker.jp/docker-for-windows/install-windows-home.html

やれ【2】

https://docs.docker.jp/docker-for-windows/index.html

やれ【3】

https://docs.docker.jp/docker-for-windows/wsl.html

なお、Docker公式チュートリアルではコードエディタにVSCodeを推奨している。最終的には何でも良くなるのだろうけど、資料が豊富にそろっている可能性が高いので、ビギナーな現状では「郷に入っては郷に従う」こととする。

###作ったコンテナはどうやって起動するのか？
コンテナを作ったはいいけどCUI上から起動するためにはどうすればよいのか？
GUI上からであれば再生ボタンのようなアイコンを押せばよいので簡単である。

```text:Google検索
Docker コンテナ 実行
```

https://qiita.com/kooohei/items/0e788a2ce8c30f9dba53

作り終えて公開されているDocker Imageを取得して起動するところまでは深く考えずともとりあえずできそうである。docker start container_name で起動、docker stop container_nameで停止、docker ps -aでコンテナの一覧と状態を確認をすることができる。

さて、ということは、

 - 用意したい環境をDocker Hubで見つける
 - 見つからない場合は自分でいちからDocker Imageを作成する

という2つのパターンに分かれそうだ。
私が今回、Dockerで用意したいものは「C言語の開発環境」である。

日本人で、Dockerを使ってC言語の開発環境を整えた人はいるのか…

```text:Google検索
Docker C言語 環境構築
```

https://becre8ive.tech/dev/how-to-develop-clang-on-docker/

先人いた。

一安心だ。心の中に少しずつ疑問が積もってきたが（開発にあたってエディタどうしよ、コンテナで作った環境の中で作業する場合（コマンドを入力うんぬんとか）はどうすればいいんだろう）、まずは「C言語のプログラムが動く環境のDocker Imageを引っ張ってくる」ことができたらいいな～という目標で、先ほど検索したサイトに従っていく。

なんて言ったって、もうDocker Imageを引っ張ってきて起動できるようになったんだからな！

けどwsl上からVSCodeが開けない問題が発生した。

###wslからVSCodeを開けるようにするには？
Docker開発を続けるにあたって、基本的にはLinuxディストリビューション上からプロジェクトを参照して開発を行うこととなる。例えばこんなの↓

https://code.visualstudio.com/docs/remote/wsl-tutorial#_run-in-wsl

そのため、wslからプロジェクトフォルダまでcdして、code . （VSCode開く）コマンドを実行する必要があるのだが、私の場合はwslではcodeコマンドが有効にならなかった。コマンドプロンプト上では有効になっているため、何か原因があると思われる。

その原因を調査するために私が利用しているwslのディストリビューションを調べた結果、「docker-desktop」となっていた
![スクリーンショット 2021-07-22 223713.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219263/9e85ba0e-5839-7e69-c9d7-6fa3ba4be698.png)
これはDocker Desktopが動くようになるために必要なディストリビューションではあり、開発環境を入れるために必要なコマンドなどは一切入っていないし（apt-getやdockerコマンドも動かなくて涙目）、Windowsの環境変数からも独立してそう（調べたわけではないけどcodeコマンドに対応してくれなかった）。

DockerとVSCodeの環境変数を設定したのにwslに連携されていない、なんで！？という事象にぶつかったことがきっかけ。

```text:Google検索
docker-desktop distribution wsl2 code path
```

https://code.visualstudio.com/blogs/2020/03/02/docker-in-wsl2

このサイトで「Ubuntuをインストールして使おうね」と言われたのだ。

###Ubuntuとは？
開発に必要なコマンドがセットになって入っとる便利なLinuxディストリビューション。CLI。

これをインストールすることでDockerがUbuntuを認識してくれて、この中にコンテナを作成できるようになるのかもしれない（まだやっていないからわからない）

https://www.microsoft.com/store/productId/9NBLGGH4MSV6

インストールしてみた。そしてこれがWSLとして認識されているのか、コマンドプロンプトで確認してみた。

![スクリーンショット 2021-07-23 135136.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219263/a6d01048-b82c-1dc1-1233-7d2e7056865d.png)

されてた。だけど、WSLのバージョンが古いらしい。

```text:Google検索
wsl ubuntu バージョンアップ
```

ごちゃごちゃと余計な情報の書いてあるサイトが多いが（この記事もそうだ）、ページにアクセスして「CTRL＋F」キーでページ内検索をしたりしてほしい情報を探していく。ここでほしい情報は「wsl2」への「バージョン」アップだ。

https://loumo.jp/archives/25294

```powershell:wsl_to_wsl2
PS > wsl --set-version ubuntu 2
```

幾ばくかの時間、待てば良い。私は数分の待ち時間でUbuntuを動かしているwslのバージョンが2に上がった。
こうすることでDocker DesktopがUbuntuを認識してくれるようになる。

![スクリーンショット 2021-07-23 141827.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219263/b66ca57d-02c8-fe8e-e904-d7f62fa5e569.png)

ここまで長かった…。目標の再確認をすると、「Linuxディストリビューションの中からVSCodeを起動できるようになろう」「VSCodeからWSL内のファイルを編集できるようになろう」「これらを駆使してDockerからC言語関係のイメージを引っ張ってきて、C言語の開発環境を整えよう」だ。

画像のトグルボタンをonにしてUbuntuでdockerを有効にし、Ubuntu上でcodeコマンドの動作を確認することができれば、「すべての開発環境を受け入れる準備」が整う。バンザイイイイィィイ！！！

改めて、C言語の開発環境を整えていこう。
前述した「[VSCodeとDockerでC/C++開発環境を構築する手順](https://becre8ive.tech/dev/how-to-develop-clang-on-docker/)」に従うことができるようになっているはずだ。

順番に実行していけば良いが、いくつか注意点。

 1. 現状の開発環境ではWindowsのエクスプローラを使うことがないため、ファイルパスの場所
 2. bb
 3.