App Deployment With GitLabCI
DEPLOYING WITH GITLAB-CI
Prerequisites
- Gitlab account
A little intro…
Connected to the gitlab instance are runners, which are responsible for executing the pipelines. Here, i’m using a self managed gitlab instance. Following the concept of configuration as code, the pipeline will be written in code and hosted in the applications git repository in a yaml file called .gitlab-ci.yaml.
For this article i’m using a docker container for my execution environment, so the jobs will run inside a container, learn more here. The runner is installed on a machine and on that machine gitlab runner creates docker machines to run the jobs.
.gitlab-ci.yaml
The tasks in a CI/CD pipeline such as running tests, building images, deploying to a server are configured as jobs in a .gitlab-ci.yaml file.
variables:
IMAGE_NAME: seriki/my-app
IMAGE_TAG: $CI_PIPELINE_ID
stages:
- test
- build
- deploy
test:
stage: test
image:
name: node:11.10.1
script:
- cd app
- npm install
- npm run test
build_image:
stage: build
image: docker:20
before_script:
- echo "$CI_REGISTRY_PASS" | docker login -u $CI_REGISTRY_USER --password-stdin
script:
- docker build -t $IMAGE_NAME:$IMAGE_TAG .
- docker push $IMAGE_NAME:$IMAGE_TAG
- docker image rm $IMAGE_NAME:$IMAGE_TAG
deploy:
stage: deploy
image:
name: alpine/k8s:1.26.0
entrypoint: [""]
before_script:
- cp $KUBE_CA /tmp/ca.crt
- cp $KUBE_CLIENT_CERT /tmp/client.crt
- cp $KUBE_CLIENT_KEY /tmp/client.key
- curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
- cd k8s
script:
- kubectl config get-contexts
- kubectl get pods
- kustomize edit set image $IMAGE_NAME=$IMAGE_NAME:$IMAGE_TAG
- kubectl apply -k .
Stages
The jobs are configured in stages, without stages our jobs will attempt to run at the same time, this is way to tell the pipeline in what order we want the jobs to run.
stages:
- test
- build
- deploy
Test-Job
A job that will run our tests called “test”, inside the job we configure a script where we tell the job what commands to execute, here the script goes into the app directory, installs npm and runs the test.
test:
stage: test
image:
name: node:11.10.1
script:
- cd app
- npm install
- npm run test
Build-job
before_script is the same as a script, also has the same syntax, but the runner knows to run the before_script before running the script. Here, i’ll need to log into my docker account before building and pushing the image.
build_image:
stage: build
image: docker:20
before_script:
- echo "$CI_REGISTRY_PASS" | docker login -u $CI_REGISTRY_USER --password-stdin
script:
- docker build -t $IMAGE_NAME:$IMAGE_TAG .
- docker push $IMAGE_NAME:$IMAGE_TAG
- docker image rm $IMAGE_NAME:$IMAGE_TAG
Deploy-job
The deploy job is going to deploy the application to kubernetes(minikube cluster) as configured in the script.Here, before the main script runs, there’s also a before script, which is going to copy kubernetes certificates to a temporary location. This way, the job has the permission to carry out the task we are instructing it to in the main script.
deploy:
stage: deploy
image:
name: alpine/k8s:1.26.0
entrypoint: [""]
before_script:
- cp $KUBE_CA /tmp/ca.crt
- cp $KUBE_CLIENT_CERT /tmp/client.crt
- cp $KUBE_CLIENT_KEY /tmp/client.key
- curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
- cd k8s
script:
- kubectl config get-contexts
- kubectl get pods
- kustomize edit set image $IMAGE_NAME=$IMAGE_NAME:$IMAGE_TAG
- kubectl apply -k .
see also: App Deployment With Kubernetes, see also: App Deployment With Docker