Continuous Integration with GitLab at 10,000 Feet
Learn how to build, test, and deploy a containerized Flask app with GitLab CI/CD.
- build - create a test container with a Python Flask application
- test - performs a unit test on the container
- release - the test container is tagged for release
Note: The example demonstrates Continuous Integration concepts and takes a short cut when handling secrets, such as API keys to external services. The best practice is to store secrets in a vault or key store and configure GitLab to retrieve the key during the build process. Establishing and adding a key store is beyond the scope of this example.
To use GitLab CI/CD, you need:
- a GitHub account and a personal access token
- a "Pay as you call" API key from openweather.org
- a validated public GitLab account*
*Note: To use free CI/CD minutes on shared runners, you'll need to validate your account with a credit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. GitLab will not charge your card, it will only be used for validation.
Caution: Use the public GitLab service to ensure thedocker:dind
service for building and testing containers is available.
api_key
with your key. Note that you will incur charges if the application exceeds 1,000 API calls per day..gitlab-ci.yml
file which defines the pipeline..gitlab-ci.yml
defines the stages and the order of execution of the stages. The pipeline will build a Docker image, run a unit test on the image, and releases the image when it passes the test.1
2
3
4
stages:
- build
- test
- release
dind
).1
2
3
image: docker:latest
services:
- docker:dind
build_job
script defines the tasks:- logging into the GitLab registry
- building the image from the Dockerfile
- tagging the image as test
- pushing the image to the GitLab image repository
1
2
3
4
5
6
build_job:
stage: build
script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- docker build --tag $CI_REGISTRY_IMAGE:test .
- docker push $CI_REGISTRY_IMAGE:test
Note that the script uses GitLab predefined variables that contain the values about the pipeline or the job required by the script when the pipeline is triggered. GitLab provides a reference of predefined variables.
build_job
to see the build log.1
2
3
4
5
test_job:
stage: test
script:
- docker pull $CI_REGISTRY_IMAGE:test
- docker run $CI_REGISTRY_IMAGE:test /app/test.py
1
2
3
4
5
6
7
release_job:
stage: release
script:
- docker login -u "GITLAB-CI-TOKEN" -p "$CI_BUILD_TOKEN" $CI_REGISTRY
- docker pull $CI_REGISTRY_IMAGE:test
- docker tag $CI_REGISTRY_IMAGE:test $CI_REGISTRY_IMAGE:latest
- docker push $CI_REGISTRY_IMAGE:latest
Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.