From 8504e1a7491226a463e21d6ec4b5c78101575fe1 Mon Sep 17 00:00:00 2001 From: "tobias.kantusch" Date: Tue, 27 Apr 2021 15:41:57 +0200 Subject: [PATCH] Add automatic deployment --- .gitlab-ci.yml | 88 +++++++++++++++++++++++++++++++++++++++++++-- nomad/Dockerfile | 18 ++++++++++ nomad/api.tpl.nomad | 64 +++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 nomad/Dockerfile create mode 100644 nomad/api.tpl.nomad diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 81e3bfd..4ca2956 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,10 +6,14 @@ stages: - lint - test - docker + - deploy + - cleanup variables: DOCKER_TLS_CERTDIR: "" - IMAGE_NAME: $DOCKER_REGISTRY/$DOCKER_IMAGE_NAME/$CI_COMMIT_REF_SLUG:latest + NOMAD_SLUG: $NOMAD_PREFIX-$CI_ENVIRONMENT_SLUG + IMAGE_NAME_ENV: $DOCKER_REGISTRY/$DOCKER_IMAGE_NAME/$CI_COMMIT_REF_SLUG:$CI_PIPELINE_IID + IMAGE_NAME_GENERAL: $DOCKER_REGISTRY/$DOCKER_IMAGE_NAME/$CI_COMMIT_REF_SLUG:latest compile: stage: build @@ -56,5 +60,83 @@ dockerimage: # Prevent pull rate limit but still have normal alpine image in Dockerfile - docker pull $DOCKER_REGISTRY/library/alpine:latest - docker tag $DOCKER_REGISTRY/library/alpine:latest alpine:latest - - docker build -t $IMAGE_NAME . - - docker push $IMAGE_NAME + - docker build -t $IMAGE_NAME_ENV . + - docker push $IMAGE_NAME_ENV + - docker tag $IMAGE_NAME_ENV $IMAGE_NAME_GENERAL + - docker push $IMAGE_NAME_GENERAL + +.start_deployment: &start_deployment + image: drp.codemoon.xopic.de/nomad-ci:latest + stage: deploy + needs: + - job: dockerimage + artifacts: false + script: + # Only replace set env vars + - envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < nomad/api.tpl.nomad > nomad/api.nomad + # Make sure to set NOMAD_ADDR, NOMAD_SKIP_VERIFY and NOMAD_TOKEN env vars in CI settings appropriately + - nomad validate nomad/api.nomad + # nomad plan returns 1 if allocation is created or destroyed which is what we want here + - nomad plan nomad/api.nomad || [ $? == 1 ] + - nomad run nomad/api.nomad + artifacts: + paths: + - nomad/api.nomad + expire_in: 1 month + expose_as: api-nomad + +deploy_review: + <<: *start_deployment + variables: + HOSTNAME: $CI_ENVIRONMENT_SLUG.$BASE_DOMAIN + environment: + name: $CI_COMMIT_REF_SLUG + url: http://$HOSTNAME + on_stop: stop_review + only: + - branches + except: + - main + +stop_review: + # See: + # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml + stage: cleanup + image: drp.codemoon.xopic.de/nomad-ci:latest + variables: + GIT_STRATEGY: none + script: + - nomad stop $NOMAD_SLUG + environment: + name: $CI_COMMIT_REF_SLUG + action: stop + needs: [] + allow_failure: true + rules: + - if: '$CI_COMMIT_BRANCH == "main"' + when: never + - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH' + when: manual + +deploy_staging: + <<: *start_deployment + variables: + NOMAD_SLUG: $NOMAD_PREFIX-staging + HOSTNAME: staging.$BASE_DOMAIN + environment: + name: staging + url: http://$HOSTNAME + only: + - main + +deploy_production: + <<: *start_deployment + variables: + NOMAD_SLUG: $NOMAD_PREFIX-production + HOSTNAME: $PRODUCTION_URL + environment: + name: production + url: https://$HOSTNAME + only: + - main + when: manual diff --git a/nomad/Dockerfile b/nomad/Dockerfile new file mode 100644 index 0000000..cd661c3 --- /dev/null +++ b/nomad/Dockerfile @@ -0,0 +1,18 @@ +# Simple image containing the Nomad binary to deploy Nomad jobs + +FROM debian:buster-slim + +# Install prerequisites, gettext contains envsubst used in the CI +RUN apt-get update && \ + apt install -y unzip wget gettext && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists + +# Download Nomad +RUN wget "https://releases.hashicorp.com/nomad/1.0.4/nomad_1.0.4_linux_amd64.zip" && \ + wget "https://releases.hashicorp.com/nomad/1.0.4/nomad_1.0.4_SHA256SUMS" && \ + grep "nomad_1.0.4_linux_amd64.zip" nomad_1.0.4_SHA256SUMS | sha256sum -c - && \ + unzip nomad_1.0.4_linux_amd64.zip + +# Install Nomad +RUN mv nomad /usr/sbin/ && nomad -version diff --git a/nomad/api.tpl.nomad b/nomad/api.tpl.nomad new file mode 100644 index 0000000..700a911 --- /dev/null +++ b/nomad/api.tpl.nomad @@ -0,0 +1,64 @@ +job "${NOMAD_SLUG}" { + datacenters = ["dc1"] + + group "api" { + count = 1 + + update { + // https://learn.hashicorp.com/tutorials/nomad/job-rolling-update + max_parallel = 1 + min_healthy_time = "30s" + healthy_deadline = "5m" + progress_deadline = "10m" + auto_revert = true + } + restart { + attempts = 3 + delay = "15s" + interval = "30m" + mode = "fail" + } + + network { + mode = "bridge" + + port "http" { + to = 3000 + } + } + + service { + # urlprefix- tag allows Fabio to discover this service and proxy traffic correctly + tags = ["urlprefix-${HOSTNAME}:80/"] + name = "${NOMAD_SLUG}" + port = "http" + + // Health check to let Consul know we are alive + check { + name = "health-check" + type = "http" + port = "http" + path = "/api/v1/health" + interval = "10s" + timeout = "2s" + check_restart { + limit = 3 // auto-restart task when health check fails 3x in a row + } + + } + } + + task "api" { + driver = "docker" + + config { + image = "${IMAGE_NAME_ENV}" + } + + resources { + memory = "100" // 100 MB RAM + cpu = "100" // 100 MHz + } + } + } +}