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 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 for docker compose.
As an extension to the tutorial on using the module on a Debian-based platform, 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-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 in the Mender documentation, and showcases a simpletraefik
+whoami
setup.
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
- a Hosted Mender account, to create a personal access token (PAT) and store it as a GitHub Actions secret. 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 enablesdocker
inside by requesting the service from the host, therefore the name “dind”, short for “Docker-in-Docker”. This is required for theapp-gen
script, which needs to run docker for obtaining the containers to package.
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.
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 themain
branch, so you have a quick feedback loop if the process is still functionalrelease
: this trigger is limited to thepublished
type. The flow is similar to thepush
/workflow_dispatch
one, but extends it by uploading the artifact to the configured Mender Server and creates a deployment for the devices listed in theMENDER_DEVICES_LIST
environment variable.
# 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:
- 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. - create a personal access token (PAT) as described at Using the APIs | Mender documentation and store it in a safe place for reference
- set the
MENDER_SERVER_ACCESS_TOKEN
secret. In your GitHub settings, go to the “Actions”->“Secrets” section and create a new one with the nameMENDER_SERVER_ACCESS_TOKEN
and the above created PAT as value - 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 versionMENDER_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 stepDEVICE_TYPE
: to thedevice_type
of the devices you want to deploy toPLATFORM
: to the docker architecture identification string of your target device(s).
- change
docker-compose.yml
according to your application, and push to GitHub. This will trigger the artifact build - 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!