# GitOps with Mender and docker-compose: mender-application-update-pipeline

**URL:** https://hub.mender.io/t/gitops-with-mender-and-docker-compose-mender-application-update-pipeline/7364
**Category:** Tutorials
**Created:** [November 28, 2024, 4:04pm UTC](https://hub.mender.io/t/gitops-with-mender-and-docker-compose-mender-application-update-pipeline/7364 "2024-11-28T16:04:38Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![TheYoctoJester](https://yyz2.discourse-cdn.com/flex036/user_avatar/hub.mender.io/theyoctojester/32/1444_2.png) [@TheYoctoJester](https://hub.mender.io/u/TheYoctoJester)
#### Post date: [November 28, 2024, 4:04pm UTC](https://hub.mender.io/t/gitops-with-mender-and-docker-compose-mender-application-update-pipeline/7364/1 "2024-11-28T16:04:38Z")

</div>

## Introduction

Containers, and especially `docker` as the management tool are seeing an ever increasing interest and demand also in embedded Linux. Taking the next step from there are orchestrated containers, for example in a microservice architecture.

In the cloud world, [**docker compose**](https://docs.docker.com/compose/) is one of the most prominent tools for orchestration and management of such solutions. Transferring cloud native methods to IoT/edge use cases can provide great value, and to facilitate the usage in device fleets, Mender is providing an [**Application Update Module**](https://github.com/mendersoftware/app-update-module) for **docker compose**.

As an extension to the [tutorial on using the module on a Debian-based platform](https://docs.mender.io/artifact-creation/create-an-artifact/docker-compose), this article explains how to set up a GitHub Actions based pipeline that builds an Application Update Module artifact upon pushing to the repository and deploys it through a Mender backend upon publishing a release.

This is meant to serve as a template to implement GitOps to OTA in your own project.

 ![mender-application-update-pipeline](https://canada1.discourse-cdn.com/flex036/uploads/mender/original/2X/0/003dcc332463cfd9c71c476b78af498419992706.png)

## [mender-app-update-pipeline](https://github.com/TheYoctoJester/mender-app-update-pipeline)

The example pipeline consists of the following parts:

- `build_dind.yml`: the actual pipeline. It can be used as a template, where you adjust the environment variable declarations near the top to your requirements.
- `docker-compose.yml`: the Docker Compose-style manifest of containers which you want to deploy. It is based on the [tutorial on application updates](https://docs.mender.io/artifact-creation/create-an-artifact/docker-compose#create-the-mender-artifact) in the Mender documentation, and showcases a simple `traefik`+`whoami` setup.

```auto
version: "3.3"
services:
  gateway:
    image: "traefik:v2.9"
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "8080:80"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
  whoami:
    image: "traefik/whoami"
    labels:
      - "traefik.enable=true"
      - 'traefik.http.routers.whoami.rule=Path("/whoami")'
      - "traefik.http.routers.whoami.entrypoints=web"

```

Requisites:

- A compatible device to deploy to. The example pipeline uses a Raspberry Pi 4 64bit, running an image built with [this tutorial](https://hub.mender.io/t/using-the-docker-compose-application-update-module-on-yocto/6133)
- a Hosted Mender account, to create a [personal access token (PAT)](https://docs.mender.io/server-integration/using-the-apis#personal-access-tokens) and store it as a [GitHub Actions secret](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions). The example expects it under the name `MENDER_SERVER_ACCESS_TOKEN`.

## Implementation details

### workflow:

the `build_dind.yml` file sets up an Ubuntu-22.04 based container, and installs the required packages:

- `docker`
- `mender-artifact`
- `app-gen` script  
Additionally, it enables `docker` inside by requesting the service from the host, therefore the name “dind”, short for “Docker-in-Docker”. This is required for the `app-gen` script, which needs to run docker for obtaining the containers to package.

```auto
jobs:
  deploy_application_update:
    runs-on: ubuntu-22.04
    services:
      docker:
        image: docker:dind
        options: --privileged --shm-size=2g
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock:ro
    container:
      image: ubuntu:22.04
    steps:
      # step implementations removed for clarity of explanation
      - name: Checkout
    
      - name: update APT

      - name: install prerequisites

      - name: prepare Mender APT repos
    
      - name: prepare Docker APT repos

      - name: update APT
    
      - name: install Docker

      - name: install mender-artifact

      - name: install app-update-module generation script
    
      - name: create artifact

```

### triggers:

the example has three triggers configured.

```auto
name: build_dind_explicit

on:
  workflow_dispatch:
  release:
    types: [published]
  push:
    branches: 
      - main

```

- `workflow_dispatch`: so the workflow can be interactively started through the GitHub Actions Web user interface.
- `push`: the workflow runs to build the artifact upon each push to the `main` branch, so you have a quick feedback loop if the process is still functional
- `release`: this trigger is limited to the `published` type. The flow is similar to the `push`/`workflow_dispatch` one, but extends it by uploading the artifact to the configured Mender Server and creates a deployment for the devices listed in the `MENDER_DEVICES_LIST` environment variable.

```auto
      # Only releases upload and deploy through Mender server
      - name: Upload Mender Artifacts to Mender server
        if: ${{ github.event_name == 'release' }}
        uses: mendersoftware/mender-gh-action-upload-artifact@master
        with:
          mender_pat: ${{ secrets.MENDER_SERVER_ACCESS_TOKEN }}
          mender_artifact: ${{ env.MENDER_ARTIFACT_NAME }}.mender
          mender_uri: ${{ env.MENDER_SERVER_URL }}
      - name: Create deployment on Mender server
        if: ${{ github.event_name == 'release' }}
        uses: mendersoftware/mender-gh-action-create-deployment@master
        with:
          mender_pat: ${{ secrets.MENDER_SERVER_ACCESS_TOKEN }}
          mender_uri: ${{ env.MENDER_SERVER_URL }}
          mender_deployment_name: ${{ env.MENDER_DEPLOYMENT_NAME }}
          mender_release_name: ${{ env.MENDER_RELEASE_NAME }}-${{ env.MENDER_RELEASE_VERSION }}
          mender_devices_list: ${{ env.MENDER_DEVICES_LIST }}

```

## Usage

The repository is meant as a template for your own project. These are the minimal modifications for getting started:

1. set up a target device with `docker-compose` and the Application Update Module plus dependencies, and accept it to your Hosted Mender account. Note down the device ide.
2. create a personal access token (PAT) as described at [Using the APIs | Mender documentation](https://docs.mender.io/server-integration/using-the-apis#personal-access-tokens) and store it in a safe place for reference
3. set the `MENDER_SERVER_ACCESS_TOKEN` secret. In your GitHub settings, go to the “Actions”-\>“Secrets” section and create a new one with the name `MENDER_SERVER_ACCESS_TOKEN` and the above created PAT as value
4. change the following in `.github/workflows/build-dind.yml`:

- `MENDER_ARTIFACT_NAME`, `MENDER_RELEASE_NAME`, `MENDER_RELEASE_VERSION`, `MENDER_DEPLOYMENT_NAME`: to the desired artifact and application names and version
- `MENDER_DEVICES_LIST`: to an array (`[..]`) of device ids that you want to deploy to, usually the one that you just noted down in the first step
- `DEVICE_TYPE`: to the `device_type` of the devices you want to deploy to
- `PLATFORM`: to the docker architecture identification string of your target device(s).

1. change `docker-compose.yml` according to your application, and push to GitHub. This will trigger the artifact build
2. publish a release through the GitHub UI. This will build the artifact, and deploy it to the configured device(s).

## Conclusion

This tutorial respectively template provides a starting point for easily deploying a `docker-compose` based application through Mender, by automating artifact creation, uplaoding and deploying to a defined set of devices through GitHub Actions.

* * *

_If this tutorial was useful to you, please press like, or leave a thank you note to the contributor who put valuable time into this and made it available to you. It will be much appreciated!_
