Docker virtualenv support
Python and Docker relationship
Docker can be expanded or managed by a few additional Python-based tools. The company behind Docker provides a docker-compose Python script which can be used to manage multiple Docker containers at a time. Ansible provides a few Docker-related modules as well. Therefore a correctly configured Python environment is very useful on a Docker host.
The debops.docker_server
Ansible role maintains a separate Python
virtualenv environment just for Docker-related Python packages. This
is done so that Python modules used by upstream Docker, don't affect the host
Python environment. The Docker virtualenv environment is by default
located in the /usr/local/lib/docker/virtualenv/
directory but it can
be changed if needed.
The docker-compose script will be symlinked in the host environment,
in /usr/local/bin/docker-compose
, so that the command can be used from
the host's shell.
The Python interpreter located in the Docker virtualenv environment
will be exposed in the host environment as
/usr/local/bin/docker-python
. That way you can use it in the Python
scripts executed in the host environment. To use the Docker Python interpreter
in a script, define it's shebang line as:
#!/usr/bin/env docker-python
Ansible modules and Docker virtualenv
The default host does not have any Docker-related Python modules available,
therefore Ansible modules that interact with Docker, like docker
,
docker_container
, docker_image
, etc. will not work out of the box in
normal Ansible playbooks and roles. To solve that, you can use the
ansible_python_interpreter
variable defined at the playbook level. Playbook
variables cannot be templated by Jinja, therefore a static value must be used,
and relates to the docker-python command exposed earlier.
Here's an example playbook that uses a Python interpreter from the Docker virtualenv environment:
---
- name: Set up a Redis Docker container
collections: [ 'debops.debops' ]
hosts: 'docker-host'
become: True
environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'
vars:
# Use Python from Docker virtualenv
ansible_python_interpreter: '/usr/bin/env docker-python'
tasks:
- name: Manage redis container
docker_container:
name: 'local-redis'
image: 'redis'
published_ports: [ '127.0.0.1:6379:6379' ]
restart_policy: 'always'
state: 'started'
Keep in mind that more extensive playbooks that use Ansible roles or modules other than the Docker-related ones might need to be executed in their own separate plays, to use the host Python interpreter instead of the one maintained in the Docker virtualenv environment. Alternatively, you need to ensure that the Docker virtualenv environment contains all needed Python modules.
How to access the Docker virtualenv
To enter the Docker virtualenv environment on a host, execute the
commands on the root
account:
cd /usr/local/lib/docker/virtualenv
source bin/activate
After that you can execute usual pip commands to manage Python packages inside the environment.