2026-01-26 23:24:37 -05:00
2026-01-26 23:24:37 -05:00
2026-01-26 23:24:37 -05:00
2026-01-26 23:24:37 -05:00
2026-01-26 23:24:37 -05:00

Docker Compose App Role

A flexible Ansible role for deploying and managing Docker Compose applications with features including backup/restore and healthchecks.

Overview

This role provides a standardized way to deploy containerized applications using Docker Compose. It handles directory creation, template rendering, and container lifecycle management.

Features

  • Template-based deployment with Jinja2 templating
  • Dual backup system (controller + remote host)
  • Health checks and deployment verification
  • Multiple deployment modes (template, file, or inline content)
  • Flexible directory management
  • Configurable backup retention policies

Quick Start

1. Create a New Role

Use the provided script to create a new application skeleton role:

./create_app_role.sh my-app

This creates:

roles/my-app/
├── defaults/main.yml     # Default variables
├── meta/main.yml         # Role metadata and dependencies
└── templates/
    └── compose.yml.j2    # Docker Compose template

2. Configure Your Application

Edit roles/my-app/defaults/main.yml:

---
app_role_name: my-app

my_app_container_name: "{{ app_name | default('my-app') }}"
my_app_container_version: latest
my_app_restart_policy: "{{ app_restart_policy }}"
my_app_http_port: 8080
my_app_data_path: "{{ app_dir }}/data"
my_app_config_path: "{{ app_dir }}/config"

# Optional: directories to create
app_subdirectories:
  - "{{ my_app_data_path }}"
  - "{{ my_app_config_path }}"

# Optional: backup configuration
app_backup_subdirectories:
  - "{{ my_app_data_path }}"
  - "{{ my_app_config_path }}"

3. Create Docker Compose Template

Edit roles/my-app/templates/compose.yml.j2:

---
services:
  my-app:
    image: "my-app:{{ my_app_container_version }}"
    container_name: "{{ my_app_container_name }}"
    restart: "{{ my_app_restart_policy }}"
    ports:
      - "{{ my_app_http_port }}:8080"
    volumes:
      - "{{ my_app_data_path }}:/data"
      - "{{ my_app_config_path }}:/config"
    environment:
      - TZ={{ app_timezone | default('UTC') }}

4. Deploy Your Application

Add to your playbook:

---
- name: Deploy my application
  hosts: localhost
  roles:
    - role: my-app

Advanced Usage

Backup and Restore

Create a New Backup

Create an on-demand backup using tags:

# Backup a specific application
ansible-playbook --tags backup playbook.yml

Configure backup retention and options in your role's meta vars:

# In roles/my-app/meta/main.yml
dependencies:
  - role: docker_compose_app
    vars:
      app_backup_subdirectories:
        - "{{ my_app_data_path }}"
        - "{{ my_app_config_path }}"
      app_backup_retention_days_controller: 90  # Keep backups for 90 days
      app_backup_retention_days_remote: 7       # Keep remote backups for 7 days  
      app_backup_stop_services: true            # Stop containers during backup

Automated Backups

For scheduled backups:

# Run daily backup at 2 AM - only runs backup tasks
0 2 * * * ansible-playbook -i inventory --tags backup my-playbook.yml

Tag-Based Execution

The role supports selective execution using tags:

# Setup only - doesn't start the containers
ansible-playbook --tags setup playbook.yml

# Full deployment - setup + start containers
ansible-playbook --tags deploy playbook.yml

# Restore and deploy
ansible-playbook --tags restore,deploy playbook.yml

# Backup only
ansible-playbook --tags backup playbook.yml

# Update only
ansible-playbook --tags update playbook.yml

# Backup then update
ansible-playbook --tags backup,update playbook.yml

Restore from Backup

Restore from the latest backup:

# Setup directories, restore from backup, then deploy
ansible-playbook --tags setup,restore,deploy playbook.yml

Configure restore options in your role's meta vars:

# In roles/my-app/meta/main.yml
dependencies:
  - role: docker_compose_app
    vars:
      app_restore_source: controller  # or 'remote'
      app_restore_max_age_days: 30    # Only restore backups newer than 30 days

Restore from a specific archive by setting the variable at runtime:

ansible-playbook --tags restore playbook.yml \
  -e app_restore_archive=/path/to/specific/backup-20240315-120000.tar.gz

Health Checks

Configure health monitoring:

- role: my-app
  vars:
    app_name: my-app
    app_health_check: true
    app_health_check_method: http
    app_health_check_url: "http://localhost:8080/health"
    app_health_check_retries: 30
    app_health_check_delay: 10

Updates

Update application containers using tags:

# Update a specific application
ansible-playbook --tags update playbook.yml

# Update all applications in a playbook
ansible-playbook --tags update site.yml

Update process:

  1. Stops the application
  2. Pulls latest images for all services
  3. Recreates containers with new images
  4. Runs health checks (if enabled)

Rollbacks

Rollback using the restore functionality:

# First, create a backup then update
ansible-playbook --tags backup,update playbook.yml

# If update fails, rollback from backup
ansible-playbook --tags restore playbook.yml

Important Notes:

  • Updates do NOT create automatic backups - create backups manually beforehand
  • Rollbacks must be triggered manually using the restore functionality
  • Using latest tags prevents effective rollbacks since the old image is overwritten
  • For production, use specific version tags instead of latest

Multiple Instances

Deploy multiple instances of the same application:

- role: jellyfin
  vars:
    app_name: jellyfin-movies
    jellyfin_http_port: 8096

- role: jellyfin  
  vars:
    app_name: jellyfin-tv
    jellyfin_http_port: 8097

Custom Templates and Files

Override template location:

- role: my-app
  vars:
    app_compose_template: /path/to/custom/compose.yml.j2

Use a static compose file:

If you have an existing docker-compose.yml file that doesn't need templating:

- role: my-app
  vars:
    app_name: my-app
    app_compose_file: /path/to/existing/docker-compose.yml

The file will be copied as-is to the application directory without Jinja2 processing.

Use inline content:

- role: docker_compose_app
  vars:
    app_name: simple-app
    app_role_name: simple-app
    app_compose_content: |
      services:
        app:
          image: nginx:alpine
          ports:
            - "80:80"

Configuration Reference

Core Variables

Variable Default Description
app_name Required Unique application instance name
role_name Required Role name for template paths
app_dir {{ host_root_path }}/{{ app_name }} Application directory
app_uid {{ ansible_facts.user_uid }} File ownership UID
app_gid {{ ansible_facts.user_gid }} File ownership GID
app_permission_mode "0640" File permission mode

Deployment Options

Variable Default Description
app_compose_template {{ app_templates_path }}/compose.yml.j2 Template file path
app_compose_file - Static compose file path
app_compose_content - Inline compose content
app_compose_validate true Validate compose syntax
app_compose_pull policy Image pull strategy
app_compose_recreate auto Container recreate strategy

Backup Configuration

Variable Default Description
app_backup_subdirectories [] Specific directories to backup
app_backup_stop_services true Stop containers during backup
app_backup_retention_days_controller 90 Controller backup retention
app_backup_retention_days_remote 7 Remote backup retention

Restore Configuration

Variable Default Description
app_restore_source controller Restore source (controller/remote)
app_restore_archive - Specific archive file to restore (overrides latest)
app_restore_max_age_days 30 Maximum backup age for restore (when finding latest)

Health Check Configuration

Variable Default Description
app_health_check true Enable health checks
app_health_check_method docker Check method (docker/http)
app_health_check_url - HTTP endpoint for health check
app_health_check_retries 30 Number of check retries
app_health_check_delay 10 Delay between checks (seconds)
app_health_check_status_codes [200, 201, 202] Valid HTTP status codes

Directory Management

Variable Default Description
app_subdirectories [] Directories to create in app_dir
app_extra_templates [] Additional templates to render

Example app_extra_templates:

app_extra_templates:
  - src: config.json.j2
    dest: "{{ app_dir }}/config/app.json"
  - src: env.j2  
    dest: "{{ app_dir }}/.env"

Best Practices

  1. Use semantic versioning for container tags instead of latest
  2. Test restore procedures regularly to ensure backups are valid
  3. Use specific directories for backups instead of entire app directory
  4. Monitor disk usage on backup storage locations

Architecture

The role is organized into logical task files for selective execution:

├── setup.yaml             # Validation, directories, and templates
├── restore.yaml           # Backup restoration logic
├── deploy.yaml            # Docker Compose deployment and startup
├── health_check.yaml      # Health monitoring and verification  
├── backup.yaml            # Backup creation and management
├── update.yaml            # Container update and image pulling
└── manage_compose.yaml    # Docker Compose lifecycle management

Task Execution Flow

  1. Setup (setup.yaml) - [setup, deploy]

    • Docker/Compose validation
    • Variable validation and security checks
    • Directory creation
    • Additional template deployment
  2. Restore (restore.yaml) - [restore, never]

    • Backup file selection and validation
    • Service stopping
    • Archive extraction
    • Service restart
  3. Deploy (deploy.yaml) - [deploy]

    • Docker Compose file creation
    • Container startup and management
  4. Health Check (health_check.yaml) - [deploy, healthcheck]

    • Service health verification
    • Endpoint monitoring
  5. Backup (backup.yaml) - [backup, never]

    • Service stopping (optional)
    • Archive creation
    • Backup copying and cleanup
    • Service restart
  6. Update (update.yaml) - [update, never]

    • Service stopping
    • Image pulling
    • Container recreation
    • Health verification

Each task file is designed to be idempotent and can be run multiple times safely.

Description
A generic ansible role for setting up and managing an application with Docker Compose.
Readme 33 KiB