{"id":24660053,"url":"https://github.com/mariansmolii/devlinks","last_synced_at":"2026-04-04T21:31:39.215Z","repository":{"id":262237501,"uuid":"886334464","full_name":"mariansmolii/devlinks","owner":"mariansmolii","description":"devlinks is a platform for developers to share and manage their links.","archived":false,"fork":false,"pushed_at":"2025-09-15T19:32:17.000Z","size":615,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-03T14:23:31.564Z","etag":null,"topics":["bitnami-mongodb","cert-manager","ci-cd","cloudflare","docker","docker-compose","external-dns","external-secrets","fluxcd","github-actions","gke-cluster","grafana","ingress","k8s","loki","nodejs","prometheus","reactjs","terraform","typescript"],"latest_commit_sha":null,"homepage":"https://devlinks.space","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mariansmolii.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-11-10T18:52:08.000Z","updated_at":"2025-11-03T09:04:45.000Z","dependencies_parsed_at":"2024-11-11T11:26:26.475Z","dependency_job_id":"f8684323-4d05-4294-8964-449494da2f38","html_url":"https://github.com/mariansmolii/devlinks","commit_stats":null,"previous_names":["mariansmolii/devlinks"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mariansmolii/devlinks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariansmolii%2Fdevlinks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariansmolii%2Fdevlinks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariansmolii%2Fdevlinks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariansmolii%2Fdevlinks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mariansmolii","download_url":"https://codeload.github.com/mariansmolii/devlinks/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mariansmolii%2Fdevlinks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31415110,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T20:09:54.854Z","status":"ssl_error","status_checked_at":"2026-04-04T20:09:44.350Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitnami-mongodb","cert-manager","ci-cd","cloudflare","docker","docker-compose","external-dns","external-secrets","fluxcd","github-actions","gke-cluster","grafana","ingress","k8s","loki","nodejs","prometheus","reactjs","terraform","typescript"],"created_at":"2025-01-26T03:17:33.105Z","updated_at":"2026-04-04T21:31:39.190Z","avatar_url":"https://github.com/mariansmolii.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CI](https://github.com/mariansmolii/devlinks/actions/workflows/ci.yaml/badge.svg)](https://github.com/mariansmolii/devlinks/actions)\n\n# Fullstack Kubernetes Deployment\n\nThis 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.\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Project Structure](#project-structure)\n- [Local Development](#local-development)\n- [Infrastructure Deployment](#infrastructure-deployment)\n- [Kubernetes Setup](#kubernetes-setup)\n\n## Overview\n\nThis project uses a combination of tools and services to automate the deployment and management of a fullstack application on GKE:\n\n- **Terraform —** infrastructure as code for GKE on GCP.\n- **GitHub Actions —** CI/CD pipeline: test, build \u0026 push Docker images.\n- **FluxCD —** GitOps: applies new manifests from GitHub and manages new image releases.\n- **External Secrets + GCP Secret Manager —** secure secret management.\n- **ExternalDNS + Cloudflare —** automated DNS record management..\n- **Cert-Manager + Let’s Encrypt —** automated TLS certificates.\n- **Database —** MongoDB deployed via the Bitnami Helm Chart.\n- **Ingress —** for routing external traffic.\n- **Prometheus + Grafana —** monitoring stack, with custom MongoDB and Ingress dashboards.\n- **Loki + Promtail —** centralized logging for Ingress and other components.\n- **Docker Compose —** for local development.\n\n## Project Structure\n\n```\n├── .github                  # GitHub Actions Workflows\n├── client                   # Frontend (Vite + React)\n├── server                   # Backend (Node.js + Express)\n├── terraform                # Infrastructure as Code (GCP provisioning)\n├── kubernetes               # Kubernetes manifests\n│   ├── apps\n│   │   └── base\n│   │       ├── client\n│   │       ├── database\n│   │       ├── ingress\n│   │       └── server\n│   ├── clusters\n│   │   └── my-cluster\n│   │       ├── flux-system\n│   │       ├── apps-kustomization.yaml\n│   │       ├── devlinks-policy.yaml\n│   │       ├── devlinks-registry.yaml\n│   │       ├── devlinks-source.yaml\n│   │       ├── flux-system-automation.yaml\n│   │       ├── infra-kustomization.yaml\n│   │       └── monitoring-kustomization.yaml\n│   ├── infrastructure\n│   │   ├── configs\n│   │   └── controllers\n│   └── monitoring\n│       ├── configs\n│       └── controllers\n\n```\n\n## Local Development\n\n### Clone the repository:\n\n```bash\ngit clone https://github.com/mariansmolii/devlinks.git\ncd devlinks\n```\n\nBefore running the app locally, create `.env.local` file for the client and `.env` file for the server.\n\n#### Sample `.env.local` for Client\n\n```bash\nVITE_BACKEND_URL=\nVITE_FRONTEND_URL=\n```\n\n#### Sample `.env` for Server\n\n```bash\nPORT=\nDB_HOST=\nJWT_SECRET=\nCLOUDINARY_FOLDER_NAME=\nCLOUDINARY_API_KEY=\nCLOUDINARY_API_SECRET=\nCLOUDINARY_CLOUD_NAME=\n```\n\n### Option 1 — Docker Compose\n\nRun the full stack locally using **Docker Compose**.\n\n#### Run Command\n\n```bash\ndocker-compose up -d\n```\n\n#### This will spin up:\n\n- db\n- server\n- client\n\n### Option 2 — Manual\n\n#### Start Client:\n\n```bash\ncd client\nnpm install\nnpm run dev\n```\n\n#### Start Server:\n\n```bash\ncd server\nnpm install\nnpm run dev\n```\n\n## Infrastructure Deployment\n\nProvision the Kubernetes cluster using Terraform.\n\n### Required Variables\n\nCreate a file named `terraform.tfvars` and fill in your values:\n\n```hcl\nproject_id               = \"your-gcp-project-id\"\nregion                   = \"your-gcp-region\"\nzone                     = \"your-gcp-zone\"\nsubnet_cidr_range        = \"10.0.0.0/20\"           # optional, default provided\nmachine_type             = \"e2-medium\"             # optional, default provided\ndisk_size_gb             = 30                      # optional, default provided\nexternal_secrets_ns      = \"external-secrets\"      # optional, default provided\nexternal_secrets_sa_name = \"external-secrets-sa\"   # optional, default provided\n\ngke_secrets = {\n  \"your-secret-name-1\" = \"your-secret-value-1\"\n  \"your-secret-name-2\" = \"your-secret-value-2\"\n  # Add more secrets as needed\n}\n```\n\n### Deploy Cluster\n\nTo deploy the Kubernetes cluster, run the following commands:\n\n```bash\ncd terraform\nterraform init\nterraform apply\n```\n\n## Kubernetes Setup\n\nAfter provisioning the infrastructure, this section covers applying Kubernetes manifests and setting up GitOps via FluxCD.\n\n### GitOps Deployment with FluxCD\n\nFluxCD automatically syncs changes from your GitHub repository to the Kubernetes cluster.\n\nFlux deploys the following components:\n\n- **Application Manifests** — from `kubernetes/apps/`\n- **Infrastructure Controllers** — from `kubernetes/infrastructure/`\n- **Monitoring Stack** — from `kubernetes/monitoring/`\n- **Container Image Updates** — tracked via `ImageRepository`, `ImagePolicy`, and `ImageUpdateAutomation`\n\n### FluxCD Bootstrap\n\nTo enable GitOps, bootstrap your GKE cluster with Flux and point it to this repository.\n\n#### 1. Export GitHub credentials:\n\n```bash\nexport GITHUB_TOKEN=\u003cyour-personal-access-token\u003e\nexport GITHUB_USER=\u003cyour-github-username\u003e\n```\n\n#### 2. Run Flux bootstrap:\n\n```bash\nflux bootstrap github \\\n  --components-extra=image-reflector-controller,image-automation-controller \\\n  --owner=$GITHUB_USER \\\n  --repository=your-repo \\\n  --branch=main \\\n  --path=kubernetes/clusters/my-cluster \\\n  --read-write-key \\\n  --personal\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmariansmolii%2Fdevlinks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmariansmolii%2Fdevlinks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmariansmolii%2Fdevlinks/lists"}