DEV Community

Cover image for Streamlining CI/CD Pipelines with Hasura GraphQL Engine
Qasim Aziz
Qasim Aziz

Posted on

Streamlining CI/CD Pipelines with Hasura GraphQL Engine

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.
Unleashing the Power of GraphQL.

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.

Embracing Hasura: The Game-Changer in GraphQL Implementation
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.

Automating CI/CD Pipelines: A Custom Solution with GitLab, Docker, and Kubernetes

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.

Setting the Stage
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:

Prerequisites:

  • Hasura CLI
  • Docker installed
  • Docker Compose
  • Git repository
  • Git Helm chart repository

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

FROM hasura/graphql-engine:v2.27.0.cli-migrations-v3 RUN mkdir /app WORKDIR /appd COPY ./myproject /app 
Enter fullscreen mode Exit fullscreen mode

Additionally, prepare a Docker Compose file to orchestrate multiple containers and the database, ensuring seamless integration:

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: 
Enter fullscreen mode Exit fullscreen mode

This setup enables you to launch all containers and access the Hasura console for schema creation and management locally:

docker-compose up -d cd myproject hasura console --endpoint=localhost:8080 --admin-secret=myadminsecretkey 
Enter fullscreen mode Exit fullscreen mode

Automating Deployment: A GitLab CI/CD Pipeline
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

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 <<EOF >> 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 
Enter fullscreen mode Exit fullscreen mode

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.


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

Top comments (0)