Skip to content

auto deploy

samatrhea edited this page May 2, 2024 · 4 revisions

Automatic Deployment

The CDP4-COMET WEB Application is automatically deployed to https://comet-web.cdp4.org/ using a Github action. The following steps are part of this automation:

Setup

The following sections explain how to install all the components in order to get Continuous Deployment to work. It is assumed that a Ubuntu box is available.

Docker Compose

Docker-Compose needs to be installed, the description is out of scope of this article

The content of the docker-compose file is as follows:

version: '3.8'
services:
  comet-web:
    image: index.docker.io/rheagroup/comet-web-community-edition:latest
    container_name: comet-web
    ports:
      - "8080:8080"

start the container using the following command:

docker-compose -f /PATH-TO-DOCKER-COMPOSE/comet-web-compose.yml up --detach

nginx

nginx is used as reverse proxy for the comet-web docker container as well as webhook using letsencrypt to install SSL certificates. The following configuration is used to setup the reverse proxy for the webhook service:

server {
        server_name YOUR-HOSTNAME;
        listen 80;

        location / {
                proxy_pass http://127.0.0.1:9000;
        }
}

NOTE: the webhook service will listen on http://127.0.0.1:9000

add a simlink to the sites-enabled folder and reload nginx. Don't forget to setup SSL using letsencript.

Wehbook

Install the community maintained webhook on the target box, we are using Ubuntu so the following command shall be used:

sudo apt-get install webhook

Create a hooks.json file in which the various hooks are described, in this case there is only one, use the following command:

touch /var/webhooks/hooks.json

The content of the hooks.json file should be as follows:

[
  {
    "id": "name-of-the-hook",
    "execute-command": "/..path-to-deployment-script../redeploy-comet-web.sh",
    "command-working-directory": "path-to-working-directory",
    "response-message": "Executing comet-web deploy script",
    "trigger-rule": {
        "match": {
                "type": "payload-hash-sha1",
                "secret": "YOUR SECRET",
                "parameter": {
                        "source": "header",
                        "name": "X-Hub-Signature"
                        }
                }
        }
  }
]

Create the redeploy-comet-web.sh file in which the existing container is stopped, a new one is pulled and started.

sudo touch /var/webhook-scripts/redeploy-comet-web.sh
sudo chmod 0600 /var/webhook-scripts/redeploy-comet-web.sh

The contents of the file are as follows:

#!/bin/bash
docker-compose -f /PATH-TO-DOCKER-COMPOSE/comet-web-compose.yml down --rmi all
docker pull rheagroup/comet-web-community-edition:latest
docker-compose -f /PATH-TO-DOCKER-COMPOSE/comet-web-compose.yml up --detach

Verify that the redeployment script works properly by executing it.

To verify that the webhook and nginx combination is working, start wehbook using the following command.

webhook -hooks /var/webhooks/hooks.json -hotreload

Use your favorite browser to send a GET request to the hook URL. Since you are not sending in the required secret, the hook will not execute, but at least a repsonse is returned that should indicate that the webhook is available.

Next step is to install webhook as a service, we'll use systemctl to do so:

sudo touch /etc/systemd/system/webhook.service

Add the following contents to the webhook.service file

[Unit]
Description=Webhooks

[Service]
ExecStart=/usr/bin/webhook -hooks /var/webhooks/hooks.json -hotreload

[Install]
WantedBy=multi-user.target

use the systemctl command to enable and start the new webhook service

sudo systemctl enable webhook.service
sudo systemctl start webhook.service

In case the unit file needs to be changed it needs to be reloaded and restarted using the following commands

sudo systemctl daemon-reload
sudo systemctl restart webhook.service

Github Action

The Github action that has been configured can be found here. It contains the folllowing parts:

The action is only invoked when a Tag is pushed that starts with web-. The convention is to use SEMVER for versioning, a valid Tag would be: web-1.0.2. The action runs on Ubuntu.

on:
  push:
    tags:
      - 'web-*'

jobs:
  build:
    runs-on: ubuntu-latest

The build starts by checking out the git repository and by setting up Docker Buildx.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2

The meta github action is used to process any metadata from github including the name of the Tag. This is used to set the tag name of the docker container in one of the following steps:

    - name: Docker meta
      id: meta
      uses: docker/metadata-action@v4
      with:
        images: rheagroup/comet-web-community-edition

A login to Docker Hub is required, otherwise we would not be able to login to Docker Hub. Please note that 2 repository secrets are used that need to be added using the GitHub web-ui. As can be noted, an extra condition is added here to make sure this only runs when a Tag is created.

    - name: Login to Docker Hub
      if: github.ref_type == 'tag'
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_PASSWORD }}

The docker container needs to be built. The context is the solution folder (the root folder of the repository), but in our case the Dockerfile is located in the COMETwebapp subfolder, hence the path to the Dockerfile is specified. Since we rely on DevExpress, we also need to pass the DEVEXPRESS_NUGET_KEY secret to the docker process. See also the Dockerfile itself for more information.

    - name: Build and push
      uses: docker/build-push-action@v4
      with:
          context: .
          file: ./COMETwebapp/Dockerfile
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          secrets: |
            "DEVEXPRESS_NUGET_KEY=${{ secrets.DEVEXPRESS_NUGET_KEY }}"

Once the dockerization and push to Docker hub was sucessfull, we need to tell our deployment target to pull and deplopy the new version. Please not that the WEBHOOK_URL and WEBHOOK_SECRET secrets are used and need to be added to the Git repository.

    - name: Invoke deployment hook
      uses: distributhor/workflow-webhook@v3
      env:
        webhook_url: ${{ secrets.WEBHOOK_URL }}
        webhook_secret: ${{ secrets.WEBHOOK_SECRET }}

Useful Links

The following articles where used to figure out how this works and can be used as reference material: