This project demonstrates how to deploy a fullstack application on a Kubernetes cluster in Google Cloud Platform. It covers the entire flow: from infrastructure provisioning with Terraform, continuous integration via GitHub Actions, to automated deployment with FluxCD.
This project uses a combination of tools and services to automate the deployment and management of a fullstack application on GKE:
- Terraform — infrastructure as code for GKE on GCP.
- GitHub Actions — CI/CD pipeline: test, build & push Docker images.
- FluxCD — GitOps: applies new manifests from GitHub and manages new image releases.
- External Secrets + GCP Secret Manager — secure secret management.
- ExternalDNS + Cloudflare — automated DNS record management..
- Cert-Manager + Let’s Encrypt — automated TLS certificates.
- Database — MongoDB deployed via the Bitnami Helm Chart.
- Ingress — for routing external traffic.
- Prometheus + Grafana — monitoring stack, with custom MongoDB and Ingress dashboards.
- Loki + Promtail — centralized logging for Ingress and other components.
- Docker Compose — for local development.
├── .github # GitHub Actions Workflows
├── client # Frontend (Vite + React)
├── server # Backend (Node.js + Express)
├── terraform # Infrastructure as Code (GCP provisioning)
├── kubernetes # Kubernetes manifests
│ ├── apps
│ │ └── base
│ │ ├── client
│ │ ├── database
│ │ ├── ingress
│ │ └── server
│ ├── clusters
│ │ └── my-cluster
│ │ ├── flux-system
│ │ ├── apps-kustomization.yaml
│ │ ├── devlinks-policy.yaml
│ │ ├── devlinks-registry.yaml
│ │ ├── devlinks-source.yaml
│ │ ├── flux-system-automation.yaml
│ │ ├── infra-kustomization.yaml
│ │ └── monitoring-kustomization.yaml
│ ├── infrastructure
│ │ ├── configs
│ │ └── controllers
│ └── monitoring
│ ├── configs
│ └── controllers
git clone https://github.com/mariansmolii/devlinks.git
cd devlinksBefore running the app locally, create .env.local file for the client and .env file for the server.
VITE_BACKEND_URL=
VITE_FRONTEND_URL=PORT=
DB_HOST=
JWT_SECRET=
CLOUDINARY_FOLDER_NAME=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=
CLOUDINARY_CLOUD_NAME=Run the full stack locally using Docker Compose.
docker-compose up -d- db
- server
- client
cd client
npm install
npm run devcd server
npm install
npm run devProvision the Kubernetes cluster using Terraform.
Create a file named terraform.tfvars and fill in your values:
project_id = "your-gcp-project-id"
region = "your-gcp-region"
zone = "your-gcp-zone"
subnet_cidr_range = "10.0.0.0/20" # optional, default provided
machine_type = "e2-medium" # optional, default provided
disk_size_gb = 30 # optional, default provided
external_secrets_ns = "external-secrets" # optional, default provided
external_secrets_sa_name = "external-secrets-sa" # optional, default provided
gke_secrets = {
"your-secret-name-1" = "your-secret-value-1"
"your-secret-name-2" = "your-secret-value-2"
# Add more secrets as needed
}To deploy the Kubernetes cluster, run the following commands:
cd terraform
terraform init
terraform applyAfter provisioning the infrastructure, this section covers applying Kubernetes manifests and setting up GitOps via FluxCD.
FluxCD automatically syncs changes from your GitHub repository to the Kubernetes cluster.
Flux deploys the following components:
- Application Manifests — from
kubernetes/apps/ - Infrastructure Controllers — from
kubernetes/infrastructure/ - Monitoring Stack — from
kubernetes/monitoring/ - Container Image Updates — tracked via
ImageRepository,ImagePolicy, andImageUpdateAutomation
To enable GitOps, bootstrap your GKE cluster with Flux and point it to this repository.
export GITHUB_TOKEN=<your-personal-access-token>
export GITHUB_USER=<your-github-username>flux bootstrap github \
--components-extra=image-reflector-controller,image-automation-controller \
--owner=$GITHUB_USER \
--repository=your-repo \
--branch=main \
--path=kubernetes/clusters/my-cluster \
--read-write-key \
--personal