docker-py v2.0.0 Can't create container data volumes using client.containers.run & create

Created on 7 Jan 2017  Â·  5Comments  Â·  Source: docker/docker-py

https://docker-py.readthedocs.io/en/latest/containers.html: run method: for volumes it says:

volumes (dict or list) –

A dictionary to configure volumes mounted inside the container. The key is either the host path or a volume name, and the value is a dictionary with the keys:

    bind The path to mount the volume inside the container
    mode Either rw to mount the volume read/write, or ro to mount it read-only.

For example:

{'/home/user1/': {'bind': '/mnt/vol2', 'mode': 'rw'},
 '/var/www': {'bind': '/mnt/vol1', 'mode': 'ro'}}

This effectively means that you can't create container data volumes, since you either have to create a volume 1st using docker create volume or use a host directory.
There is no option to just specify a container folder.

The low-level API (https://docker-py.readthedocs.io/en/latest/api.html#module-docker.api.container) create_container still allows you to do this (since I was able to do this using the v1 of docker-py

From the docker run documentation https://docs.docker.com/engine/reference/commandline/run/:

  -v, --volume value                Bind mount a volume (default []). The format
                                    is `[host-src:]container-dest[:<options>]`.
                                    The comma-delimited `options` are [rw|ro],
                                    [z|Z], [[r]shared|[r]slave|[r]private], and
                                    [nocopy]. The 'host-src' is an absolute path
                                    or a name value.

Am I correct here that logic to support container data volumes is missing from client.containers.run & create?
Or is there another way how to do this? Or are container data volumes being replaced by data volumes?

kinbug levedockerclient

Most helpful comment

I believe there is also a bug with named volumes not being supported by DockerClient.containers.run:

>>> print(docker.__version__)
2.0.1
>>> client.containers.run('alpine', 'ls', volumes={'my-named-volume': {'bind': '/data', 'mode': 'ro'}})
Traceback (most recent call last):
[...]
docker.errors.APIError: 500 Server Error: Internal Server Error for url: http+docker://localunixsocket/v1.24/containers/create
("Invalid volume spec "my-named-volume": Invalid volume destination path: 'my-named-volume' mount path must beabsolute.")

(The volume had already been created with docker volume create --name my-named-volume.)

All 5 comments

Thank you for the report. It looks like this is an issue we overlooked.

cc @bfirsh It seems like we're passing the volumes data to host_config no matter what, so even using the list syntax (volumes=['/hello/world:rw']) will result in an error from the engine because we're passing an invalid bind mount spec.

I believe there is also a bug with named volumes not being supported by DockerClient.containers.run:

>>> print(docker.__version__)
2.0.1
>>> client.containers.run('alpine', 'ls', volumes={'my-named-volume': {'bind': '/data', 'mode': 'ro'}})
Traceback (most recent call last):
[...]
docker.errors.APIError: 500 Server Error: Internal Server Error for url: http+docker://localunixsocket/v1.24/containers/create
("Invalid volume spec "my-named-volume": Invalid volume destination path: 'my-named-volume' mount path must beabsolute.")

(The volume had already been created with docker volume create --name my-named-volume.)

I had the same problem that @RobbieClarken mentioned above. And I solved it by doing a tiny modification on the line 882 in docker/models/containers.py.(on branch 2.0.2-release)
The original line of codes is
create_kwargs['volumes'] = [v.split(':')[0] for v in binds]
And I change it as below:
create_kwargs['volumes'] = [v.split(':')[1] for v in binds]

Which I believe might be a bug to fix because the definition of volume parameter for docker engine api is

An object mapping mount point paths inside the container to empty objects.

Hence, the volume parameter should be mapping to v.split(':')[1] instead v.split(':')[0] because former one means mount point paths inside the container and later one means host path or volume name.

@milk4candy It works on docker-py version 2.0.2! Thanks a lot.

Gosh, what a mess. Fixes for both things here: https://github.com/docker/docker-py/pull/1439

Sorry all!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ko-christ picture ko-christ  Â·  3Comments

treuherz picture treuherz  Â·  4Comments

vickydgm picture vickydgm  Â·  4Comments

MahdiZareie picture MahdiZareie  Â·  3Comments

AdamWRichardson picture AdamWRichardson  Â·  4Comments