This system exposes a GraphQL API for managing Clients and Products, backed by MongoDB and instrumented with Prometheus metrics. It leverages Docker, Kubernetes, NGINX Ingress, GitHub Actions, ArgoCD GitOps, and production-grade monitoring with Prometheus and Grafana. The project demonstrates a complete DevOps pipeline with automated deployments, container orchestration, and modern API design, built with reliability and long-term engineering practices in mind.
- π₯ Features
- π Project Structure
- π Technology Stack Overview
- β Setup & Installation
- π‘ How to Test GraphQL APIs
- π³ Docker Setup (Optional)
- βΈοΈ Kubernetes Deployment with NGINX (Optional)
- π GitOps with Argo CD (Optional)
- π€ GitHub Actions & Automated Docker Builds (Optional)
- π Monitoring with Prometheus & Grafana (Optional)
- π€ Created By
- π License
| Feature | Description |
|---|---|
| CRUD for Clients | Create, read, update, and delete client records with full validation and error handling. |
| CRUD for Products | Manage products linked to clients, with validation to ensure data consistency and integrity. |
| Field Validation | Ensures correct email format, non-empty names, positive prices, and other field constraints. |
| Nested References | Products are linked to clients, allowing relational queries and efficient data retrieval. |
| GraphiQL UI | Interactive interface to test queries and mutations, with real-time feedback for developers. |
| Feature | Description |
|---|---|
| Dockerized Services | Both API and MongoDB are containerized for consistent environments, portability, and easy deployment. |
| Kubernetes Deployment & Service | Provides automated scaling, load balancing, service discovery, and high availability for the system. |
| TLS-Secured Ingress | Routes traffic via NGINX Ingress with HTTPS, supporting self-signed or custom TLS certificates. |
| GitHub Actions CI | Continuous Integration workflow automates Docker image build, testing, and pushing on code changes. |
| ArgoCD GitOps | Automatically syncs and deploys Kubernetes manifests from Git, enabling GitOps-based deployments. |
| Feature | Description |
|---|---|
| Prometheus Metrics | Exposes a /metrics endpoint for monitoring API performance, request counts, and system health. |
| Grafana Dashboards | Visualizes metrics with customizable dashboards, alerting, and historical trend analysis. |
| Helm Installation | Prometheus and Grafana installed and configured via Helm charts, simplifying deployment and upgrades. |
The following structure is used for this project:
graphql-system-k8s-nginx-prometheus-grafana/
β
βββ .github/ # GitHub Actions workflows for building Docker images
β βββ workflows/
β βββ build-docker-image.yaml
β
βββ argocd/ # ArgoCD GitOps application configuration
β βββ application.yaml
β
βββ k8s/ # Kubernetes resource manifests
β βββ graphql-deployment.yaml
β βββ graphql-ingress-https.yaml # Official NGINX Ingress controller configuration
β βββ graphql-service.yaml
β βββ mongo-deployment.yaml
β βββ mongo-service.yaml
β
βββ nginx/ # Custom NGINX config for local/testing environments
β βββ default.conf
β βββ nginx-config.yaml
β βββ nginx-deployment.yaml
β βββ nginx-service.yaml
β
βββ node_modules/
β
βββ src/ # GraphQL API source code
β βββ config/
β β βββ db.js
β βββ graphql/ # GraphQL schema, types, models, queries, and mutations
β β βββ models/
β β β βββ Client.js
β β β βββ Product.js
β β βββ mutations/
β β β βββ ClientMutations.js
β β β βββ ProductMutations.js
β β βββ queries/
β β β βββ ClientQueries.js
β β β βββ ProductQueries.js
β β βββ schema/
β β β βββ schema.js
β β βββ types/
β β βββ ClientType.js
β β βββ MessageType.js
β β βββ ProductType.js
β βββ main/
β β βββ app.js
β βββ monitoring/ # Prometheus metrics export
β β βββ metrics.js
β β βββ prometheus&grafana.txt # Notes and configuration references for monitoring setup
β βββ seed/
β βββ seed.js
β
βββ .dockerignore
βββ .gitignore
βββ Dockerfile
βββ docker-compose.yml # Local multi-service setup
βββ LICENSE
βββ README.md
βββ server.js
βββ package.json # Dependencies & scripts
The following technologies are used in this project:
| Layer | Technology | Description |
|---|---|---|
| API Backend | Node.js, Express, express-graphql, GraphQL | Handles all API requests and exposes GraphQL endpoints |
| Database | MongoDB, Mongoose | Stores client and product data with schema modeling |
| Containerization | Docker, docker-compose | Packages application services for portable deployment |
| Orchestration | Kubernetes | Manages, scales, and runs containers in clusters |
| Ingress Controller | NGINX Ingress | Routes external traffic into the cluster with TLS |
| DevOps Workflow | GitHub Actions | Automates Docker image build and CI pipeline |
| GitOps Automation | ArgoCD | Syncs deployments to cluster using GitOps flow |
| Monitoring | Prom-client, Prometheus, Grafana (Helm) | Collects metrics and visualizes system performance |
Follow these steps to run the project locally using Docker:
git clone https://github.com/PAIshanMadusha/graphql-system-k8s-nginx-prometheus-grafana.gitcd graphql-system-k8s-nginx-prometheus-grafanaThis project can run locally with Docker. Make sure you have Docker Desktop (or Docker Engine) running on your system.
docker-compose up --buildIf everything is configured correctly, check each container's logs in Docker Desktop or your terminal. You should see output similar to:
MongoDB Connected Successfully!
Server is running on port: 4000
Docker or Kubernetes Pod Name: {docker-hostname}π Test the App: Visit: http://localhost:4000
You can test the APIs by navigating to http://localhost:4000/graphql, which will open the GraphiQL UI. From there, you can test the queries and mutations shown below.
mutation{
addClient(name: "test", email: "test@test.com", phone: "0000000000", address: "test"){
message
client{
id
name
email
phone
address
}
}
}mutation{
addProduct(name: "test", brand: "test", description: "test", price: 10.10, clientId: "real-client-id"){
message,
product{
id
name
brand
description
price
client{
id
name
email
phone
address
}
}
}
}{
clients{
id
name
email
phone
address
}
}{
products{
id
name
brand
description
price
client{
id
name
email
phone
address
}
}
}{
client(id: "real-client-id"){
id
name
email
phone
address
}
}{
product(id: "real-product-id"){
id
name
brand
description
price
client{
id
name
email
phone
address
}
}
}mutation{
updateClient(id: "real-client-id", name: "test2", email: "test2@test.com", phone: "1111111111", address: "test2"){
message
client{
id
name
email
phone
address
}
}
}mutation{
updateProduct(id: "real-product-id", name: "test2", brand: "test2", description: "test2", price: 20.20){
message
product{
id
name
brand
description
price
client{
id
name
email
phone
address
}
}
}
}mutation{
deleteClient(id: "real-client-id"){
message
client{
id
name
email
phone
address
}
}
}mutation{
deleteProduct(id: "real-product-id"){
message
product{
id
name
brand
description
price
}
}
}These steps allow you to build your own Docker image or pull the pre-built image for testing with Kubernetes and Argo CD.
Official Docker Image:
ishanmadusha/graphql-system-k8s-nginx-prometheus-grafana:latest
docker pull ishanmadusha/graphql-system-k8s-nginx-prometheus-grafana:latestIf you want to build a custom image, update the image name inside: graphql-system-k8s-nginx-prometheus-grafana/k8s/graphql-deployment.yaml
docker build -t <your-username>/graphql-system-k8s-nginx-prometheus-grafana:latest .docker push <your-username>/graphql-system-k8s-nginx-prometheus-grafana:latestMake sure Minikube or a Kubernetes cluster is running before deployment: π https://minikube.sigs.k8s.io/docs
| File | Description |
|---|---|
| graphql-deployment.yaml | Main GraphQL application Deployment (4 replicas for HA + load balancing) |
| graphql-service.yaml | ClusterIP Service exposing the GraphQL app internally on port 4000 |
| graphql-ingress-https.yaml | NGINX Ingress with HTTPS (self-signed cert supported via TLS Secret) |
| mongo-deployment.yaml | MongoDB Deployment (single pod, uses emptyDir for ephemeral storage) |
| mongo-service.yaml | Internal ClusterIP Service for MongoDB at mongo-service:27017 |
| File | Description |
|---|---|
| default.conf | Raw NGINX config for local or standalone container routing |
| nginx-config.yaml | Converts the config into ConfigMap for Kubernetes use |
| nginx-deployment.yaml | Test NGINX Deployment referencing ConfigMap |
| nginx-service.yaml | ClusterIP service for NGINX test instance |
β οΈ This directory is for testing only.
Production routing is handled by the official
Ingress-NGINX controller, configured ingraphql-ingress-https.yaml.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt -subj "/CN=localhost/O=localhost"kubectl create secret tls localhost-tls --key localhost.key --cert localhost.crtkubectl apply -f k8s/https://localhost/graphqlkubectl port-forward svc/graphql-system-k8s-nginx-prometheus-grafana 4000:4000π Test the App: Visit: http://localhost:4000
Install Argo CD on Minikube and configure it to automate Kubernetes deployments, Learn more: https://argo-cd.readthedocs.io/en/stable
The file argocd/application.yaml is responsible for automatically syncing Kubernetes with your GitHub repository, Apply the config:
kubectl apply -f argocd/application.yaml -n argocdMake sure you update your GitHub repository URL inside the file: graphql-system-k8s-nginx-prometheus-grafana/argocd/application.yaml
kubectl port-forward svc/argocd-server -n argocd 8080:443π View the ArgoCD UI: Visit https://localhost:8080
| The view of how Argo CD automation works with this application |
|---|
A CI/CD pipeline is included at .github/workflows/build-docker-image.yaml, which automatically builds and pushes the Docker image whenever changes are committed to the main branch.
1. π You can view application metrics by navigating to http://localhost:4000/metrics, which exposes all Prometheus-compatible metrics of the application.
2. β‘ To set up Prometheus and Grafana on Kubernetes (Windows recommended via Helm), follow the guide provided in: src/monitoring/prometheus&grafana.txt, This file includes all required configurations and setup steps clearly.
| Prometheus dashboard view live metrics collected while the application is running |
|---|
| Grafana dashboard visual representation of application metrics |
|---|
Ishan Madhusha
GitHub: PAIshanMadusha
Feel free to explore my work and reach out if you'd like to collaborate! π
This project is licensed under the MIT License.
See the LICENSE file for more details.






