Day 13 of my 90-Devops project: Setting Up a CI/CD Pipeline with Docker and Kubernetes on GitLab

Day 13 of my 90-Devops project: Setting Up a CI/CD Pipeline with Docker and Kubernetes on GitLab

ยท

4 min read

Prerequisites

  1. Basic Knowledge of Docker and Kubernetes

  2. GitLab Account

  3. Git Installed on Local Machine

  4. Docker Installed on Local Machine

  5. Minikube Installed on Local Machine

  6. kubectl Installed on Local Machine

Step 1: Setting Up the Project

  1. Create a Project Directory

     mkdir day13secureci
     cd day13secureci
    
  2. Initialize a Git Repository

     git init
    
  3. Create a Dockerfile

     touch Dockerfile
    

    Content of Dockerfile:

     # Use an official Node.js runtime as a parent image
     FROM node:14
    
     # Set the working directory
     WORKDIR /usr/src/app
    
     # Copy package.json and package-lock.json
     COPY package*.json ./
    
     # Install dependencies
     RUN npm install
    
     # Copy the rest of the application code
     COPY . .
    
     # Expose port 8080
     EXPOSE 8080
    
     # Run the application
     CMD ["node", "app.js"]
    
  4. Create Kubernetes Deployment and Service Files

     mkdir -p kubernetes
     touch kubernetes/deployment.yaml
     touch kubernetes/service.yaml
    

    Content of deployment.yaml:

     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: my-app-deployment
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: my-app
       template:
         metadata:
           labels:
             app: my-app
         spec:
           containers:
           - name: my-app
             image: registry.gitlab.com/your-username/your-project-name:my-app:latest
             ports:
             - containerPort: 8080
    

    Content of service.yaml:

     apiVersion: v1
     kind: Service
     metadata:
       name: my-app-service
     spec:
       selector:
         app: my-app
       ports:
         - protocol: TCP
           port: 80
           targetPort: 8080
       type: LoadBalancer
    
  5. Create GitLab CI/CD Configuration File

     touch .gitlab-ci.yml
    

    Content of .gitlab-ci.yml:

     stages:
       - build
       - test
       - deploy
    
     variables:
       DOCKER_DRIVER: overlay2
    
     before_script:
       - docker info
    
     build:
       stage: build
       script:
         - docker build -t my-app .
         - docker tag my-app:latest registry.gitlab.com/your-username/your-project-name:my-app:latest
         - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
         - docker push registry.gitlab.com/your-username/your-project-name:my-app:latest
    
     test:
       stage: test
       script:
         - docker run --rm my-app npm test
    
     deploy:
       stage: deploy
       script:
         - kubectl apply -f kubernetes/deployment.yaml
         - kubectl apply -f kubernetes/service.yaml
       environment:
         name: production
         url: http://your-app-url.com
    
  6. Create Your Application Code

    • Create a simple Node.js application:
    touch app.js

Content of app.js:

    const express = require('express');
    const app = express();
    const port = 8080;

    app.get('/', (req, res) => {
      res.send('Hello, World!');
    });

    app.listen(port, () => {
      console.log(`App running on http://localhost:${port}`);
    });

Create package.json:

    touch package.json

Content of package.json:

    {
      "name": "my-app",
      "version": "1.0.0",
      "description": "A simple Node.js app",
      "main": "app.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "dependencies": {
        "express": "^4.17.1"
      }
    }

Step 2: Setting Up GitLab

  1. Create a New Project on GitLab

    • Log in to your GitLab account and create a new project.
  2. Connect Your Local Repository to GitLab

     git remote add origin https://gitlab.com/your-username/your-project-name.git
     git add .
     git commit -m "Initial commit"
     git push -u origin master
    

Step 3: Running the Pipeline Locally

Since GitLab CI/CD runs in a CI environment and cannot directly interact with your local Minikube cluster, youโ€™ll need to simulate the pipeline locally or adjust your setup for local testing.

  1. Create a Script to Run the CI/CD Steps Locally

     touch run_pipeline.sh
    

    Content of run_pipeline.sh:

     #!/bin/bash
    
     # Set variables
     IMAGE_NAME="my-app"
     REGISTRY="registry.gitlab.com"
     USERNAME="your-username"
     PROJECT_NAME="your-project-name"
     IMAGE_TAG="${REGISTRY}/${USERNAME}/${PROJECT_NAME}:${IMAGE_NAME}"
    
     # Build Docker image
     echo "Building Docker image..."
     docker build -t ${IMAGE_NAME} .
    
     # Tag the Docker image
     echo "Tagging Docker image..."
     docker tag ${IMAGE_NAME}:latest ${IMAGE_TAG}:latest
    
     # Log in to GitLab container registry
     echo "Logging in to GitLab container registry..."
     docker login -u your-gitlab-username -p your-gitlab-password ${REGISTRY}
    
     # Push the Docker image to the registry
     echo "Pushing Docker image to registry..."
     docker push ${IMAGE_TAG}:latest
    
     # Run tests (assuming you have a test script)
     echo "Running tests..."
     docker run --rm ${IMAGE_TAG}:latest npm test
    
     # Deploy to Minikube
     echo "Deploying to Minikube..."
     kubectl apply -f kubernetes/deployment.yaml
     kubectl apply -f kubernetes/service.yaml
    
     echo "Pipeline execution completed."
    
  2. Make the Script Executable

     chmod +x run_pipeline.sh
    
  3. Run the Script

     ./run_pipeline.sh
    

Step 4: Verify Deployment on Minikube

  1. Start Minikube

     minikube start
    
  2. Check the Deployment and Service

     kubectl get deployments
     kubectl get services
    

Common Issues and Troubleshooting

  1. Dockerfile Not Found

    • Ensure the Dockerfile is in the project root directory and named correctly.
  2. Invalid Repository/Tag Format

    • Ensure you have replaced placeholder values with actual GitLab username and project name.
  3. Missing Kubernetes Files

    • Verify that kubernetes/deployment.yaml and kubernetes/service.yaml exist and have the correct content.

Final Notes

  • Ensure all paths and filenames are correct.

  • Replace all placeholder values with your actual values.

  • Follow the steps sequentially to avoid errors.

ย