docker-pyを使ってpythonでコンテナを操作する方法

![vertical (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258841/56384a72-9f33-6595-d2ac-5537b830eec2.png)

A Python library for the Docker Engine API.

## 背景

[docker](https://github.com/docker)のページを見てると[docker-py](https://github.com/docker/docker-py)っていうリポジトリを見つけた。
せっかくだから触ってみたので使い方とかまとめてみました。

## docker-pyとは

Docker Engine API用のPythonライブラリです。
dockerコマンドを使ってやるような操作をpythonで書いたアプリケーションから実行できます。
オープンソースでありGitHubで公開されています。(Apache License 2.0)
『[docker/docker-py](https://github.com/docker/docker-py)』
言語はpythonで書かれている。スター数は4000程度

## 環境

* OS : macOS Mojave 10.14.2
* Python : 3.7.3

## インストール手順

pipを使って簡単にインストールできる

``` bash
$ pip install docker
```

## とりあえず実行

とりあえず実行します。
下記のソースではdockerデーモンと通信をするだけで何も表示されません。
ここでエラーが起きてる場合はインストールが失敗しているかimportのパス解決がうまくいってない場合があります。
過去にインストールしてあったりする場合は一度消してから再度インストールしてみるなどで解決する場合が多いようです。

``` python
import docker

# デフォルトソケットを用いて通信
client = docker.from_env()
```

ここでfrom_envへDockerサーバへのURLを記載することもできます。

``` python
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
```

またこの段階でdockerに関する情報を取得するための機能も実装されています。
どれも辞書型で値を返されます。

``` python
# データ使用情報を表示
client.df()

# システムの情報を表示します。 => docker info
client.info())

# dockerのバージョンを表示 => docker version
client.version()

# サーバが応答してるかどうか確認
client.ping()
```

上記を使えばこんな感じでdockerが起動してるかやアプリ側からもdockerのバージョン情報なんかが落とすとかが簡単にできたりします。(dockerが昔入れてそのまんまで動かない！みたいなのが減りそうです。そもそもコマンド叩いて見ろって話ですが。。。)

``` python
import sys
import docker

client = docker.from_env()

# 応答確認
if client.ping() == False :
    print ("Ping Error", file=sys.stderr)

cv = client.version()
print(cv["Components"][0]["Version"])
```

## コンテナを走らせる

上まではdockerの実行環境を見たりしてるだけでしたがここからはコンテナを実際に動かしてみます。
docker runのような形同様にとっても簡単に動かせます。
実行時オプションはrun()の第3引数へ渡すことで処理することができます。
cpu_countでのCPU割り当てやentrypointでコンテナのエントリポイント、networkでネットワークなどを指定することができます。

``` python
import sys
import docker

client = docker.from_env()

# run(image, command=None, **kwargs)
print (client.containers.run("alpine", "cat /etc/alpine-release"))
```

当然ですが起動せずにコンテナを作成したりコンテナ情報を取得したりすることもでできます。

``` python
# コンテナを作成
client.containers.create()

# コンテナリストを取得
client.containers.list()

# コンテナオブジェクトを取得
client.containers.get(id or name)

# 停止したコンテナを削除
client.containers.prune()

# pullもできる
image = client.images.pull("alpine")
```

若干余談ですが、ここら辺は全て共通してサーバでのエラーは「docker.errors.APIError」を返す仕様となっているようです。

## ネットワーク

ネットワークもpythonから操作できます。
docker networkに対応した操作がそれぞれあるようです。
[Docker コンテナ・ネットワークの理解](http://docs.docker.jp/engine/userguide/networking/dockernetworks.html)

``` python
client.networks.create("network1", driver="bridge")

# サブネット、ゲートウェイを使うことも
ipam_pool = docker.types.IPAMPool(
    subnet='192.168.52.0/24',
    gateway='192.168.52.254'
)

ipam_config = docker.types.IPAMConfig(
    pool_configs=[ipam_pool]
)

client.networks.create(
    "network1",
    driver="bridge",
    ipam=ipam_config
)
```

## ボリューム

ボリューム作成/削除も可能

``` python
volume = client.volumes.create(name='foobar', driver='local',
        driver_opts={'foo': 'bar', 'baz': 'false'},
        labels={"key": "value"})

# 未使用ボリュームの削除
volume.prune(filters)
```

## まとめ

触ってて思ったのは「python」 & [docker]を効率よく同時に学べるいい題材！だなって感じでした。
ここで紹介した機能以外にもたくさんの機能がありました。dockerコマンドでできることは恐らくできるんだと思います。
公式のドキュメントを読みつつ進めていくと色々活用できそうだなって感じでした。
(docker-py使うためのコンテナとか面白そう)

## 参考リンク

* [docker/docker-py](https://github.com/docker/docker-py)
* [Docker SDK for Python](https://docker-py.readthedocs.io/en/latest/index.html)
* [Python の学習がてら、SDKs for Docker Engine API を触ってみた](https://dev.classmethod.jp/tool/docker/learning-on-docker-sdk-for-python/)