Containers#
Here is more carefull consideration of the options associated with working with containers.
import os
import docker
client = docker.from_env()
Run#
Here we look more closely at concepts related to running containers. See the relevant section in the official documentation.
Volumes#
There is a special parameter in docker.client.DockerClient
- volumes
. This allows you to specify volumes for your Docker container.
The definition of the volume has a specific syntax - it should be a dictionary, each element of which corresponds to the container. Each key is a path on the host, each value is another dictionary with keys bind
and mode
. Where bind
is the path in the container and mode
is the mode of the volume.
In general, it should look like this:
{
"<path on the host 1>": {"bind": "<path on the container 1>", "mode": "<mode>"},
"<path on the host 2>": {"bind": "<path on the container 2>", "mode": "<mode>"},
...
}
Consider example where we try to mount file to the container runned with sdk. So in the next file we creating file that contains specific message:
%%writefile containers_files/some_message
This is message from future container
Overwriting containers_files/some_message
This cell is running container and then executing cat some_message
so content of the mounted file should be printed.
container = client.containers.run(
image="ubuntu",
name="temp_container",
volumes={
f"{os.getcwd()}/containers_files/some_message":
{'bind': '/some_message', 'mode': 'rw'}
},
detach=True,
stdin_open=True,
remove=True
)
print(container.exec_run("cat some_message").output.decode("utf-8"))
container.stop()
This is message from future container
Ports#
You can set ports for docker conatiner using the ports
argument. It must take dict value with format {<port in the conatainer>: <port in the host>}
.
Note: it can be confusing that in the docker run
, -p
parameter we usually set the port on the host first, but in the port
argument of the docker SDK, the dictionary takes ports on the host as a keys.
The following cell starts the docker container with the ports
argument.
container = client.containers.run(
image="alpine",
ports={6060: 7070},
command="sh",
detach=True,
stdin_open=True,
remove=True
)
The following code shows that the container was indeed created and that it has the appropriate ports configuration.
!docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
81bd3dacf36b alpine "sh" 3 seconds ago Up 3 seconds 0.0.0.0:7070->6060/tcp, [::]:7070->6060/tcp tender_allen
container.stop()
Logs#
You can get container logs as bytes
by using logs()
method.
The following example runs a Docker container that uses Python to spam some information to standard output.
command = """
python3 -c
"for i in range(10):
print(''.join([chr(i+j+100) for j in range(10)]))"
"""
container = client.containers.run(
"python:3.10.14-alpine3.20",
command = command,
detach = True
)
Now for an example of loading and printing logs from the container.
print(container.logs().decode("utf-8"))
container.remove()
defghijklm
efghijklmn
fghijklmno
ghijklmnop
hijklmnopq
ijklmnopqr
jklmnopqrs
klmnopqrst
lmnopqrstu
mnopqrstuv