Dockerを再起動してもdriver failed programming external connectivity on endpointでコンテナを起動できない時の対処法

## 環境
* Windows 10
* Docker for Windows Version 2.1.0.0(36874)
* Docker version 19.03.1, build 74b1e89
* docker-compose version 1.24.1, build 4667896b

## Port利用中のエラーが発生
開発環境でPCを再起動するたびに、`docker-compose up -d`でコンテナを起動させようとすると発生する`Cannot start service xxx: driver failed programming external connectivity on endpoint ~ bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.`という下記のエラー。

```
Creating mysql ...
Creating redis ... error

ERROR: for redis  Cannot start service redis: driver failed programming external connectivity on endpoint redis (413f200ac5699af718e524d6cccc951244ae88bf828a0b9d285a99471e7c7bd5): Error starting userland proxy: listen tcp 0.0.0.0:6379: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.

ERROR: for mysql  Cannot start service mysql: driver failed programming external connectivity on endpoint mysql (703db6db03311aa08d34dceee81dd6d8507cc1ef41b1c2022a17d6fd504f8e1b): Error starting userland proxy: listen tcp 0.0.0.0:3310: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
ERROR: Encountered errors while bringing up the project.
```

通常は、というか今まではDocker for Windowsを再起動すれば解消されてました。
面倒だなと思いながらもほぼ毎回Dockerを再起動していました。

Macでも同様のエラーが発生する模様。
[docker-compose up したらdriver failed programming external connectivity on endpointが出てきた](https://qiita.com/MitsuguSueyoshi/items/50f8465680aa462a4191)

再起動は上記の記事と同様で
1. タスクバーのDockerアイコン（クジラのアイコン）を右クリック
2. 「Quit Docker Desktop」をクリック[^1]
3. クジラのアイコンが消えたらDockerアプリケーションを起動
4. Dockerが起動したら`docker-compose up -d`でコンテナを起動

[^1]: 「Restart」でもいいのかもしれませんが、Restartだと解消しないことが結構あるので一度終了してから起動してます。

Docker for Windowsをアップデートした影響なのかわからないのですが、Docker for Windowsを再起動しても解消されない事象が発生。

### 2019年9月 追記
違うパターンのエラー文（Error starting userland proxy: /forwards/expose/port returned unexpected status: 500）が出たのですが同様の対応方法で解消できたので、追記しておきます。

```
Creating mysql ... error

ERROR: for mysql  Cannot start service mysql: driver failed programming external connectivity on endpoint mysql (c9fa28746828b6645953a0a88e042e4bdf7cbe8ccd0e6c5db10e45c3fad51021): Error starting userland proxy: /forwards/expose/port returned unexpected status: 500
ERROR: Encountered errors while bringing up the project.
```


## 結論：エラーを解消した方法

下記で経緯を説明しますが、今回ポートをつかんで離さなかったのはDockerの`com.docker.backend.exe`というプロセスでした。
このプロセスを再起動させることで問題なく起動することができました。

一応、プロセスを終了するので自己責任でお願いします。
他に良い方法をご存知の方はコメントいただけると嬉しいです。

### 1. Docker for Windowsを終了させる
1. 画面右下のタスクバーのDockerアイコン（クジラのアイコン）を右クリック。
2. 「Quit Docker Desktop」をクリックしてDocker for Windowsを終了します。
3. アプリケーションが終了するのを待ちます。

### 2. com.docker.backend.exeを終了
1. `Ctrl + alt + del`でタスクマネージャーを起動して「詳細」タブを開きます。
2. `com.docker.backend.exe`というプロセスを右クリックして終了します。
3. 自動的に同じプロセスが立ち上がります。

![process.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422631/d2a7bd1a-d279-b588-2eaf-1d51f9b9c50c.png)


### 3. Docker for Windowsを再起動

Docker for Windowsを再起動して、起動したら`docker-compose up -d`でコンテナを起動します。
これだけで無事に起動できました。

```
$ docker-compose up -d
Creating network "default" with the default driver
Creating mysql ... done
Creating redis ... done
Creating nginx ... done
Creating rails ... done
```

## 経緯：原因を調査してみた

まずはポートが何に使われているか確認しました。

```
$ netstat -an | find "3310"
TCP        0.0.0.0:3310        0.0.0.0:0     LISTENING    11240
TCP        [::]:3310           [::]:0        LISTENING    11240
```

`Ctrl + alt + del`でタスクマネージャーを起動して「詳細」タブを確認。
PIDが同じプロセスを探すと先ほど解説した`com.docker.backend.exe`が利用している状態でした。
![process.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422631/d2a7bd1a-d279-b588-2eaf-1d51f9b9c50c.png)

Dockerを終了してもこのプロセスは起動したまま。

問題のプログラムに関して検索しても情報がなく、詳細不明だったので、とりあえずコンテナを全て終了させて、コンテナ、ネットワーク、イメージを削除してみました。
それでも解消せず。

苦肉の策でWindowsを再起動したら普通に起動するという…
もしかしたらbackendプロセス内でエラーが発生していたのかもしれませんね。

Dockerを再起動してみても`driver failed programming external connectivity on endpoint`エラーが解消しない場合は[上記で解説した方法](#結論：エラーを解消した方法)を試してみてください。