Check! docker-compose で urllib3 が原因でエラーになる場合の対処

こんばんは、 @dz_ こと大平かづみです。

Prologue - はじめに
====
vagrant の `ubuntu/trusty64` をアップデートしたら、vagrant 内で使っている docker-compose が動かなくなってしまったので対応しました。その備忘録です。

エラー内容
----
`docker-compose` を利用しようとすると、以下のように python のエラーが発生しました。

### エラーの抜粋

```bash
vagrant@vagrant-ubuntu-trusty-64:~$ docker-compose --help

  ... <略> ...

  File "/usr/local/lib/python2.7/dist-packages/docker/transport/ssladapter.py", line 22, in <module>
    urllib3.connection.match_hostname = match_hostname
AttributeError: 'module' object has no attribute 'connection'
```

### 発生環境
- vagrant box: `'ubuntu/trusty64' (v20170131.0.0)` (Ubuntu 14.04.5 LTS)

```bash
# python の docker 関連のバージョンを確認する
vagrant@vagrant-ubuntu-trusty-64:~$ pip freeze | grep docker
docker==2.0.2
docker-compose==1.10.1
docker-pycreds==0.2.1
dockerpty==0.4.1

# Docker のバージョンを確認する
vagrant@vagrant-ubuntu-trusty-64:~$ docker version
Client:
 Version:      1.13.0
 API version:  1.25
 Go version:   go1.7.3
 Git commit:   49bf474
 Built:        Tue Jan 17 09:50:17 2017
 OS/Arch:      linux/amd64

Server:
 Version:      1.13.0
 API version:  1.25 (minimum version 1.12)
 Go version:   go1.7.3
 Git commit:   49bf474
 Built:        Tue Jan 17 09:50:17 2017
 OS/Arch:      linux/amd64
 Experimental: false
```


調査
----
こちらの記事を参照すると、どうやら python の `urllib3` のバージョンが合わないようです。 `urllib3` の最新バージョンは `1.20` なのに、なぜか `1.7.1` が入っていました。

- ['module' object has on attribute 'connection' · Issue #1054 · docker/docker-py](https://github.com/docker/docker-py/issues/1054 "'module' object has on attribute 'connection' · Issue #1054 · docker/docker-py") 

更に調べると、こちらの issue でも指摘されているように、 `apt-get` でインストールされる `python-urllib3` が　`1.7.1` なのでした。

- [kliko-run error: urllib3 connection error due to version python-urllib3 (v.1.7.1) vs. pip urllib3 (v1.16) · Issue #12 · gijzelaerr/kliko](https://github.com/gijzelaerr/kliko/issues/12)

```bash
# python の urllib3 のバージョンを確認する
vagrant@vagrant-ubuntu-trusty-64:~$ pip freeze | grep urllib3
urllib3==1.7.1

# apt-get でインストールされた python-urllib3 のバージョンを確認する
vagrant@vagrant-ubuntu-trusty-64:~$ dpkg --list | grep urllib3
ii  python-urllib3                       1.7.1-1ubuntu4                      all          HTTP library with thread-safe connection pooling for Python
ii  python-urllib3-whl                   1.7.1-1ubuntu4                      all          HTTP library with thread-safe connection pooling
```

だがしかし…

単純に `pip install urllib3=1.20` でインストールしても、 docker は `1.7.1` の方を見てしまい、うまく行きませんでした。 そこで、 `apt-get remove python-urllib3 python-urllib3-whl` で取り除くとたしかに docker は動くのですが、今度は `pip` も一緒にアンイストールされてしまい…、これではだめですね(´・ω・`)

結論
----

私はこのとき、vagrant 内で docker-compose を使いたいのでした。これを達成するには、方法は２つありそうです。

ひとつは、 `apt-get` の `python-urllib3*` は削除し、 `pip` を `apt-get` を使わず `get-pip.py` でインストールする方法でしょう。

- [Installing with get-pip.py](https://pip.pypa.io/en/stable/installing/#installing-with-get-pip-py)

そして、もうひとつは、Ubuntu のバージョンを上げてしまうことでした。

なぜかというと、 `ubuntu/trusty (14.04)` でインストールされる `python-urllib3` は `1.7.1-1build1` だそうだが、 `ubuntu/xenial (16.04)` でインストールされる `python-urllib3` は `1.13.1-2` なんだそうです。

- [How to install python-urllib3 on Ubuntu 14.04 (Trusty Tahr)](https://www.howtoinstall.co/en/ubuntu/trusty/python-urllib3)
- [How to install python-urllib3 on Ubuntu 16.04 (Xenial Xerus)](https://www.howtoinstall.co/en/ubuntu/xenial/python-urllib3)

ということで、 Ubuntu を `16.04` に更新することで事なきを得ました！！

（Ubuntu 16.04 でも `urllib3` が最新バージョンではないですが、docker-compose の利用には問題ありませんでした。）

Epilogue - おわりに
====
発生環境が限られるエラーかもしれませんが、どなたかの参考になれば幸いです m(_ _)m