CATPOD Docs
  • What is CATPOD?
  • How to Use
  • Use Cases
  • Resources Used

How to Use

Getting Started

Using a CATPOD container to orchestrate other Docker containers on the same host is fairly straightforward. You only need a suitable Ansible playbook. For a first example, create a file named test.yml with the following content (or use the file from the GitHub repository):

---
  - name: Test Playbook
    hosts: localhost
    connection: local
    tasks:

      - name: Start a Docker service
        community.docker.docker_container:
          name: hello-world
          image: hello-world

From within CATPOD, you can use the Ansible docker Community collection to handle Docker containers on the host, as you can see in the example task here.

With this example playbook, we can run a CATPOD container to start a Docker Hello World container with the following command:

docker run -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v ./test.yml:/tmp/test.yml \
  --group-add $(stat -c '%g' /var/run/docker.sock) \
  --rm fpod/catpod \
    /tmp/test.yml

We need to mount two volumes into the CATPOD container:

First mount: -v /var/run/docker.sock:/var/run/docker.sock

/var/run/docker.sock is the path to the Docker socket. By mounting the host socket path to the socket path inside the container, Docker commands inside the container will be relayed to the socket on the host, allowing the CATPOD container to interact with other containers on the host (an idea that is described in this blog post by Jérôme Petazzoni and used widely nowadays for pseudo-Docker-in-Docker settings).

Second mount: -v ./test.yml:/tmp/test.yml

This is your example playbook that needs to be mounted into the container for the Ansible instance inside the container to use. Note that it does not matter where exactly in the container the file is mounted, as you specify the full file path in the container command anyway. However, tmp is a safe location without any risks of name collisions or overwriting existing files.

Enabling Docker socket access: --group-add $(stat -c '%g' /var/run/docker.sock)

The default user inside the CATPOD container is not root but a user named catpod with the UID and GID 10900. This user does not automatically have permissions to access the mounted Docker socket. The the group-add option, you add the catpod user to the group with the required permissions to do so.

It is recommended to use the --rm option to remove the CATPOD container after it has run the playbook, otherwise you'll end up with an idle container hanging around.

Container command: /tmp/test.yml

To run a playbook, the container command is the path to the mounted playbook file inside the container, in this case /tmp/test.yml. If you use a different mount path, e.g., -v ./test.yml:/var/test.yml, your container command would refer to that path, /var/test.yml.

Passing the playbook path as command prompts the container to internally use the ansible-playbook binary to run the playbook. CATPOD provides other options, described later in this chapter.

This is, of course, a toy example of how to use CATPOD; you don't really need a utility container to start another simple container. Have a look at the Use Cases chapter for more complex examples.

Container Commands Overview

{ playbook path }

As noted, providing the path to a playbook as a container command will prompt ansible-playbook to run the playbook. You can find more details here: https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html

This is used just like in the example above:

docker run -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v ./test.yml:/tmp/test.yml \
  --group-add $(stat -c '%g' /var/run/docker.sock) \
  --rm fpod/catpod \
    /tmp/test.yml

Beyond this, CATPOD provides (as of now) access to ansible-galaxy and ansible-vault.

galaxy

The galaxy command allows you to download and install collections (and to build and publish your own). You can find more details here: https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html

You can run this container command like ansible-galaxy itself, e.g., for downloading a collection:

docker run -it \
  -v ./local_collections:/tmp/local_collections \
   --group-add $(stat -c '%g' /var/run/docker.sock) \
   --rm fpod/catpod \
    galaxy collection download my_namespace.my_collection \
    -p /tmp/local_collections

Note that you don't need to mount the Docker socket or any playbooks for this, but it makes sense to mount a host directory where downloaded (or installed) collections are persisted, otherwise they will be gone once the CATPOD container is removed.

In the above example, the local local_collections is mounted into the container at /tmp/local_collections and the mount is passed as download path (with the -p option) to ansible-galaxy in the container command.

vault

The vault command allows to encrypt variables and files that can be used in Ansible playbooks. You can find more details here: https://docs.ansible.com/ansible/latest/cli/ansible-vault.html

You can run this container command like ansible-vault itself, e.g, for encrypting a string containing an access token:

docker run -it \
  --group-add $(stat -c '%g' /var/run/docker.sock) \
  --rm fpod/catpod vault \
    encrypt_string 'secret-access-token' --name 'encrypted_token'

You are then prompted to enter a vault password (this password will later need to be known to your playbook in order to decrypt the token value).

Once you entered and confirmed a password, you get the entry for the encrypted value that you can use in your playbooks; here's an example using the password foo:

Encryption successful
encrypted_token: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          37363638653461663238643433646166336563653439656666303464353331393932653332643033
          3064313364383764636238383139663430646563663864620a396565366633613833653035613762
          31626265326363343339386162373363623232666333346636396430636337646539376362663739
          6232353164336239630a383436643661396231346231663533366431633839633737363261373362
          33376336653061633766393461313233383139356561353037346439346266323630
Last Updated: 27/04/2025, 05:49
Contributors: Frodo Podschwadek
Prev
What is CATPOD?
Next
Use Cases