<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Qasim Aziz</title>
    <description>The latest articles on DEV Community by Qasim Aziz (@qasimaziz).</description>
    <link>https://dev.to/qasimaziz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1286776%2F05499ce1-646e-4f9f-a3f5-dba2de417c9a.jpeg</url>
      <title>DEV Community: Qasim Aziz</title>
      <link>https://dev.to/qasimaziz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/qasimaziz"/>
    <language>en</language>
    <item>
      <title>Setting Up DevOps Monitoring and Automation with Jenkins, Prometheus, Grafana, and Docker</title>
      <dc:creator>Qasim Aziz</dc:creator>
      <pubDate>Thu, 25 Jul 2024 09:49:25 +0000</pubDate>
      <link>https://dev.to/qasimaziz/setting-up-devops-monitoring-and-automation-with-jenkins-prometheus-grafana-and-docker-g5p</link>
      <guid>https://dev.to/qasimaziz/setting-up-devops-monitoring-and-automation-with-jenkins-prometheus-grafana-and-docker-g5p</guid>
      <description>&lt;p&gt;In this guide, we'll explore how to create a DevOps monitoring and automation system using Jenkins for CI/CD, Prometheus for metrics collection, Grafana for data visualization, and Docker for containerization.&lt;/p&gt;

&lt;p&gt;Installing Docker&lt;br&gt;
First, ensure Docker is installed on your system. Follow the installation instructions provided on the Docker website for your specific operating system.&lt;/p&gt;

&lt;p&gt;Setting Up Jenkins&lt;br&gt;
To run Jenkins in a Docker container, execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -u 0 --privileged --name jenkins -it -d -p 8080:8080 -p 50000:50000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(which docker):/usr/bin/docker \
-v /home/jenkins_home:/var/jenkins_home \
jenkins/jenkins:latest

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access and Configure Jenkins&lt;br&gt;
Open your browser and navigate to &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;.&lt;br&gt;
Provide the initial admin password, which can be found by running docker logs .&lt;br&gt;
Install the suggested plugins during the initial setup.&lt;br&gt;
From the Jenkins dashboard, create a new item and choose "Pipeline".&lt;/p&gt;

&lt;p&gt;Install Required Plugins&lt;br&gt;
Navigate to "Manage Jenkins" &amp;gt; "Manage Plugins" and install the following plugins:&lt;/p&gt;

&lt;p&gt;Docker Plugin&lt;br&gt;
Docker Pipeline Plugin&lt;br&gt;
Prometheus Metrics Plugin&lt;br&gt;
Restart Jenkins if prompted.&lt;/p&gt;

&lt;p&gt;Setting Up Prometheus and Grafana&lt;br&gt;
Create a Docker Network&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker network create monitoring

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run Prometheus&lt;br&gt;
Create a prometheus.yml configuration file with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'jenkins'
    static_configs:
      - targets: ['jenkins:8080']
      metrics_path: '/prometheus'

  - job_name: 'node'
    static_configs:
      - targets: ['node-exporter:9100']

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run Prometheus with this configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d --name=prometheus --network=monitoring -p 9090:9090 \
-v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run Node Exporter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d --name=node-exporter --network=monitoring --restart=unless-stopped prom/node-exporter

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run Grafana&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d --name=grafana --network=monitoring -p 3000:3000 grafana/grafana

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configuring Grafana&lt;br&gt;
Access Grafana&lt;br&gt;
Open your browser and go to &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;. Log in with the default credentials (username: admin, password: admin).&lt;/p&gt;

&lt;p&gt;Add Prometheus as a Data Source&lt;br&gt;
Navigate to "Data Sources" on the left sidebar, click "Add data source," and select "Prometheus".&lt;br&gt;
Enter &lt;a href="http://prometheus:9090" rel="noopener noreferrer"&gt;http://prometheus:9090&lt;/a&gt; as the Prometheus server URL.&lt;br&gt;
Click "Save &amp;amp; Test".&lt;br&gt;
Create a Dashboard&lt;br&gt;
Select "Dashboards" from the left sidebar to create a new dashboard.&lt;br&gt;
Import a dashboard using an ID or URL (e.g., ID: 11159).&lt;br&gt;
Add a query to visualize Jenkins job duration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;default_jenkins_builds_last_build_duration_milliseconds

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Automating Application Deployment with Jenkins&lt;br&gt;
Set Up a Jenkins Pipeline&lt;br&gt;
From your Jenkins dashboard, navigate to your pipeline project, go to "Configure," and add the following script under "Pipeline Script":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pipeline {
    agent any

    environment {
        DB_HOST = 'your-db-host'
        DB_USER = 'your-db-user'
        DB_PASS = 'your-db-password'
        DB_NAME = 'your-db-name'
    }

    stages {
        stage('Checkout') {
            steps {
                script {
                    checkout([$class: 'GitSCM', branches: [[name: '*/main']],
                      doGenerateSubmoduleConfigurations: false,
                      extensions: [[$class: 'CleanCheckout']],
                      submoduleCfg: [],
                      userRemoteConfigs: [[url: 'https://github.com/yourusername/your-nodejs-typescript-api-repo.git',
                      credentialsId: 'git-credentials-id']]
                    ])
                }
            }
        }

        stage('Install Dependencies') {
            steps {
                sh 'npm install'
            }
        }

        stage('Build') {
            steps {
                sh 'npm run build'
            }
        }

        stage('Test') {
            steps {
                sh 'npm test'
            }
        }

        stage('Build Docker Image') {
            steps {
                script {
                    sh 'docker build -t your-dockerhub-username/your-nodejs-typescript-api:latest .'
                }
            }
        }

        stage('Push Docker Image') {
            steps {
                script {
                    withCredentials([usernamePassword(credentialsId: 'dockerhub-credentials', usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) {
                        sh 'echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin'
                    }
                    sh 'docker push your-dockerhub-username/your-nodejs-typescript-api:latest'
                }
            }
        }

        stage('Deploy') {
            steps {
                script {
                    sh '''
                    docker run -d -p 3000:3000 \
                        -e NODE_ENV=$NODE_ENV \
                        -e DB_HOST=$DB_HOST \
                        -e DB_USER=$DB_USER \
                        -e DB_PASS=$DB_PASS \
                        -e DB_NAME=$DB_NAME \
                        your-dockerhub-username/your-nodejs-typescript-api:latest
                    '''
                }
            }
        }

        stage('Monitor') {
            steps {
                script {
                    // Additional monitoring setup can be added here
                }
            }
        }
    }

    post {
        success {
            echo 'Build succeeded!'
        }
        failure {
            echo 'Build failed!'
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding Credentials&lt;br&gt;
Add credentials for GitHub and Docker in Jenkins:&lt;/p&gt;

&lt;p&gt;Navigate to "Manage Jenkins" &amp;gt; "Credentials".&lt;br&gt;
Select "Global" and add your credentials for GitHub and Docker. Note the ID, as it will be referenced in the pipeline script.&lt;br&gt;
By following these steps, you can set up a comprehensive DevOps monitoring and automation tool using Jenkins, Prometheus, Grafana, and Docker.&lt;br&gt;
Build Application&lt;br&gt;
Build your application and view the metrics on the Grafana dashboard 😃.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo9yzo7ak6kxqgzq9ta1y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo9yzo7ak6kxqgzq9ta1y.png" alt="Image description" width="747" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>monitoring</category>
      <category>docker</category>
      <category>containers</category>
    </item>
    <item>
      <title>Streamlining CI/CD Pipelines with Hasura GraphQL Engine</title>
      <dc:creator>Qasim Aziz</dc:creator>
      <pubDate>Tue, 20 Feb 2024 12:42:31 +0000</pubDate>
      <link>https://dev.to/qasimaziz/streamlining-cicd-pipelines-with-hasura-graphql-engine-78l</link>
      <guid>https://dev.to/qasimaziz/streamlining-cicd-pipelines-with-hasura-graphql-engine-78l</guid>
      <description>&lt;p&gt;In the dynamic landscape of API management, the perennial debate surrounding architectural choices - whether it's gRPC, traditional HTTP, or the revolutionary GraphQL - remains ever-present. Drawing from a wealth of experience amassed over years in the tech industry, one conclusion stands out: GraphQL, with its unparalleled performance and precision, emerges as the optimal solution for real-world scenarios.&lt;br&gt;
Unleashing the Power of GraphQL.&lt;/p&gt;

&lt;p&gt;What sets GraphQL apart is its innate ability to deliver exactly what is needed, precisely when it's needed. Unlike traditional HTTP endpoints, where retrieving data often entails fetching entire objects and sifting through unwanted information, GraphQL empowers developers to fetch only the necessary details, significantly streamlining the process. Imagine a scenario where you're dealing with massive datasets but require only specific fields - GraphQL's fine-grained control ensures you retrieve precisely what's required, enhancing efficiency and performance manifold.&lt;/p&gt;

&lt;p&gt;Embracing Hasura: The Game-Changer in GraphQL Implementation&lt;br&gt;
Enter Hasura - a transformative force in the realm of GraphQL. With its comprehensive feature set and intuitive interface, Hasura simplifies schema creation and management, making it the go-to choice for developers seeking simplicity without compromising on power. The Hasura CLI facilitates seamless migration management, empowering teams to deploy with confidence and ease.&lt;/p&gt;

&lt;p&gt;Automating CI/CD Pipelines: A Custom Solution with GitLab, Docker, and Kubernetes&lt;/p&gt;

&lt;p&gt;Now, let's dive into the heart of the matter: automating CI/CD pipelines for Hasura. I'll guide you through a custom solution tailored to seamlessly integrate with your preferred pipeline tools, leveraging the robust capabilities of GitLab, Docker, and Kubernetes to ensure high availability and scalability.&lt;/p&gt;

&lt;p&gt;Setting the Stage&lt;br&gt;
Firstly, let's establish a dedicated repository to manage Hasura metadata and migrations. Initiate your project with the Hasura CLI and utilize the console to generate database schemas and migrations effortlessly. Ensure you have the necessary prerequisites in place:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hasura CLI&lt;/li&gt;
&lt;li&gt;Docker installed&lt;/li&gt;
&lt;li&gt;Docker Compose&lt;/li&gt;
&lt;li&gt;Git repository&lt;/li&gt;
&lt;li&gt;Git Helm chart repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;https://git.opshive.io/myproject/hasura.git&lt;/code&gt;&lt;br&gt;
Run hasura init to create the project directory, guiding you through the initial setup process and allowing you to configure basic settings locally.&lt;br&gt;
Crafting the Environment&lt;br&gt;
Next, let's configure the Dockerfile at the root of your project to facilitate container creation and automated migration processing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM hasura/graphql-engine:v2.27.0.cli-migrations-v3

RUN mkdir /app
WORKDIR /appd

COPY ./myproject /app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, prepare a Docker Compose file to orchestrate multiple containers and the database, ensuring seamless integration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3.6"
services:
  graphql-engine:
    build: 
      context: ./
      dockerfile: Dockerfile 
    # image: hasura/graphql-engine:v2.27.0.cli-migrations-v3
    ports:
      - "8080:8080"
    restart: always
    environment:
      HASURA_GRAPHQL_MIGRATIONS_DIR: /app/migrations
      HASURA_GRAPHQL_METADATA_DIR: /app/metadata
      ## postgres database to store Hasura metadata
      ## this env var can be used to add the above postgres database to Hasura as a data source. this can be removed/updated based on your needs
      HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgres@postgres:5432/myproject
      ## enable the console served by server
      HASURA_GRAPHQL_ENABLE_CONSOLE: "true" # set to "false" to disable console
      ## enable debugging mode. It is recommended to disable this in production
      HASURA_GRAPHQL_DEV_MODE: "true"
      HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log
      ## uncomment next line to run console offline (i.e load console assets from server instead of CDN)
      # HASURA_GRAPHQL_CONSOLE_ASSETS_DIR: /srv/console-assets
      ## uncomment next line to set an admin secret
      HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey
  postgres:
    image: postgres:14.1-alpine
    container_name: pg_db
    restart: always
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports:
      - '5432:5432'
    volumes:
      - postgresql:/var/lib/postgresql/data
  pgadmin:
    container_name: pgadmin_container-new
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL:-pgadmin4@pgadmin.org}
      PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD:-admin}
      PGADMIN_CONFIG_SERVER_MODE: 'False'
    volumes:
       - pgadmin:/var/lib/pgadmin
      #  - /home/opshive/workspace/qasim/storage/projects/fabmedic/hasura/pg_backups:/tmp
    ports:
      - "${PGADMIN_PORT:-5050}:80"
volumes:
  postgresql:
    driver: local
  pgadmin:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup enables you to launch all containers and access the Hasura console for schema creation and management locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up -d
cd myproject 
hasura console --endpoint=localhost:8080 --admin-secret=myadminsecretkey
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Automating Deployment: A GitLab CI/CD Pipeline&lt;br&gt;
With the foundation laid, it's time to automate deployment to your development server. Create a .gitlab-ci.yml file at the root of your project with the following content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;image: docker:latest
stages:
  - docker-build-dev
  - patch-dev

docker-build-dev:
  stage: docker-build-dev

  services: 
    - name: docker:dind    
  before_script:
    - docker login -u "$DOCKER_USER" -p "$DOCKER_PASSWORD" "docker.io"
  script:
    - docker build . -t "$DEV_IMAGE_NAME":"$CI_COMMIT_SHA" 
    - docker push "$DEV_IMAGE_NAME":"$CI_COMMIT_SHA"

  tags:
    - my-runner
  only:
    - dev

patch-dev:
  stage: patch-dev
  script:
    - |
      apk add git
      git clone -b main $HELM_REPO
      cd helm-charts/myproject-hasura
      git config credential.helper store
      rm -f dev-values.yaml   
      cat &amp;lt;&amp;lt;EOF &amp;gt;&amp;gt; dev-values.yaml
      replicaCount: 1

      image:
        repository: $DEV_IMAGE_NAME
        pullPolicy: IfNotPresent
        # Overrides the image tag whose default is the chart appVersion.
        tag: "$CI_COMMIT_SHA"

      imagePullSecrets:
      - name: mypullsecret
      nameOverride: ""
      fullnameOverride: "hasura-dev"

      serviceAccount:
        # Specifies whether a service account should be created
        create: true
        # Annotations to add to the service account
        annotations: {}
        # The name of the service account to use.
        # If not set and create is true, a name is generated using the fullname template
        name: ""

      podAnnotations: {}

      podSecurityContext: {}
        # fsGroup: 2000

      securityContext: {}
        # capabilities:
        #   drop:
        #   - ALL
        # readOnlyRootFilesystem: true
        # runAsNonRoot: true
        # runAsUser: 1000

      service:
        type: ClusterIP
        port: 8080

      ingress:
        enabled: true
        className: "nginx"
        annotations:
          kubernetes.io/ingress.class: nginx
          kubernetes.io/tls-acme: "true"
          nginx.ingress.kubernetes.io/proxy-body-size: 100m
          cert-manager.io/cluster-issuer: letsencrypt-mydomain-issuer-dns
        hosts:
          - host: dev-hasura.mydomain.io
            paths:
              - path: /
                pathType: ImplementationSpecific
        tls:
          - secretName: domain-hasura-tls
            hosts:
            - dev-hasura.mydomain.com
        # livenessProbe:
        #   httpGet:
        #     path: /
        #     port: http
        # readinessProbe:
        #   httpGet:
        #     path: /
        #     port: http
      resources: 
        # We usually recommend not to specify default resources and to leave this as a conscious
        # choice for the user. This also increases chances charts run on environments with little
        # resources, such as Minikube. If you do want to specify resources, uncomment the following
        # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
        limits:
          cpu: 1000m
          memory: 800Mi
        requests:
          cpu: 250m
          memory: 128Mi

      autoscaling:
        enabled: false
        minReplicas: 1
        maxReplicas: 3
        targetCPUUtilizationPercentage: 80
        # targetMemoryUtilizationPercentage: 80

      nodeSelector: {}

      tolerations: []

      affinity: {}
      # configmaps
      HASURA_GRAPHQL_DATABASE_URL: "postgresql://user:securepassword@postgresql-server:5432/devmyproject"
      HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
      HASURA_GRAPHQL_DEV_MODE: "false"
      HASURA_GRAPHQL_ADMIN_SECRET: "ASD78F5ASD95FGAS8765GSD6F9S7F69ASD78"
      HASURA_GRAPHQL_ENABLE_ALLOWLIST: "false"
      HASURA_GRAPHQL_ENABLED_LOG_TYPES: "startup,http-log,query-log,websocket-log,webhook-log"
      HASURA_GRAPHQL_UNAUTHORIZED_ROLE: "anonymous"

      HASURA_GRAPHQL_CORS_DOMAIN: "*"

      EOF
      git config --global user.email "bot@mycompany.com"
      git config --global user.name "bot"
      git add .
      git commit -m "$CI_COMMIT_SHA"
      git push origin main
  tags:
    - my-runner
  only:
    - dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By following these meticulously crafted steps, you'll seamlessly integrate Hasura GraphQL Engine into your CI/CD workflows, fostering efficiency, reliability, and scalability throughout the development lifecycle.&lt;/p&gt;




&lt;p&gt;This comprehensive guide empowers developers to harness the full potential of GraphQL with Hasura while streamlining CI/CD processes for unparalleled efficiency and agility.&lt;/p&gt;

</description>
      <category>hasura</category>
      <category>cicd</category>
      <category>gitops</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
