Python
Docker
docker_remote_api

docker-pyを使ってみる

More than 3 years have passed since last update.

!バージョンによって挙動が全然違うので注意してください!

通常 docker は daemon として待ち受けていて、unix domain socket を listen している。実はこの socket に流れるプロトコルは REST/HTTP で、-H option で tcp に bind させることもできて、webサーバになる。仕様は "Docker Remote API" に書いてある。そして各種 language client も存在する。

そんな python client である docker-py のお話。

まずは通常の使い方。

import docker

dc = docker.Client()
# docker ps
dc.containers()
# docker images
dc.images()
# docker run -ti ubuntu bash
c = dc.create_container("ubuntu", stdin_open=True, tty=True)
dc.start(c["Id"])
print "docker attach %s" % c["Id"]

ところが。

「あ…ありのまま 今 起こった事を話すぜ」とばかりに、激しい落とし穴があったりするので注意。

/container/create の ExposedPorts の組立の部分。listなのかtupleなのか。listが正しいかと思いきや、tupleを要求されるところもある。しかも正しい組み合わせでなければ正しい値にならない。その上、普通に使ってるとエラーも出ないという罠。

import traceback

import docker

dc = docker.Client()

tests = (
[22,], # OK
(22,), # NG
["22/tcp",], # NG
[(22, "tcp"),], # OK
[[22, "tcp"],] # NG
)

for ports in tests:
c = dc.create_container("ubuntu", stdin_open=True, tty=True, command="bash", ports=ports)
dc.start(c["Id"])
info = dc.inspect_container(c["Id"])
print ports, info["Config"]["ExposedPorts"]
try:
assert {'22/tcp': {}} == info["Config"]["ExposedPorts"]
except:
traceback.print_exc()
finally:
dc.stop(c["Id"])

次は /containers/(id)/start の PortBindings。うん…なんだろう。この一貫性の無さは。

import traceback

import docker

dc = docker.Client()

tests = (
# automatic allocation
{22:None}, # OK
{"22/tcp": None}, # OK
# manual allocation
{22:10080}, # OK
{"22/tcp": 10080}, # OK
{22: ":10080"}, # NG
{22: dict(HostPort=10080, HostIp="0.0.0.0")}, # NG
{22: ["0.0.0.0", 10080]}, # NG
{22: ("0.0.0.0", 10080)} # OK
)

for port_bindings in tests:
c = dc.create_container("ubuntu", stdin_open=True, tty=True, command="bash", ports=[22,])
dc.start(c["Id"], port_bindings=port_bindings)
info = dc.inspect_container(c["Id"])
print port_bindings, info["HostConfig"]["PortBindings"]
try:
assert '22/tcp' in info["HostConfig"]["PortBindings"]
except:
traceback.print_exc()
finally:
dc.stop(c["Id"])