mhutter
ansible-docker-systemd-service
Jinja

Ansible role for creating Systemd services for docker containers

Last updated Jun 23, 2026
52
Stars
31
Forks
13
Issues
0
Stars/day
Attention Score
60
Language breakdown
Jinja 100.0%
Files click to expand
README

Docker role mhutter.docker-systemd-service

Generic role for creating systemd services to manage docker containers.

Example

Example of a Systemd unit for your app "myapp" that links to an already existing container "mysql":

- name: Start WebApp
  include_role:
    name: mhutter.docker-systemd-service
  vars:
    container_name: myapp
    container_image: myapp:latest
    container_links: ["mysql"]
    container_volumes:
      - "/data/uploads:/data/uploads"
    container_ports:
      - "3000:3000"
    container_hosts:
      - "host.docker.internal:host-gateway"
    container_env:
      MYSQLROOTPASSWORD: "{{ mysqlrootpw }}"
    container_labels:
      - "traefik.enable=true"

This will create:

  • A file containing the env vars (either /etc/sysconfig/myapp or /etc/default/myapp).
  • A systemd unit which starts and stops the container. The unit will be called <name>_container.service to avoid name clashes.

Role variables

  • container_name (required) - name of the container

Docker container specifics

  • container_image (required) - Docker image the service uses
  • container_args - arbitrary list of arguments to the docker run command as a string
  • containercmd (default: []_) - optional list of commands to the container run command (the part after the image name)
  • container_env - key/value pairs of ENV vars that need to be present
  • containervolumes (default: []_) - List of -v arguments
  • containerhostnetwork (default: false) - Whether the host network should be used
  • containerports (default: []_) - List of -p arguments
  • containerhosts (default: []_) - List of --add-host arguments
  • containerlinks (default: []_) - List of --link arguments
  • containerlabels (default: []_) - List of -l arguments
  • containerdockerpull (default: yes) - whether the docker image should be pulled
  • containerdockerpullforcesource (default: yes) - whether the docker image pull should be executed at every time (see dockerimage.forcesource)
  • containercapadd (default []) - List of capabilities to add
  • containercapdrop (default {}) - List of capabilities to drop
  • containernetwork (default "") - Network settings
  • containeruser (default "") - User settings
  • containerhostname (default ""_) - Container host name: --hostname flag
  • containerdevices (default []_) - List of devices to add
  • containerprivileged (default false_) - Whether the container should be privileged
  • containerstartpost - Optional command to be run by systemd after the container has started

Systemd service specifics

  • serviceenabled (default: yes_) - whether the service should be enabled
  • servicemasked (default: no_) - whether the service should be masked
  • servicestate (default: started_) - state the service should be in - set to
absent to remove the service.
  • servicerestart (default: yes_) - whether the service should be restarted on changes
  • servicename (default: <containername>_container) - name of the systemd service
  • servicesystemdoptions (default: []) - Extra options to include in systemd service file
  • servicesystemdunit_options: (default {"After": "docker.service", "PartOf": "docker.service", "Requires": "docker.service"}), key/value defining the content of the [Unit] service section.

Installation

This role requires the docker python module. Install it with pip3 install docker or apt install python3-docker (or drop the 3 for python 2.x).

Put this in your requirements.yml:

- role: mhutter.docker-systemd-service

and run ansible-galaxy install -r requirements.yml.

Gotchas

  • When the unit or env file is changed, systemd gets reloaded but existing containers are NOT restarted.
  • Make sure to quote values for containerports, containerhosts, container_volumes and so on, especially if they contain colons (:). Otherwise YAML will interpret them as hashes/maps and ansible will throw up.

About orchestrating Docker containers using systemd.

The concept behind this is to define systemd units for every docker container. This has some benefits:

  • systemd is a well-known interface
  • all services are controllable via the same tool (systemctl)
  • all logs are accessible via the same tool (journalctl)
  • dependencies can be defined
  • startup behaviour can be defined
  • by correctly defining the unit (see below), we can ensure we always have a clean container.
Here is an example myapp_container.service unit file (about what's produced by above code):

[Unit] # define dependencies After=docker.service PartOf=docker.service Requires=docker.service

[Service] # Load ENV vars from a file. Note that this env vars will only be # accessible in the context of the Exec* commands, and not within the # container itself. To make env-vars accessible within the Container, we use # the --env-file flag for the docker run command. EnvironmentFile=/etc/sysconfig/myapp

# Even though we explicitly run the container using the --rm flag, there # may be leftover containers (eg. after a system-, docker- or app-crash). # Starting a container with an existing name will always fail.

ExecStartPre=-/usr/bin/docker rm -f myapp

# actually run the container. # --name to identify the container # --rm ensure the container is removed after stopping # --env-file make ENV vars accessible to app # --link mysql link to a container named mysql. The DB will then be # accesible at mysql:3306 # -v mount /data/uploads into the container # -p 3000:3000 expose port 3000 on the network ExecStart=/usr/bin/docker run --name myapp --rm --env-file /etc/sysconfig/myapp --link mysql -v /data/uploads:/data/uploads -p 3000:3000 registry.cust.net/myapp/myapp:latest # note that there is no --restart parameter. This is because restarting # is taken care of by systemd.

# Stop command. ExecStop=/usr/bin/docker stop myapp

# Ensure log messages are correctly tagged in the system log. SyslogIdentifier=myapp

# Auto-Restart the container after a crash. Restart=always

[Install] # make sure service is started after docker is up WantedBy=docker.service

🔗 More in this category

© 2026 GitRepoTrend · mhutter/ansible-docker-systemd-service · Updated daily from GitHub