CI/CD GitLab
The following Dockerfile sets up a "Fortune Cookie" server using the fortune and cowsay commands. It generates humorous and random sayings.
FROM debian:stable-slim RUN apt-get update && apt-get install -y cowsay fortune COPY entrypoint.sh / ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh:
#!/bin/bash if [ $# -eq 0 ]; then /usr/games/fortune | /usr/games/cowsay else /usr/games/cowsay "$@" fi
The script checks if the number of command-line arguments, represented by $#, is equal to 0 (no arguments). If that's the case, /usr/games/fortune | /usr/games/cowsay line is executed. It generates a random saying or fortune using the /usr/games/fortune command and then pipes (|) that output to the /usr/games/cowsay command. The result is a humorous message or saying displayed as a cow with a speech bubble.
If there are command-line arguments provided when running the script, this section of the script is executed. In this case, /usr/games/cowsay "$@"line meams it runs the /usr/games/cowsay command and passes all the command-line arguments provided to the script as arguments to the cowsay command. This allows us to customize the message that the cow displays based on the provided arguments.
Build the image and run a container on local:
$ docker build -t bogo-fortunes . $ docker run bogo-fortunes ______________________________________ / Having nothing, nothing can he lose. \ | | \ -- William Shakespeare, "Henry VI" / -------------------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || $ docker run bogo-fortunes bogotobogo ____________ < bogotobogo > ------------ \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
In this section, we'll build a docker image and push it to Docker Hub via CI/CD pipeline. First, we need to create a project:
clone: git clone https://<token-name>:<token-value>@gitlab.com/<group-id><project>
$ git clone https://bogoPilot:glpat-D8bVhwMSxkGsmU3sryzj@gitlab.com/bogotobogo/BogoPilot.git Cloning into 'BogoPilot'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (3/3), done.
To automate the build and deployment of our Docker image, we can create a .gitlab-ci.yml file in our GitLab repository. This file defines the CI/CD pipeline.
.gitlab-ci.yml:
docker-build: image: docker:latest stage: build services: - docker:dind: before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - docker build --pull -t $CI_REGISTRY_IMAGE . - docker push $CI_REGISTRY_IMAGE only: - main
The line image: docker:latest specifies the Docker image to be used for the environment of this job. In this case, it's using the "docker:latest" image, which provides Docker functionality within the job.
The services: keyword is used to define services that are needed for the job to run. Services are additional containers that are started alongside our job's container and provide certain functionalities.
The docker:dind: is the specific service we're defining. docker:dind stands for "Docker in Docker" and is a common service used in CI/CD pipelines. It means that a separate Docker container running Docker itself (i.e., Docker within Docker) will be started alongside our job's container. This is particularly useful if our CI/CD job needs to build or work with Docker images. The service allows our job to interact with Docker, build Docker images, and run containers within our job's container. The docker:dind service provides a self-contained Docker environment within our CI/CD job's environment, which is important for tasks like building Docker images, running containers, and interacting with Docker-related operations. In summary, by specifying services: - docker:dind in our GitLab CI/CD pipeline configuration, we're ensuring that a Docker-in-Docker service is made available to our job, allowing our CI/CD job to work with Docker as if it were running on a machine with Docker installed.
Note that we need to set variables: Settings >> CI/CD >> Variables. In my case, $CI_REGISTRY_USER = dockerbogo, $CI_REGISTRY_PASSWORD = Access_token, $CI_REGISTRY = docker.io, $CI_REGISTRY_IMAGE = dockerbogo/bogo_fortunes
We can create the Access_token from "Account Settings":
After login in to the Docker Hub, the docker build --pull -t $CI_REGISTRY_IMAGE . ensures (by the --pull flag) that the base image used in the Dockerfile is always up-to-date and the -t flag is used to specify the name and optionally a tag for the image being built. In this case, the image will be tagged with the name dockerbogo/bogo_fortunes which is the format for the tag is typically repository_name/image_name. docker build is the command to build a Docker image. It instructs Docker to create an image based on the instructions provided in a Dockerfile. The dot (.) at the end of the command specifies the build context. It tells Docker to look for a Dockerfile in the current directory (the directory where we're running the docker build command). The Dockerfile contains the instructions for building the image, and it should be present in the same directory.
Ref: Authenticate with registry in Docker-in-Docker
The .gitlab-ci.yml file will automatically trigger a GitLab CI/CD pipeline when we push code to our GitLab repository. GitLab CI/CD is configured to respond to certain events, including code pushes. Here's how it typically works:
- When we push code changes to our GitLab repository, GitLab automatically detects the push event.
- If our repository contains a .gitlab-ci.yml file in the root directory, GitLab CI/CD reads the configuration defined in that file.
- Based on the configuration, GitLab CI/CD creates and starts a pipeline for our project.
- The pipeline runs through a series of stages and jobs, as defined in our .gitlab-ci.yml. These jobs can include tasks like building, testing, and deploying our code.
- We can monitor the progress of the pipeline, view job logs, and check for any errors or issues in the GitLab CI/CD section of our GitLab project.
$ git add .gitlab-ci.yml Dockerfile entrypoint.sh $ git commit -m "adding Dockerfile and .gitlab-ci.yml" $ git push
We can see GitLab CI/CD pipeline was automatically triggered:
We can check the image has been built and pushed to docker.io:
DevOps
DevOps / Sys Admin Q & A
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization