diff --git a/01.Get-started/02.Deploy-an-application-update/docs.md b/01.Get-started/02.Deploy-an-application-update/docs.md index ae7dbe675..6ceb42560 100644 --- a/01.Get-started/02.Deploy-an-application-update/docs.md +++ b/01.Get-started/02.Deploy-an-application-update/docs.md @@ -129,4 +129,4 @@ using Mender! Proceed to one of the following tutorials (listed in recommended order): 1. [Deploy an Operating System update](../03.Deploy-an-operating-system-update/docs.md) -1. [Deploy a Container update](../04.Deploy-a-container-update/docs.md) +1. [Deploy a Docker Compose Container update](../04.Deploy-a-docker-compose-update/docs.md) diff --git a/01.Get-started/03.Deploy-an-operating-system-update/docs.md b/01.Get-started/03.Deploy-an-operating-system-update/docs.md index 9db95733a..57c4942b6 100644 --- a/01.Get-started/03.Deploy-an-operating-system-update/docs.md +++ b/01.Get-started/03.Deploy-an-operating-system-update/docs.md @@ -238,4 +238,4 @@ resources on more advanced ways you will find here: ## Next step -Proceed to [Deploy a Docker container update](../04.Deploy-a-container-update/docs.md). +Proceed to [Deploy a Docker Compose Container update](../04.Deploy-a-docker-compose-update/docs.md) diff --git a/01.Get-started/04.Deploy-a-container-update/docs.md b/01.Get-started/04.Deploy-a-container-update/docs.md deleted file mode 100644 index 8ae310748..000000000 --- a/01.Get-started/04.Deploy-a-container-update/docs.md +++ /dev/null @@ -1,197 +0,0 @@ ---- -title: Deploy a Container update -taxonomy: - category: docs - label: tutorial ---- - -!!! This tutorial is not supported by the virtual device because it does not come -!!! with a package manager to install the needed dependencies. - -This tutorial will walk you through how to deploy Docker container updates with -Mender. We will be using the -[Docker Update Module](https://hub.mender.io/t/docker/324?target=_blank) which -allows you to specify a list of container images and their versions in a -[Mender Artifact](../../02.Overview/03.Artifact/docs.md) which -can later be deployed to your device using the hosted Mender Server. - -## Prerequisites - -To follow this tutorial, you will need to install: - -* [Docker Engine](https://docs.docker.com/engine/install?target=_blank) on your -workstation. - -It is also assumed that you have completed the following tutorials: - -* [Prepare a Raspberry Pi device](../01.Preparation/01.Prepare-a-Raspberry-Pi-device/docs.md) -* [Deploy an application update](../02.Deploy-an-application-update/docs.md) - -## Step 1 - Install Docker Engine on your Raspberry Pi - -Log in to your Raspberry Pi and run the commands outlined below. - -The [Docker Update Module](https://hub.mender.io/t/docker/324?target=_blank) has -a dependency on the `jq` utility, run the following command to install it: - -```bash -sudo apt-get install jq -``` - -Download the Docker install script: - -```bash -curl -fsSL https://get.docker.com -o get-docker.sh -``` - -Execute the Docker install script: - -```bash -sudo sh get-docker.sh -``` - -Once the installation script has finished, verify that you can run the -`sudo docker images` command. - -You will get similar output to below: - -```bash -sudo docker images -``` -> ```console -> REPOSITORY TAG IMAGE ID CREATED SIZE -> ``` - -As you can see, there are no Docker images on the device. In the next step we -will generate a -[Mender Artifact](../../02.Overview/03.Artifact/docs.md) which will -download an image. - -### Step 2 - Download the mender-artifact utility on your workstation - -!!! If you already installed `mender-artifact` on your system, you can skip this step. - -Prepare destination directory: - -```bash -mkdir -p ${HOME}/bin -``` - -Download the `mender-artifact` binary. If you're on Linux - - -```bash -wget https://downloads.mender.io/mender-artifact/master/linux/mender-artifact -O ${HOME}/bin/mender-artifact -``` - -On MacOS - - -```bash -wget https://downloads.mender.io/mender-artifact/master/darwin/mender-artifact -O ${HOME}/bin/mender-artifact -``` - - -Make the `mender-artifact` binary executable: - -```bash -chmod +x "${HOME}/bin/mender-artifact" -``` - -Add `${HOME}/bin` to `PATH`: - -```bash -export PATH="${PATH}:${HOME}/bin" -``` - -!!! Add above to `~/.bashrc` or equivalent to make it persistent across multiple -!!! terminal sessions. - - -## Step 3 - Prepare a Mender Artifact on your workstation - -Prepare a workspace and change directory to it: - -```bash -mkdir "${HOME}/mender-docker" && cd "${HOME}/mender-docker" -``` - -Download the `docker-artifact-gen` utility script: - - -```bash -wget https://raw.githubusercontent.com/mendersoftware/mender/master/support/modules-artifact-gen/docker-artifact-gen -``` - -Make `docker-artifact-gen` executable: - -```bash -chmod +x docker-artifact-gen -``` - -Set the target device type: - -```bash -DEVICE_TYPE="raspberrypi4" -``` - -!!! Change `raspberrypi4` to `raspberrypi3` if you are using a Raspberry Pi 3 - - -Generate a Mender Artifact that will deploy the `hello-world` Docker container image: - -```bash -./docker-artifact-gen \ - -n "hello-world-container-update" \ - -t "${DEVICE_TYPE}" \ - -o "hello-world-container-update.mender" \ - "hello-world" -``` - -!!! [hello-world](https://hub.docker.com/_/hello-world?target=_blank) is the name of the Docker -!!! image that we want to download on the device when we deploy the generated -!!! [Mender Artifact](../../02.Overview/03.Artifact/docs.md) - -## Step 3 - Deploy the Docker update - -Upload the file `hello-world-container-update.mender` from the previous step -to the hosted Mender. Go to the **RELEASES** tab in the UI and upload it. - -Once uploaded, click **CREATE DEPLOYMENT WITH THIS RELEASE** in order to deploy -it to your device. - -If the deployment of `hello-world-container-update.mender` is successful, you -will see that there is a image downloaded on the device: - -```bash -sudo docker images -``` -> ```console -> REPOSITORY TAG IMAGE ID CREATED SIZE -> hello-world 851163c78e4a 4 months ago 4.85kB -> ``` - -You can also see that the container was started, but since the hello-world -container does not contain a daemon it exited immediately: - -```bash -sudo docker ps -a | head -``` -> ```console -> CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -> 72e6cf80fa6a hello-world "/hello" 45 seconds ago Exited (0) 42 seconds ago optimistic_shaw -> ``` - -The [Docker Update Module](https://hub.mender.io/t/docker/324?target=_blank) -will download and run the specified images from e.g -[https://hub.docker.com](https://hub.docker.com). - -## Read more - -There is an alternative option for deploying containerized updates: - -* *[Docker Compose Update Module](../../06.Artifact-creation/01.Create-an-Artifact/10.Docker-Compose)* provides an interface for deploying container workloads managed by Docker Compose. - -You can explore other types of updates available by extending the Mender client -in the -[Update Modules category in the Mender Hub community platform](https://hub.mender.io/c/update-modules/13?target=_blank). diff --git a/01.Get-started/04.Deploy-a-docker-compose-update/docs.md b/01.Get-started/04.Deploy-a-docker-compose-update/docs.md new file mode 100644 index 000000000..fc54883a1 --- /dev/null +++ b/01.Get-started/04.Deploy-a-docker-compose-update/docs.md @@ -0,0 +1,419 @@ +--- +title: Deploy a Docker Compose update +taxonomy: + category: docs + label: tutorial +--- + + +!!! This tutorial is not supported by the virtual device because it does not come with a package manager to install the needed dependencies. + + +In this tutorial, we will conduct a container update to a device using a +multi-container Docker composition with a Traefik gateway and a backend service +`whoami`. First we will create the update Artifact with a new Docker composition +and deploy it to the device. In the second part will show how update the Docker +images in the composition using binary delta to save size and data transfer +bandwidth. + +In the example, we will observe Traefik as the primary container in the composition. +As a result the composition's naming and version will be heavily defined by the Traefik version. +This makes sense because Traefik provides the primary functionality in the composition. +In deployments consisting of multiple containers without a clear primary, it can make sense to version the composition separate from the container. + + +### Prerequisites + +To get started using the Docker Compose Update Module, we need to prepare the +target devices for accepting the deployment and the workstation for creating the +deployment. + +The tutorial assumes the usage of the Raspberry Pi with the reference OS image. +Please [prepare a Raspberry Pi device](../../01.Get-started/01.Preparation/01.Prepare-a-Raspberry-Pi-device/docs.md) if you haven't already. + +Throughout the tutorial you will execute commands on the device. +You can use the [Remote terminal](../../09.Add-ons/50.Remote-Terminal/docs.md) to gain access to the shell of the device and execute the command. + +The term [Update Module](../../03.Client-installation/05.Use-an-updatemodule/docs.md) will be used throughout the tutorial. +This is Mender mechanism to work with different types of updates, Docker Compose being one of them. +You don't need to know about this concept to complete get to a working example. + + +##### Installing the update module for docker compose + +! In this chapter the commands are executed on the **device** using the [Remote terminal](../../09.Add-ons/50.Remote-Terminal/docs.md) + +Since you're using the [Raspberry Pi reference image](../../01.Get-started/01.Preparation/01.Prepare-a-Raspberry-Pi-device/docs.md) Mender client is already present. +You need to install the other external dependencies. + +Become the root user on the device to simplify the install process: + +``` bash +sudo su +``` + +Install the extra external dependencies on the device: + +``` bash +printf "\n\nInstalling external dependencies \n\n" && \ +apt-get install -y jq tree xdelta3 && \ +printf "\n\nFeching docker install script \n\n" && \ +curl -fsSL https://get.docker.com -o get-docker.sh && \ +printf "\n\nExecuting docker install script \n\n" && \ +sh get-docker.sh && \ +printf "\n\nTesting docker \n\n" && \ +docker ps && \ +printf "\n\nSuccess \n\n" +``` + + +With all the dependencies in place you can install the update module: + + +```bash +printf "\n\nCreating the directory structure \n\n" && \ +mkdir -p /usr/share/mender/modules/v3 && \ +mkdir -p /usr/share/mender/app-modules/v1 && \ +printf "\n\nDownloading and installing the app update module \n\n" && \ +wget https://raw.githubusercontent.com/mendersoftware/app-update-module/1.1.0/src/app \ + -O /usr/share/mender/modules/v3/app && \ +chmod +x /usr/share/mender/modules/v3/app && \ +printf "\n\nDownloading and installing the docker compose update module \n\n" && \ +wget https://raw.githubusercontent.com/mendersoftware/app-update-module/1.1.0/src/app-modules/docker-compose \ + -O /usr/share/mender/app-modules/v1/docker-compose \ + && chmod +x /usr/share/mender/app-modules/v1/docker-compose +printf "\n\nDownloading and installing the configuration files \n\n" && \ +wget https://raw.githubusercontent.com/mendersoftware/app-update-module/1.1.0/conf/mender-app.conf \ + -O /etc/mender/mender-app.conf && \ +wget https://raw.githubusercontent.com/mendersoftware/app-update-module/1.1.0/conf/mender-app-docker-compose.conf \ + -O /etc/mender/mender-app-docker-compose.conf && \ +printf "\n\nSuccess \n\n" +``` + +##### Prepare the workstation + +! In this chapter the commands are executed on the **workstation** + +Install the external dependencies: + +``` bash +sudo su +``` + +```bash +printf "\n\nInstalling external dependencies \n\n" && \ +apt-get install -y xdelta3 && \ +printf "\n\nSuccess \n\n" +exit +``` + +Run the following to verify: + + +``` bash +xdelta3 -h +# Xdelta version 3.0.11, Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Joshua MacDonald +# Xdelta comes with ABSOLUTELY NO WARRANTY. +# This is free software, and you are welcome to redistribute it +# under certain conditions; see "COPYING" for details. +# usage: xdelta3 [command/options] [input [output]] +# make patch: +# +# xdelta3.exe -e -s old_file new_file delta_file +``` + +You also need to need to install [mender-artifact](../../10.Downloads/docs.md#mender-artifact) (version >= 3.0) on your workstation. +This isn't installable through a copy code snippet. +Please follow the instructions to install [mender-artifact](../../10.Downloads/docs.md#mender-artifact) on your workstation. + +To verify the successful install, run the commands below: + +```bash +mender-artifact -h +# Output +# NAME: +# mender-artifact - interface for manipulating Mender Artifacts +# +# USAGE: +# mender-artifact [--version][--help] [] +# ... +``` + +Next install the `app-gen` tool. +This is the tool we will use to generate the artifacts. + + +```bash +printf "\n\nCreating the directory structure \n\n" && \ +mkdir docker-compose-evaluation && \ +printf "\n\nDownloading and installing the docker compose generator tool \n\n" && \ +cd docker-compose-evaluation && \ +wget https://raw.githubusercontent.com/mendersoftware/app-update-module/1.1.0/gen/app-gen \ + -O app-gen && \ +chmod +x app-gen && \ +printf "\n\nSuccess \n\n" +``` + +Test the installation: + +```bash +./app-gen +# Simple tool to generate Mender Artifact suitable for App Update Module +# +# Usage: ./app-gen [options] [-- [options-for-mender-artifact] ] +# ... +``` + + +### Create a deployment + +! In this chapter the commands are executed on the **workstation** + +The `app-gen` script we installed previously extends the +[mender-artifact](../../10.Downloads/docs.md#mender-artifact) tool to create +Artifacts for container updates. We will use this tool to create a Mender +Artifact containing the Docker Compose manifest and the Docker images used by +the composition. Including the Docker images is optional, excluding the images +will make the devices try to pull the images from the Docker registry. + +#### Create the Mender Artifact + +Begin by creating the manifest on your workstation and saving it in a separate +directory: + +```bash +VERSION="v2.9" +MANIFEST_DIR="manifests/$VERSION" + +mkdir -p $MANIFEST_DIR + +cat < $MANIFEST_DIR/docker-compose.yaml +version: "3.3" +services: + gateway: + image: "traefik:$VERSION" + 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" +EOF +``` + +To generate the Artifact, we need to know the target platform of the devices we want to deploy to. +In this tutorial the device is a Raspberry Pi so it's set to `linux/arm/v7` (`os/arch/variant`). + +!!! You can check more details regarding this notation in [Multi-platform images](https://docs.docker.com/build/building/multi-platform/) and [Architectures other than amd64](https://github.com/docker-library/official-images#architectures-other-than-amd64). + +Run the command below to generate the update Artifact: + +```bash +ARTIFACT_NAME="traefik-composition" + +app-gen --artifact-name "$ARTIFACT_NAME-$VERSION" \ + --device-type "raspberrypi4" \ + --device-type "raspberrypi3" \ + --platform "linux/arm/v7" \ + --application-name "$ARTIFACT_NAME" \ + --image docker.io/library/traefik:$VERSION \ + --image docker.io/traefik/whoami:latest \ + --orchestrator docker-compose \ + --manifests-dir $MANIFEST_DIR \ + --output-path "$ARTIFACT_NAME-$VERSION".mender \ + -- \ + --software-name="$ARTIFACT_NAME" \ + --software-version="$VERSION" +``` + +The generated Artifact (`.mender` extension) is now ready to be deployed on the device. + +Open your browser and navigate to the "Releases" column in the [Mender UI](https://hosted.mender.io/ui/releases) and upload your newly created Artifact. +Once uploaded, navigate to the "Devices" column and select your device and then click `Create a deployment for this device` in the `Device actions` in the bottom right corner. +Select your newly created Artifact and click `CREATE DEPLOYMENT`. + +##### Verify your deployment + +! In this chapter the commands are executed on the **device** using the [Remote terminal](../../09.Add-ons/50.Remote-Terminal/docs.md) + +Once deployed, the device will start serving a simple server on port 8080. +You can test the application by sending a request to path `/whoami` and the server will echo the request. + + +```bash +docker ps + + +# Output +# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +# 3a27e70761b8 traefik:v2.9 "/entrypoint.sh --pr…" 9 minutes ago Up 9 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp traefik-composition-gateway-1 +# 01ca7e0e2f93 traefik/whoami "/whoami" 9 minutes ago Up 9 minutes 80/tcp traefik-composition-whoami-1 +``` + +If you get the similar output as above it shows that the containers on the device are running the correct versions. +Run the following command to verify it works: + +``` bash +curl http://localhost:8080/whoami + +# Output: +# Hostname: d8ae8a9eca1c +# IP: 127.0.0.1 +# IP: 172.19.0.3 +# RemoteAddr: 172.19.0.2:58470 +# GET /whoami HTTP/1.1 +# Host: localhost:8080 +# Accept: */* +# Accept-Encoding: gzip +# X-Forwarded-For: 172.19.0.1 +# X-Forwarded-Host: localhost:8080 +# X-Forwarded-Port: 8080 +# X-Forwarded-Proto: http +# X-Forwarded-Server: c2c36ac1634b +# X-Real-Ip: 172.19.0.1 +``` + + +#### Update your composition using delta + +! In this chapter the commands are executed on the **workstation** + +Now that your Docker composition is running on the device, it is time to upgrade +the Traefik container to the next version. Create a new manifest directory and +update the gateway service to `traefik:v2.10`: + +```bash +VERSION="v2.10" +MANIFEST_DIR="manifests/$VERSION" + +mkdir -p $MANIFEST_DIR + +cat < $MANIFEST_DIR/docker-compose.yaml +version: "3.3" +services: + gateway: + image: "traefik:$VERSION" + 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" +EOF +``` + +Since we are only upgrading the Traefik service, we do not need to include the +image for the `whoami` service in the command below. + +Proceed with creating the Artifact: + + +```bash +ARTIFACT_NAME="traefik-composition" +PREVIOUS_VERSION="v2.9" +NEW_VERSION="v2.10" + +app-gen --artifact-name "$ARTIFACT_NAME-$VERSION" \ + --device-type "raspberrypi4" \ + --device-type "raspberrypi3" \ + --platform "linux/arm/v7" \ + --application-name "$ARTIFACT_NAME" \ + --image docker.io/library/traefik:$PREVIOUS_VERSION,docker.io/library/traefik:$NEW_VERSION \ + --orchestrator docker-compose \ + --manifests-dir $MANIFEST_DIR \ + --output-path "$ARTIFACT_NAME-$VERSION".mender \ + --deep-delta \ + -- \ + --software-name "${ARTIFACT_NAME}" \ + --software-version="$VERSION" \ + --depends "rootfs-image.${ARTIFACT_NAME}.version:$PREVIOUS_VERSION" +``` + +In the above command we create a binary delta of the image to save bandwidth. +That is why some parameters are different compared to the first version. + +The `--image` argument now has two images listed. +This instructs the tool to create a delta to update form the previous to the new version. + +The `--depends` argument sets a [versioning constraints](../../06.Artifact-creation/09.Software-versioning/docs.md#application-updates-update-modules). +This ensures that the new Artifact can only be installed on top of a specific version running on the device. +This is a requirement for delta updates as they can only be applied to a specific base version. + +The `--deep-delta` flag enables the delta feature of comparing individual layers of the composition and calculating delta between the each. +This gives a better compression ratio and is recommended as the default delta. + + +Upload the Artifact to Hosted Mender and deploy it to the device. + +#### Verify the update on the device + +! In this chapter the commands are executed on the device using the [Remote terminal](../../09.Add-ons/50.Remote-Terminal/docs.md) + +```bash +docker ps + +# Output +# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +# 0a81f8f74b30 traefik:v2.10 "/entrypoint.sh --pr…" 58 seconds ago Up 55 seconds 0.0.0.0:8080->80/tcp, :::8080->80/tcp traefik-composition-gateway-1 +# 6cacafb1e9d3 traefik/whoami "/whoami" 58 seconds ago Up 55 seconds 80/tcp traefik-composition-whoami-1 +``` + +If you get the similar output as above it shows that the containers have been updated to the new versions. + + +### Benefits of Delta Updates + +! In this chapter the commands are executed on the **workstation** + +The motivation for using the delta updates is to have a smaller Artifact for the same effect. +This varies a lot depending on the amount of content change between the two versions. +The more the software is alike, the more the delta will save. + +Let's compare how much saving the delta introduced in this case by creating a non-delta Artifact for the new version. + + +```bash +ARTIFACT_NAME="traefik-composition" +VERSION="v2.10" + +app-gen --artifact-name "$ARTIFACT_NAME-$VERSION" \ + --device-type "raspberrypi4" \ + --device-type "raspberrypi3" \ + --platform "linux/arm/v7" \ + --application-name "$ARTIFACT_NAME" \ + --image docker.io/library/traefik:$VERSION \ + --orchestrator docker-compose \ + --manifests-dir $MANIFEST_DIR \ + --output-path "NO-DELTA-${ARTIFACT_NAME}-${VERSION}".mender \ + -- \ + --software-name "${ARTIFACT_NAME}" \ + --software-version="$VERSION" +``` + + +And compare the difference: + +``` bash +du -h NO-DELTA-traefik-composition-v2.10.mender traefik-composition-v2.10.mender +# Output: +# 38M NO-DELTA-traefik-composition-v2.10.mender +# 28M traefik-composition-v2.10.mender +``` + +So in this case we are seeing a ~28% decrease in size, though the size savings of deltas vary depending on the changes between Artifacts and can go up to 90% in some cases. diff --git a/06.Artifact-creation/01.Create-an-Artifact/10.Docker-Compose/docs.md b/06.Artifact-creation/01.Create-an-Artifact/10.Docker-Compose/docs.md deleted file mode 100644 index a11bdc86c..000000000 --- a/06.Artifact-creation/01.Create-an-Artifact/10.Docker-Compose/docs.md +++ /dev/null @@ -1,254 +0,0 @@ ---- -title: Tutorial: Docker Compose update -taxonomy: - category: docs - label: tutorial ---- - -In this tutorial, we will conduct a container update to a device using a -multi-container Docker composition with a Traefik gateway and a backend service -`whoami`. First we will create the update Artifact with a new Docker composition -and deploy it to the device. In the second part will show how update the Docker -images in the composition using binary delta to save size and data transfer -bandwidth. - -### Prerequesites - -To get started using the Docker Compose Update Module, we need to prepare the -target devices for accepting the deployment and the workstation for creating the -deployment. - -##### Prepare the devices -Before installing the Update Module on the **target device**, you need to ensure that the following -dependencies are installed on the device: - * [Mender client](../../../03.Client-installation/02.Install-with-Debian-package) (version >= 3.0) - * [Docker Engine](https://docs.docker.com/engine/install/?target=_blank) - * [Docker Compose](https://docs.docker.com/compose/install/?target=_blank) (version >= 2.0) - * [`jq`](https://jqlang.github.io/jq/) - * [`tree`](http://mama.indstate.edu/users/ice/tree/) - * [`xdelta3`](https://github.com/jmacd/xdelta) - -> To quickly verify the required dependencies are installed on your device, run -> the following commands: -> ```bash -> mender-update --version && \ -> docker --version && \ -> docker compose version && \ -> jq --version && \ -> tree --version && \ -> xdelta3 -V && -> ``` - -To install the Docker Compose Update Module, run the following commands on your -devices: - -```bash -# Install Application Update Module -mkdir -p /usr/share/mender/modules/v3 -wget https://raw.githubusercontent.com/mendersoftware/app-update-module/1.1.0/src/app \ - -O /usr/share/mender/modules/v3/app \ - && chmod +x /usr/share/mender/modules/v3/app -# Install Docker Compose module -mkdir -p /usr/share/mender/app-modules/v1 -wget https://raw.githubusercontent.com/mendersoftware/app-update-module/1.1.0/src/app-modules/docker-compose \ - -O /usr/share/mender/app-modules/v1/docker-compose \ - && chmod +x /usr/share/mender/app-modules/v1/docker-compose -# Install the Configuration files -wget https://raw.githubusercontent.com/mendersoftware/app-update-module/1.1.0/conf/mender-app.conf \ - -O /etc/mender/mender-app.conf -wget https://raw.githubusercontent.com/mendersoftware/app-update-module/1.1.0/conf/mender-app-docker-compose.conf \ - -O /etc/mender/mender-app-docker-compose.conf -``` - - -!!! The Docker Compose Update Module is a sub-module of the -!!! [Application Update Module](https://github.com/mendersoftware/app-update-module/blob/master/docs/README-submodule-api.md#applications-updates). -!!! That is why we install two Update Modules in the snippet above. - -##### Prepare the workstation -Once your devices are ready, return to your workstation and install the -Application Update Artifact Generator. First, make sure that you have -[mender-artifact](../../../10.Downloads/docs.md#mender-artifact) (version >= 3.0) installed -on your workstation, then install the Application Update Artifact Generator: - -```bash -BINDIR=$HOME/bin -mkdir -p $BINDIR -export PATH=$BINDIR:$PATH -wget https://raw.githubusercontent.com/mendersoftware/app-update-module/1.1.0/gen/app-gen \ - -O $BINDIR/app-gen -chmod +x $BINDIR/app-gen -``` - -### Create a deployment -The `app-gen` script we installed previously extends the -[mender-artifact](../../../10.Downloads/docs.md#mender-artifact) tool to create -Artifacts for container updates. We will use this tool to create a Mender -Artifact containing the Docker Compose manifest and the Docker images used by -the composition. Including the Docker images is optional, excluding the images -will make the devices try to pull the images from the Docker registry. - -#### Create the Mender artifact -Begin by creating the manifest on your workstation and saving it in a separate -directory: -```bash -mkdir -p manifests/v1 -cat < manifests/v1/docker-compose.yaml -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" -EOF -``` - -To generate the artifact, we need to know the target platform of the devices we -want to deploy to. In the following example, we will assume the platform we are -deploying to is `linux/arm/v7` (`os/arch/variant`). You can check more details regarding -this notation in [Multi-platform images](https://docs.docker.com/build/building/multi-platform/) and -[Architectures other than amd64](https://github.com/docker-library/official-images#architectures-other-than-amd64). -```bash -ARTIFACT_NAME="myfirstcomposition" -DEVICE_TYPE="raspberrypi4" -PLATFORM="linux/arm/v7" -app-gen --artifact-name "$ARTIFACT_NAME" \ - --device-type "$DEVICE_TYPE" \ - --platform "$PLATFORM" \ - --application-name "$ARTIFACT_NAME" \ - --image docker.io/library/traefik:v2.9 \ - --image docker.io/traefik/whoami:latest \ - --orchestrator docker-compose \ - --manifests-dir ./manifests/v1 \ - --output-path artifact.mender \ - -- \ - --software-name="$ARTIFACT_NAME" \ - --software-version="v1" -``` - -!!!!! All arguments after `--` are passed directly to `mender-artifact write -!!!!! module-image`. In the following example we will make use of -!!!!! [versioning constraints](../../09.Software-versioning/docs.md#application-updates-update-modules) -!!!!! to prevent deploying the wrong version to a device. - -#### Deploy the Mender Artifact -The generated artifact is now ready to be deployed on the device. Open your -browser and navigate to the "Releases" column in the [Mender -UI](https://hosted.mender.io/ui/releases) and upload your newly created -artifact. Once uploaded, navigate to the "Devices" column and select your device -and then click `Create a deployment for this device` in the `Device actions` in -the bottom right corner. Select your newly created artifact and click `CREATE -DEPLOYMENT`. - -##### Verify your deployment - -Once deployed, the device will start serving a simple server on port 8080. You -can test the application by sending a request to path `/whoami` and the server -will echo the request. -To this end, we will leverage the Troubleshoot add-on and start a port-forward -session using the [mender-cli](../../../10.Downloads/docs.md#mender-cli). -```bash -mender-cli port-forward 8080:8080 -``` -!!!!! Note that `device_id` should be replaced with the ID of the device (i.e `1bfcf943-4378-4a4f-bc88-0b4c86cdcc74`). - -```bash -curl http://localhost:8080/whoami -``` -> ```bash -> Hostname: d8ae8a9eca1c -> IP: 127.0.0.1 -> IP: 172.19.0.3 -> RemoteAddr: 172.19.0.2:58470 -> GET /whoami HTTP/1.1 -> Host: localhost:8080 -> Accept: */* -> Accept-Encoding: gzip -> X-Forwarded-For: 172.19.0.1 -> X-Forwarded-Host: localhost:8080 -> X-Forwarded-Port: 8080 -> X-Forwarded-Proto: http -> X-Forwarded-Server: c2c36ac1634b -> X-Real-Ip: 172.19.0.1 -> ``` - - -#### Update your composition using delta - -! This section requires [xdelta3](https://github.com/jmacd/xdelta) to be -! installed on both your workstation and your device. Please make sure that -! this dependency is installed before proceeding. - -Now that your Docker composition is running on the device, it is time to upgrade -the Traefik container to the next version. Create a new manifest directory and -bump gateway service to `traefik:v2.10`: -```bash -mkdir -p manifests/v2 -cat < manifests/v2/docker-compose.yaml -version: "3.3" -services: - gateway: - image: "traefik:v2.10" - 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" -EOF -``` - -Since we are only upgrading the Traefik service, we do not need to include the -image for the `whoami` service since this was provided by the last deployment. -And, to save bandwidth we will create a binary delta of the image for the -gateway service. - -```bash -app-gen --artifact-name "${ARTIFACT_NAME}-v2" \ - --device-type "$DEVICE_TYPE" \ - --platform "$PLATFORM" \ - --application-name "$ARTIFACT_NAME" \ - --image docker.io/library/traefik:v2.9,docker.io/library/traefik:v2.10 \ - --orchestrator docker-compose \ - --manifests-dir ./manifests/v2 \ - --output-path artifact-v2.mender \ - --deep-delta \ - -- \ - --software-name "${ARTIFACT_NAME}" \ - --software-version "v2" \ - --depends "rootfs-image.${ARTIFACT_NAME}.version:v1" -``` - -!!!!! The last argument to `app-gen` ensures that the artifact is only -!!!!! installed if `v1` is installed. - -The `--deep-delta` flag enables the delta feature which creates a binary delta -between the container images provided by the `--image` flag. Note that the -`--image` flag needs two inputs to be able to compute the delta. After -generating the artifact, upload the artifact to the Mender Server and deploy it -to your device. - -Congratulations! You successfully upgraded a component on your device. Continue -reading to learn more about advanced use-cases such as [custom update -modules](../../08.Create-a-custom-Update-Module)) and [software -versioning](../../09.Software-versioning).