I spent money on a domain so I might as well use it.

Media Center Series Part 1: Install Docker With Ansible

Using Anisble to provision Docker and Docker Compose

This series is a collection of notes from my experience setting up a media server. This first post covers using Ansible to setup Docker and Docker Compose on the server.

Ansible

The full Ansible playbook is available but I'm going to breakdown what went in to it. The file is designed so that you can drop it on to a box as a fresh root user and it will handle everything for you.

I'm not coordinating multiple machines so the script will be run locally on the box you want to configure using the default localhost configuration:

  - name: Docker
    connection: local
    gather_facts: yes
    hosts: localhost
    vars_prompt:
      - name: password
        prompt: "Password for docker user"
        private: yes
        encrypt: "sha512_crypt"
        confirm: yes
        salt_size: 7

I've configured the playbook to prompt for a password to use with for the docker user since there is no secretes management tool. That could be a nice to have but would be overkill for such a simple demo application.

Docker User

First we need a non root user to run the containers with. Instead of running these commands:

adduser docker
usermod -aG sudo docker

We can use the user module:

  - name: Create docker user
    user:
        name: docker
        password: "{{password}}"
        update_password: on_create
        groups:
            - sudo
            - render
            - video
        shell: /bin/bash
        state: present

The docker user will also be added to the render and video groups to enable access to hardware transcoding.

Install Docker

The Docker documentation recommends the following installation process:

sudo apt-get update
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg2 \
    software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

This involves installing some dependencies, adding a key and a new repository to the package manager and installing docker. Ansible has built in support for many of these operations which simplifies tasks.

The apt module allows us to install dependencies. By using "update_cache: yes" we can skip having a separate update step:

  - name: Install Docker Deps
    apt:
        name:
            - apt-transport-https
            - ca-certificates
            - curl
            - gnupg2
            - software-properties-common
        update_cache: yes

The apt_key module lets us pull in a new key from a URL:

  - name: Install Docker Repository Key
    apt_key:
        url: https://download.docker.com/linux/debian/gpg

The apt_repository module lets us add a new repository. Since I specified "gather_facts: yes" at the start of the playbook Ansible collected information about the machine before it started. This includes a "ansible_distribution_release" value that lets us use the correct repository for our Debian release:

- name: Add Docker Respository
apt_repository:
    repo: "deb [arch=amd64] https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable"

Then we can install Docker from the new repository:

- name: Install Docker
    apt:
        name:
            - docker-ce
            - docker-ce-cli
            - containerd.io
        update_cache: yes

Finally instead having to do this to enable the docker service to run on startup:

sudo systemctl enable docker
sudo systemctl start docker

The systemd module can be used instead:

- name: Set Docker to Run on Startup
  systemd:
    state: started
    name: docker
    enabled: true

Install Docker Compose

The Docker Compose documentation recommends the following installation process:

sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

This pulls a binary from Github, saves the binary under /usr/local/bin and sets the appropriate permissions for it.

The get_url module lets us fetch the binary off of GitHub. We use "ansible_system" and "ansible_architecture" from the gathered facts to generate the URL as opposed to uname. As a part of getting the binary we can set the mode to 755 for the docker user to avoid doing this in a second step. Also as per the docs "You must either add a leading zero so that Ansible's YAML parser knows it is an octal number (like 0644 or 01777) or quote it (like '644' or '1777') so Ansible receives a string and can do its own conversion from string into number."

  - name: Install Docker Compose
    get_url:
        url: https://github.com/docker/compose/releases/download/1.24.1/docker-compose-{{ ansible_system }}-{{ ansible_architecture }}
        dest: /usr/local/bin/docker-compose
        mode: '755'
        owner: docker

Running the Playbook

At this point you can curl the playbook to a fresh Debian machine and run the following:

ansible-playbook ansible.yml

Now you will have Docker and Docker Compose ready to use on your machine.