Skip to content

Continuous integration pipeline

Timo Järvenpää edited this page Nov 20, 2020 · 1 revision

Continuous integration pipeline

The project has been configured to automatically run integration and end-to-end tests when a pull request has been created or when a pull request has been merged to the master branch. These tests are executed by GitHub actions workflows. In addition to the tests, a docker image will be built when there are changes to the master branch and the aforementioned tests have passed. In order to keep the lastest version of the application running on a staging environment, watchtower has been installed and configured on the staging server. The actual production version of the application has to be updated manually on the production server. This way we can ensure that only stable versions of the application are deployed to production.

GitHub Actions

The workflows can be found in node-pr.js.yml and node-push.js.yml respectively. The former will be executed when a pull request is made while the latter only activates when changes are merged into the master branch. The tests that will be run in both scenarios are the same ones that can be used in a local/development environment. Various integration tests will be done for the backend using Jest, while Cypress is used for the larger scale end-to-end tests.

Once all tests have passed in node-push.js.yml, the Dockerfile in the project repository will be used to build a docker image that will be pushed to DockerHub. The image can then be found under hybakteeripeli/app:latest. In order to achieve this, we've created a machine user account whose credentials will be used for the push operation.

DockerHub & Watchtower

Automatic deployment to the staging environment is implemented using the watchtower application. Since the application itself is a docker image being run in a container on the staging server, watchtower is set to ping the DockerHub repository for the app (i.e. hybakteeripeli/app) every 5 minutes and when a new version of the image is detected, watchtower pulls it to the staging server, restarting the application container in the process. Watchtower has also been configured to remove old versions of the image automatically to save space on the server. Watchtower also updates the other images (mongobd, nginx) on the server when there are newer versions available. Here's the docker-compose.yml for our simple watchtower configuration:

version: "3"
services:
  watchtower:
    restart: unless-stopped
    image: containrrr/watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    command: --cleanup
    logging:
      driver: "json-file"
      options:
        max-size: "200k"
        max-file: "10"
    container_name: watchtower