Skip to content

A containerized app that generates QR codes with urls as an input ,Built ,Pushed and Deployed with a CI/CD Pipeline using Docker ,Jenkins and an EKS cluseter set up with Terrafrom .This repo contains details on running this app using docker compose along with steps to deploy it on vercel and render

Notifications You must be signed in to change notification settings

hamdiz0/qr-code-generator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

67 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Qr-Code-Generator

Based on devops-qr-code

This app generates QR codes based on input URLs. It is designed to be flexible, working seamlessly in both internal environments like Kubernetes and external deployments on platforms like Vercel and Render by using NextJS routing features along with environment variables to switch between the two modes

  • Front-End built with NextJs
  • Api built with python FastApi
  • Data Base created with postgres

The user enters a url and clicks the button to send the url to the api ,the api checks if the url is present in the data-base or not :

  • if yes it retrieves the corresponding qr-code and sends it back to the user
  • if not it generates a qr-code sends it back to the user and save it in the data-base

Prerequisites :

  • Docker
  • Docker-compose
  • AWS account (Free Tier)
  • Jenkins (as a container)
  • AWS-CLI
  • Kubectl
  • Terraform

Runing the app using docker-compose :

  • make sure to set up the right enviroment variables in the .env file for the internal docker compose environmnet

    NEXT_PUBLIC_USE_INTERNAL_ROUTE=true
    NEXT_PUBLIC_INTERNAL_API=http://api ("api" is the service name for the api in the docker-compose.yml)
    
  • the external network can be used but it's not practicle for this case

    NEXT_PUBLIC_USE_INTERNAL_ROUTE=false
    NEXT_PUBLIC_EXTERNAL_API=http://localhost:3001 (the api service must be forwarded for this to work)
    
  • run the app using the Docker files in build/context folders view file here :

    docker compose up --build
    
  • run the app using the docker images from DockerHub view file here :

    docker compose up -f ./docker-compose-images.yml up
    

Deploying an EKS cluster using Terraform :

  • here is a quick setup guide on how to deploy an minimal EKS cluster using terraform :

  • after creating the cluter make sure to add an access entry for the IAM user to access the cluster

  • go to the eks console EKS>Cluster>"eks-cluster-name">IAM access entries and add the user to the cluster with the necessary permissions :

  • The Terraform configuration is divided into three files:

    • eks.tf: Contains the main configuration for the EKS cluster.
    • network.tf: Defines the network settings for the EKS cluster.
    • provider.tf: Specifies the provider configuration for AWS.

Setting up Jenkins :

  • follow this guide to set up jenkins as a container Docker in Jenkins

  • make sure docker is setup in jenkins (more details here)

  • it's preferable to use a multibranch pipeline cause of the usefull plugins and features it provides

  • add "Multibranch Scan Webhook Trigger" plugin in jenkins

  • configure a webhook in the git repo webhook settings :

    • <jenkins-url>/multibranch-webhook-trigger/invoke?token=<token>
  • more details about multibranch webhooks here

  • install the aws cli in the jenkins container :

    docker exec -it jenkins bash
    apt install unzip wget
    wget "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip"
    unzip awscli-exe-linux-x86_64.zip
    sudo ./aws/install
  • configure the aws cli with the credentails of the IAM user used to cretae the EKS cluster or add a new user for jenkins with right permissions :

    aws configure
  • verify the configuration :

    aws sts get-caller-identity
  • install kubectl in the jenkins container :

    K8S_VERSION=1.32
    apt-get update
    apt-get install --quiet --yes apt-transport-https ca-certificates curl
    curl -fsSL https://pkgs.k8s.io/core:/stable:/v${K8S_VERSION}/deb/Release.key | \
    gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
    echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v${K8S_VERSION}/deb/ /" | \
    tee /etc/apt/sources.list.d/kubernetes.list
    apt-get update
    apt-get install --quiet --yes kubectl
  • update the kubeconfig file :

    aws eks --region <region> update-kubeconfig --name <cluster-name>

YAML files :

  • set up a deployment with its corresponding service for each component of the app

CI/CD Pipeline :

CI Pipeline :

Building and Pushing the images :

  • utilized two Function Templates to build and push the images
    • hamdiz0/qr-front:latest
    • hamdiz0/qr-api:latest
    • postgres:15-alpine (default)

Changing the YAML files iamge verion :

  • utilized a script to change the demployment image version change_version.sh
  • in the update version stage, Jenkins runs the script to change both the front-end and api image versions
    script {
      sh """
        cd k8s-manifests
        chmod +x change_version.sh
        ./change_version.sh -v $VERSION
      """
    }

Pushing the version change :

  • set up jenkins to update the git repository with new version
  • set up a git user.name and user.eamil for Jenkins :
    docker exec -it jenkins bash
    git config --global user.name "jenkins"
    git config user.email "jenkins@jenkins.com"
    
  • ustilized a function that adds and pushs changes to a git repository
    • view the function here
  • the function uses a git access token wish must be configured and added to jenkins as a Username and Password credential
    • set up an access token in git hub :
  • make sure to add the Ignore Commiter Strategy plugin and ignore jenkins pushes to avoid infinite build loops :
  • example of using the function :
    gs.git_push(
        'github.com/hamdiz0/qr-code-generator',     // url without "https://"
        'github-api-token',                         // credentialsId
        "updated to version ${VERSION}",            // commit message
        'main'                                      // branch
    )

CD Pipeline :

  • after the updated version stage the deploy stage is triggered
  • the deploy stage runs the deploy.sh script wich applies the changes to the EKS cluster :
    script {
      sh """
          export KUBECONFIG=$KUBECONFIG  // eks kubeconfig's absolute path in the jenkins container
          cd k8s-manifests               // change directory to the yaml files directory
          chmod +x deploy.sh             // make the script executable
          ./deploy.sh                    // run the script
      """
    }
  • the yaml files must be in the same directory as the script

Deploying the app using render and vercel :

deploying the front end on vercel :

  • create a new project on vercel and link the gitub repo hosting the front end

  • choose the right directory containing the front end files

  • make sure to select the NextJs framework

  • add the necessary environment variables for the external routing mode in Settings/Environment Varaibles

    NEXT_PUBLIC_USE_INTERNAL_ROUTE=true
    NEXT_PUBLIC_EXTERNAL_API=an external api url "https://api.onrender.com"
    

deploying both the api and postgres db on render :

Setting a Postgres data base :

  • create a new webservice
  • make sure to select the nearest region
  • add all the needed information

Setting up the API :

  • create a new webservice
  • make sure to select the nearest region
  • select python as the language

  • add the Start command :
    uvicorn main:app --host  0.0.0.0 --port 80
    
  • add the environment variables along with their values from the postgres service
    CORS_ORIGIN         // "*" to allow all traffic or set a specific url
    POSTGRES_HOST       // Hostname value from info/connections
    POSTGRES_DB         // Database value from info/connections
    POSTGRES_USER       // Username value from info/connections
    POSTGRES_PASSWORD   // Password value from info/connections
    

  • the required values are present in the connections part of the postgres db info tab

Results :

EKS deployment :

Vercel and Render deployment :

Checkout my LearningDevops repo for more details about these tools and devops in general do not hesitate to contribute

About

A containerized app that generates QR codes with urls as an input ,Built ,Pushed and Deployed with a CI/CD Pipeline using Docker ,Jenkins and an EKS cluseter set up with Terrafrom .This repo contains details on running this app using docker compose along with steps to deploy it on vercel and render

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published