Docker Desktop for Windows の proxy 設定

# これは何？

Docker for Windows の proxy 設定について説明します

Docker の proxy 設定は二カ所必要です。一つは docker daemon の設定。もう一つは docker container の設定です。両方とも設定が必要です。

# docker daemon の設定

`docker pull` や `docker build` などを実行する daemon が参照する proxy の設定です。

公式の Get start with Docker for windows の [proxy](https://docs.docker.com/docker-for-windows/#proxies) に記載しています。
具体的に記入例は、"[Proxy環境下でDocker for Windowsを使う](https://qiita.com/wryun0suke/items/1f4bbd2977ae41ee7a36)" がわかりやすいので、そちらをご覧ください。

# docker container の設定

`docker run` で起動された、 docker container 上で走る OS が使う proxy の設定です。`Dockerfile` 中の `RUN` 文もこちらの設定を使います。
二通りのやり方があります。詳細は公式の [Configure Docker to use a proxy server](https://docs.docker.com/network/proxy/) に記載がありますが、 linux 向けの記述しかありません。

また、昔の記事ではよく Dockerfile に ENV で記述する方法を紹介していますが、非推奨の方法なのでやめましょう。やめた方が良い理由は後述します。

## `config.json` に追記し、 docker client の設定に proxy を加える

docker コマンドの実行環境が, `cmd` または `powershell` と `WSL2`で設定先が変わります。

### `cmd`　または `powershell`  向けの設定

`cmd` または `powershell` の場合、`config.json` は `%USERPROFILE%\.docker\config.json` を参照します。
デフォルトの状態だと下記のようになっていると思います。

```json:%USERPROFILE%\.docker\config.json
{
 "credsStore":"desktop",
 "stackOrchestrator":"swarm"
}
```

これに、下記のように proxy 設定を追記してください。

```json:%USERPROFILE%\.docker\config.json
{
 "credsStore":"desktop",
 "stackOrchestrator":"swarm",
 "proxies":
 {
   "default":
   {
     "httpProxy": "http://127.0.0.1:3001",
     "httpsProxy": "http://127.0.0.1:3001",
     "noProxy": "*.test.example.com,.example2.com"
   }
 }
}
```

### WSL2 の場合

Linux と同様に `${HOME}/.docker/config.json` を修正します。
デフォルトの状態だと下記のようになっていると思います。

```json:${HOME}/.docker/config.json
{
  "credsStore": "desktop.exe"
}
```

これに、下記のように proxy 設定を追記してください。

```json:${HOME}/.docker/config.json
{
 "credsStore": "desktop.exe",
 "proxies":
 {
   "default":
   {
     "httpProxy": "http://127.0.0.1:3001",
     "httpsProxy": "http://127.0.0.1:3001",
     "noProxy": "*.test.example.com,.example2.com"
   }
 }
}
```

## docker container 起動時に引数で与える

`docker run --env HTTP_PROXY="http://127.0.0.1:3001"` のように、`--env` で指定します。


# Dockerfile に ENV で記述するのはやめましょう

個人的に使用し、他の人と docker image を共有するのであれば、 ENV で指定するのは即座にやめましょう。

## 移植性がない

余所の環境で利用する場合、そのままの `Dockerfile` では動きません。ENV の行を書き換える必要があります。もしくは、ENV に与える値を ARG 経由にするとか、 `Dockerfile` 側に独自の引数を追加することになります。
そのままの image を起動する場合、[上記の設定](#docker container の設定) が必要になります。 ENV に埋めるだけ無駄です。

## 安全性が低い

`docker inspect` で docker image の情報を確認すると、 ENV の値が全て見えます。
例えば、下記の `Dockerfile` で作成したものを　inspect した例を示します。

```:Dockerfile
FROM gliderlabs/alpine
ENV http_proxy hogehoge.jp:8080
```

inspect で見える、該当箇所だけ抜粋します。

```json
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "http_proxy=hogehoge.jp:8080"
            ],
```

のような感じで、 ENV に指定した値が丸見えです。ユーザ認証を必要とする proxy だったりすると、ID や pass が漏れます。
[docker build --build-arg http_proxy=... で認証プロキシを設定すると危険だよ、という話](https://qiita.com/wadahiro/items/3b08e14e7ca2c6b31461) が詳しいです。

# 参考にしたところ

[Get started with Docker for Windows](https://docs.docker.com/docker-for-windows/)
[Proxy環境下でDocker for Windowsを使う](https://qiita.com/wryun0suke/items/1f4bbd2977ae41ee7a36)
[Configure Docker to use a proxy server](https://docs.docker.com/network/proxy/) 
[docker build --build-arg http_proxy=... で認証プロキシを設定すると危険だよ、という話](https://qiita.com/wadahiro/items/3b08e14e7ca2c6b31461)