Streamlining CI/CD Pipelines with Hasura GraphQL Engine
Qasim Aziz
Posted on February 20, 2024
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
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:
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
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
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.
Posted on February 20, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.