LoginSignup
555
660

More than 3 years have passed since last update.

Docker for Windowsで快適な環境を得るまでの そこそこ長い闘い

Last updated at Posted at 2017-11-09

2019年8月更新

2年の間にWindowsでのDocker開発環境が進化したのと
知人より凄い便利な機能を教えてもらったので共有します

おさらい

今までの大雑把なおさらいとして
Windowsでのサーバ開発はDockerを使えば問題なく出来る
(実際私は2016年からWindowsでサーバ開発を行っている)
VirtualBoxなどを使い、boot2dockerを使いVM上のLinuxで開発も出来るが
Windows10 Pro64bitで Hyper-VをONにして Docker for Windowsで開発するとカッコイイ
ただし、WindowsにはBashがないのでシェルスクリプトが実行できない
WSLを使いDockerをインストールし、Docker for WindowsのExportを使えば良い
ただし、WSLのマウントポイントが /mnt/c/ になっているため、環境変数やsedを使いパスを変更する必要があり不便だった

WSLのマウントポイントの変更

知り合いに教えてもらった。簡単にWSLのマウントポイントを変更できる!

/etc/wsl.conf ファイルでマウントポイントを設定できる
具体的には /を指定すると /cにマウントされる

/etc/wsl.conf
[automount]
root = /
options = "metadata"

これでマウントポイントが /cになり、今までの問題が全部解決してしまった!

Windowsで幸せなServer開発を行ってくださいね!

更に便利に

ほんと、ここ数年のWindowsのDocker対応は進化が速く追いつくのが大変だ

LCOW

今までのDockerはMoby Linux上で実行されていた
VM上にLinuxを立ち上げその上でDockerを実行していたが
LCOWではHyper-V分離を使い、よりオーバーヘッドが少ないコンテナ実行が出来るらしい
Docker for WindowsでExperimentalではあるがLCOWの使う事が出来る

Windowsコンテナ

WindowsネイティブのDockerHostで、Windowsコンテナをネイティブ実行できる
今のところはCLIしか使えないので使ったことはないが
Windowsサーバの管理などで使う人は便利だと思われる

WSL2

今までのWSLはLXCore という技術を使い、Linuxをエミュレートしている
完全なLinuxではないため、動かせない物がたくさんある
例えばDockerHostなど
WSL2は完全なLinux VMを使っているので、Linux機能を全部使う事が出来るらしい
例えばDockerHostも動かすことができる

そして、WSL2に最適化された WSL2 Dockerというものが作られた
https://engineering.docker.com/2019/06/docker-hearts-wsl-2/
7月末にプレリリースとの話だが

WSL2が、プレビュー版のWindowsをインストールする必要があり
私の環境では、OSインストールでブルースクリーン落ちするため
WSL2を試せていない・・

2年前までの情報

はじめに

Macで開発する人も多いと思います。たしかにMacはBSDベースで開発便利ですが
Windowsこそ最高の開発環境である という前提で、Windowsで最高の開発環境を構築しようと思います

結果だけ見たい人は下の方をw

Windowsのメリットは、ハードウェアの選択肢が多い事
特にゲームや人工知能開発には ハイスペックGPU選べるのが良いですね
DirectXも動きます

ではWindows開発の問題は何か?

一番は シェルです
WindowsにはBash等 Linuxと互換性のあるシェルがなく、コマンドプロンプトやパワーシェルという独特なシェルです
一般的には bash等のシェルスクリプトが使われるため、これは不利です

もう一つは、Windowsに PHPやらPythonやらApache・・・をインストールしたくない事。
そして、OSの機能。たとえばファイアウォール等の設定がLinuxと違う事やディレクトリ名
このあたりは、DockerやVMなどで開発すれば問題ないですね

ので、Dockerを使う前提で考えます
WindowsでDockerを使うためには 2つの方法があります
1つは DockerToolsを使う方法で、VirtualBox上のLinuxからDockerを使う方法で、Macでもこの方法ですし
Linux上なので シェル問題も解決するので、何も問題ありません
これで満足する人は DockerToolsを使ってください。
共有ディレクトリやポートフォワードも VirtualBoxの設定で可能なので 何も問題なく使えます

Windows10 Pro 64bitの人は Docker for Windowsを使う事が出来ます
ホスト型のVirtualBoxで動かすよりも、ハイパーバイザーで動くHyper-Vのほうが
オーバーヘッドが少なくより快適になるのではないかと期待しています
ただし、色々と不便があり やっと快適に使う方法を手にしたので
少し環境構築が大変です
でも、最高の開発環境のために 頑張ります!

シェル問題

VirtualBoxを使う

LinuxをVMに入れるので何も問題ない
ただ、今回はより最高の環境のため Docer for Windowsを使うため、使用しない

Windows専用のバッチファイルを作る

コマンドプロンプトやPowerShellを使えば Bashと同等の事はおそらく可能であるが管理コストが増えるし
普段使うシェルもBashのほうが慣れているので、出来れば避けたいところ

Cygwinを使う

古典的な手法だが、Cygwinはいいぞ
ただし Dockerコンテナに入ろうとすると
cannot enable tty mode on non tty input
と怒られてしまうので Cygwinは使えない

Gitのbashやmingwを使う

mingwを使えば問題ないらしいぞ!
ただし、あくまでWindows上なため、シェルの設定等あまり出来ないだろうし
パッケージもインストールできない

Windows Subsystem for Linux(Bash on Ubuntu on Windows)

Windows内のLinuxを使う!!
これが最も最強っぽい響きがあるので あえてこれで挑戦します
(多分 mingw使うのが一番楽なんだけど・・)
シェルではなく Ubuntuなので aptで色々とインストールも出来たりします
カオス!
ただし 色々な問題があります

不具合

日本語対応が怪しかったりするので日本語パスとかやめましょう
コンソールに高確率でゴミが残ります
vimなどよく固まる。大きいファイル扱うと固まります
その他いろいろと 不具合あります

β機能なので 温かい心が必要です!

WSLも仮想IP上で動いているのでDocker for Windowsと直接通信出来ない

WSLは“アプリケーションのためのサンドボックス環境”で動いているようです
大問題です(が解決できます)
Docker for Windowsは ホストOS(Windows10)のHyper-V上で動いていますが
Bash on Winowsも ホストOSのHyper-Vで動いているためか
bashでdockerコマンドうっても Bash on Windows上のdockerに接続にいきます
(そして Bash on WindowsのDockerは 対応してないのか落ちる)

という事で、 Bash on Winowsから ホストのDockerを叩けるように してみます!

インストール

Docker for Windowsのインストールと Bash on Windowsをインストール
この辺の手順は 色々なサイトであるので 書かない
また Docker for Windowsには docker-composeも入っているので素晴らしい!
Hyper-Vの有効化や BIOSの有効化も忘れずに

ドライブシェアの設定

SnapCrab_NoName_2017-11-10_2-23-34_No-00.png

私のPCはCドライブしかないけど、複数ドライブある時は、シェアするドライブを指定します
また、チェックしたときに Firewallがなんたら・・ と怒られる事がるので その場合は
Firewallで445ポートをオープンすればよい
ただし それだけではダメで 一度Windowsの ファイル共有サービスを削除してインストールすれば直るとのこと
https://qiita.com/shwld/items/7aad11ca53e2e5daad46

bashでdockerをうっても コマンドがない!
それは Bash on Windowsに dockerクライアントがインストールされてないからです

Bash on WindowsでDockerのインストール

Docker本家より

sudo apt-get install \
    apt-transport-https  ca-certificates curl \
    software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

sudo apt-get update
sudo apt-get install docker-ce

こんな感じでインストールできます
ただし このままでは 起動しない Bash on WindowsのDockerをみにいくので
環境変数を設定し、ホストOSのDockerを見るようにします

ホストのDockerを見に行く設定

export DOCKER_HOST='tcp://0.0.0.0:2375'

これを .bashrc に追加しておけば大丈夫です

そして、ホストのDockerにて 2357ポートを許可する必要があります
(私はこの設定をしらず 3か月 コマンドプロンプトで Dockerを使う不便を味わった)

SnapCrab_NoName_2017-11-10_2-24-38_No-00.png

この Expose daemon on tcp://localhost:2375 without TLS
これをチェックする必要があります
もしかすると、TLSを使い dockerコマンド送る方法もあるのかもしれないけど、今回はそこは調べません

これで
$ docker hogehoge
で ホストOSのDockerを動かすことができます

docker-composeのバージョンアップ

$ docker-compose up

とすると、docker-composeのバージョンが古く、書式が通りませんでした・・・
docker-compose -v とすると version 1.3 でした
古い・・・

という事でバージョンアップします。
まずはホストOSですが、Dockerの公式より

のWindowsタブを見ます
ホストOSの PowerShellを管理者モードで起動し

Invoke-WebRequest "https://github.com/docker/compose/releases/download/1.17.0/docker-compose-Windows-x86_64.exe" -UseBasicParsing -OutFile $Env:ProgramFiles\docker\docker-compose.exe

のようにします。 今回は 1.17.0を取得

インストールが完了しても、Bash on WindowsのDocker-composeはバージョンが古いので、まだ怒られます

Bash on Windows上のdocker-compose バージョンアップ

上記URLの Linuxのところをみると

sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

と書いてますが 今回は pipで行おうと思います

https://bootstrap.pypa.io/get-pip.py
上記URLからダウンロードし get-pip.py という名前で保存し

$ sudo python get-pip.py
$ sudo pip install docker-compose

結論

bash on windowsから docker-compose up もちゃんと動いたし
bashも問題なく使える
ちょっと不具合はあるけど 今後解消されるのを待ちましょう

最強の開発環境完成です!!

パス問題

Bash on WindowsでDockerを使えて便利になったけど相対パスを指定すると不具合が出る
例えば docker-compose.ymlで volumesを相対パスで設定

    volumes:
      - .:/myapp

うまくマウントされない
原因は DockerのMobyLinuxVMと WSLのUbuntuのマウントパスの違いです
DockerはCドライブを /c にマウントしますが
WSLでは /mnt/c をマウントします

解決案1 環境変数

環境変数 $PWDを上書きして使う(むろん他の名前でもよい)
WSLのBash上では /mnt/c/... となっているので

$ PWD=echo $(pwd) | sed -e 's/^\/mnt//'

と、/mntを削除し 設定ファイルも環境変数を使うようにする

    volumes:
      - $PWD:/myapp
555
660
6

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
555
660