{"id":22246044,"url":"https://github.com/mdshimulmahmud/goal-projects","last_synced_at":"2026-04-12T09:04:55.514Z","repository":{"id":264991420,"uuid":"894811391","full_name":"MdShimulMahmud/goal-projects","owner":"MdShimulMahmud","description":"This project is a full-stack MERN application deployed with Kubernetes, featuring manifests for Deployments, Services, Ingress, Secrets, ConfigMaps, and NFS-backed storage. CI/CD integrates GitHub Actions, Jenkins, and ArgoCD for automated testing, building, and Kubernetes deployments.","archived":false,"fork":false,"pushed_at":"2024-12-03T05:04:29.000Z","size":440,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-30T10:29:02.818Z","etag":null,"topics":["argocd","backend","ci-cd","docker","docker-compose","frontend","github-actions","jenkins","kubernetes","kubernetes-deployment","mognodb","nfs-client"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MdShimulMahmud.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"license.txt","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}},"created_at":"2024-11-27T03:16:08.000Z","updated_at":"2024-12-22T09:49:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"e4bf2156-f133-40c9-8764-d880cccf315a","html_url":"https://github.com/MdShimulMahmud/goal-projects","commit_stats":null,"previous_names":["mdshimulmahmud/goal-projects"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MdShimulMahmud%2Fgoal-projects","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MdShimulMahmud%2Fgoal-projects/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MdShimulMahmud%2Fgoal-projects/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MdShimulMahmud%2Fgoal-projects/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MdShimulMahmud","download_url":"https://codeload.github.com/MdShimulMahmud/goal-projects/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245450604,"owners_count":20617379,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["argocd","backend","ci-cd","docker","docker-compose","frontend","github-actions","jenkins","kubernetes","kubernetes-deployment","mognodb","nfs-client"],"created_at":"2024-12-03T05:25:47.463Z","updated_at":"2026-04-12T09:04:55.483Z","avatar_url":"https://github.com/MdShimulMahmud.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Goals Project\n\nA fullstack MERN project which has Reactjs as frontend, Nodejs as backend, and MongoDB as a Database.\n\n## Project Set Up\n\nClone this repository from the GitHub URL.\n\n```sh\ngit clone https://github.com/MdShimulMahmud/goal-projects.git\ncd goal-projects\ncode .\n```\n\n### 1. Backend Development\n\n1.1 **Open Backend**\n```bash\ncd backend\n```\n\n1.2 **Install Dependencies**\n```bash\nnpm install\n```\n\n1.3 **Run Backend**\n```bash\nnpm start\n```\n\n1.4 **Check Application running on:** http://localhost:5000/goals\n\n### 2. Frontend Application\n\n2.1 **Open Frontend**\n```bash\ncd frontend\n```\n\n2.2 **Install Dependencies**\n```bash\nnpm install\n```\n\n2.3 **Run Frontend**\n```bash\nnpm start\n```\n\n2.4 **Check Application running on:** http://localhost:3000\n\n## Dockerized Application\n\n### Backend Application\n\n#### Dockerfile\n\n```dockerfile\nFROM node:16-alpine\n\nWORKDIR /app\n\nCOPY package.json .\n\nCOPY . .\n\nRUN npm install\n\nEXPOSE 5000\n\nCMD [\"npm\", \"start\"]\n```\n\n#### Build Docker Image\n```bash\ndocker build -t \u003cimage name\u003e:\u003cimage tag\u003e \u003cdockerfile path\u003e\n```\nBest Practice:\n```bash\ndocker build -t your-dockerhub-username/backend:tag -f backend/Dockerfile .\n```\nFor example:\n```bash\ndocker build -t shimulmahmud/backend:v1.0.4 .\n```\n\n#### Run Docker Image\n```bash\ndocker run -d -p \u003chost-port\u003e:\u003ccontainer-port\u003e \u003cimage name\u003e:\u003cimage tag\u003e\n```\nFor example:\n```bash\ndocker run -d -p 5000:5000 shimulmahmud/backend:v1.0.4\n```\n\n#### Push Image to Docker Registry\n```bash\ndocker login\ndocker push your-dockerhub-username/backend:tag\n```\nFor example:\n```bash\ndocker push shimulmahmud/backend:v1.0.4\n```\n\n### Frontend Application\n\n#### Multistage Image Build\n\n```dockerfile\nFROM node:16-alpine AS build-stage\n\nWORKDIR /app\n\nCOPY package.json .\n\nRUN npm install\n\nCOPY . .\n\nRUN npm run build\n\nFROM nginx:latest\n\nCOPY --from=build-stage /app/build /usr/share/nginx/html\nCOPY ./conf/nginx.conf /etc/nginx/conf.d/default.conf\n\nCMD [\"nginx\", \"-g\", \"daemon off;\"]\n```\n\nHere we used nginx as a web server which provides static web content and listens on port 80 by default.\n\n#### Build Docker Image\n```bash\ndocker build -t \u003cimage name\u003e:\u003cimage tag\u003e \u003cdockerfile path\u003e\n```\nBest Practice:\n```bash\ndocker build -t your-dockerhub-username/frontend:tag -f frontend/Dockerfile .\n```\nFor example:\n```bash\ndocker build -t shimulmahmud/frontend:v1.0.4 .\n```\n\n#### Run Docker Image\n```bash\ndocker run -d -p \u003chost-port\u003e:\u003ccontainer-port\u003e \u003cimage name\u003e:\u003cimage tag\u003e\n```\nFor example:\n```bash\ndocker run -d -p 3000:80 shimulmahmud/frontend:v1.0.4\n```\n\n#### Push Image to Docker Registry\n```bash\ndocker login\ndocker push your-dockerhub-username/frontend:tag\n```\nFor example:\n```bash\ndocker push shimulmahmud/frontend:v1.0.4\n```\n\n### Reverse Proxy Nginx\n\nTo set up Nginx as a reverse proxy for your MERN stack application, you can configure Nginx to route traffic to both your frontend (React) and backend (Node.js/Express) applications.\n\nHere’s how you can configure Nginx to act as a reverse proxy in a Dockerized environment:\n\nYou’ll need to create a custom Nginx configuration file (`default.conf`) to set up the reverse proxy.\n\n#### Nginx Configuration\n\n```default.conf```\n```bash\nupstream frontend {\n    server frontend:3000;\n}\n\nupstream backend {\n    server backend:5000;\n}\n\nserver {\n    listen 80;\n\n    location / {\n        proxy_pass http://frontend;\n    }\n\n    location /api {\n        rewrite /api/(.*) /$1 break;\n        proxy_pass http://backend;\n    }\n}\n```\n\nIn this configuration:\n1. Frontend (React) is served from http://frontend:3000.\n2. Backend (Node.js/Express API) is served from http://backend:5000.\n3. The location / route handles requests for the frontend.\n4. The location /api route handles API requests that should be forwarded to the backend.\n\n#### Dockerize Nginx\n\nTo use Nginx as a reverse proxy in a Dockerized environment, you'll need to create a Dockerfile for Nginx and replace its default configuration.\n\n```dockerfile\nFROM nginx:alpine\n\nRUN rm /etc/nginx/conf.d/default.conf\n\nCOPY default.conf /etc/nginx/conf.d/default.conf\n```\n\nTo understand how a reverse proxy works, you can [Visit Here](https://www.upguard.com/blog/reverse-proxy-vs-load-balancer)\n\n![Reverse Proxy](https://github.com/MdShimulMahmud/goal-projects/blob/master/reverse_proxy.png)\n\n## Docker Compose\n\nTo set up a Docker Compose configuration for your MERN stack application (MongoDB, Express, React, Node.js) along with Nginx as a reverse proxy, here’s a structured example.\n\n### Project Structure\n\n```bash\n/goal-projects\n  ├── backend/\n  │   ├── Dockerfile\n  │   └── ...\n  ├── frontend/\n  │   ├── Dockerfile\n  │   └── ...\n  ├── nginx/\n  │   ├── Dockerfile\n  │   └── nginx.conf\n  ├── docker-compose.yml\n  └── ...\n```\n\n### Docker Compose Configuration (`docker-compose.yml`)\n\n```yaml\nversion: \"3.8\"\n\nservices:\n  backend:\n    build:\n      context: ./backend\n      dockerfile: Dockerfile\n\n  frontend:\n    build:\n      context: ./frontend\n      dockerfile: Dockerfile\n    depends_on:\n      - backend\n\n  nginx:\n    build:\n      context: ./nginx\n      dockerfile: Dockerfile\n    ports:\n      - \"80:80\"\n    depends_on:\n      - backend\n      - frontend\n```\nRun docker-compose : ```docker-compose up --build```\n1. Docker Compose manages multiple containers for the MERN stack, including frontend, backend, and nginx.\n2. The Nginx container acts as a reverse proxy to route traffic to the frontend (/) and backend (/api).\n3. Dockerfiles are defined for the frontend, backend, and Nginx.\n\n## Kubernetes Manifests\n\n### Overview\n\n- **Deployment**: Describes the pods that should run for your frontend, backend, and MongoDB services.\n- **Service**: Exposes each component (frontend, backend, MongoDB) to the network within the Kubernetes cluster.\n- **Ingress**: Manages external access to your services, routing traffic to the frontend and backend.\n- **Secrets**: Stores sensitive information such as MongoDB credentials.\n- **ConfigMap**: Stores configuration data that can be accessed by the application pods.\n- **PersistentVolumeClaim (PVC)**: Allows MongoDB to store data persistently.\n\n### Example Manifests\n\n#### Deployment\n\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: frontend-deployment\n  labels:\n    app: frontend\n    type: frontend\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: frontend\n      type: frontend\n  template:\n    metadata:\n      labels:\n        app: frontend\n        type: frontend\n    spec:\n      containers:\n      - name: frontend-container\n        image: shimulmahmud/frontend:v1.0.4\n        ports:\n        - containerPort: 3000\n\n--- \n\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: backend-deployment\n  labels:\n    app: backend\n    type: backend\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: backend\n      type: backend\n  template:\n    metadata:\n      labels:\n        app: backend\n        type: backend\n    spec:\n      containers:\n      - name: backend-conatiner\n        image: shimulmahmud/backend:v1.0.4\n        ports:\n        - containerPort: 5000\n        volumeMounts:\n          - mountPath: /app/logs/\n            name: access-log-volume\n            # subPath: access.log\n        env:\n          - name: DATABASE_PASSWORD\n            valueFrom:\n              secretKeyRef:\n                name: database-secret\n                key: password\n          - name: DATABASE_USERNAME\n            valueFrom:\n              secretKeyRef:\n                name: database-secret\n                key: username\n          - name: DATABASE_URL\n            valueFrom:\n              configMapKeyRef:\n                name: configmap\n                key: database\n      volumes:\n        - name: access-log-volume\n          persistentVolumeClaim:\n            claimName: test-claim\n```\n\n#### Service\n\n```yaml\napiVersion: v1\nkind: Service\nmetadata:\n  name: client-service\nspec:\n  selector:\n    app: frontend\n    type: frontend\n  ports:\n    - protocol: TCP\n      port: 3000\n      targetPort: 3000\n  type: ClusterIP \n\n---\n\napiVersion: v1\nkind: Service\nmetadata:\n  name: backend-service\nspec:\n  selector:\n    app: backend\n    type: backend\n  ports:\n    - protocol: TCP\n      port: 5000\n      targetPort: 5000\n  type: ClusterIP \n```\n\n#### Ingress\n\n```yaml\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  name: minimal-ingress\n  annotations:\n    kubernetes.io/ingress.class: 'nginx'\n    nginx.ingress.kubernetes.io/use-regex: 'true'\n    # nginx.ingress.kubernetes.io/rewrite-target: /$1\nspec:\n  ingressClassName: nginx\n  rules:\n  - http:\n      paths:\n      - path: /\n        pathType: Prefix\n        backend:\n          service:\n            name: client-service\n            port:\n              number: 3000\n      - path: /goals\n        pathType: Prefix\n        backend:\n          service:\n            name: backend-service\n            port:\n              number: 5000\n```\n\n#### Secrets\n\n```yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  name: database-secret\ntype: Opaque\ndata:\n  password: \u003cbase64 your mongodb password\u003e\n  username: \u003cbase64 your mongodb username\u003e\n```\n\n#### ConfigMap\n\n```yaml\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: configmap\ndata:\n  database: \"cluster1.uktxj.mongodb.net/?retryWrites=true\u0026w=majority\u0026appName=Cluster1\"\n```\n\n#### PersistentVolumeClaim (PVC)\n\nTo set up nfs-server for persistent volume you can [read this](https://github.com/nasirnjs/kubernetes/blob/main/k8s-cluster-setup/dynamic-nfs-provisioning_k8s.md) .\n\n```yaml\nkind: PersistentVolumeClaim\napiVersion: v1\nmetadata:\n  name: test-claim\nspec:\n  storageClassName: nfs-client\n  accessModes:\n    - ReadWriteMany\n  resources:\n    requests:\n      storage: 100Mi\n```\n\nTo apply and create corresponding services, run the command in the terminal ```cd k8s``` and \n```kubectl apply -f .```\n\n## CI/CD Pipeline Build with GitHub Actions\n\n[ **Workflow Overview** ](https://github.com/MdShimulMahmud/goal-projects/blob/master/.github/workflows/ci.yaml)\n\n### Triggers\n\n- **Push**: Triggers on push events to the `master` branch, excluding changes to `k8s/deployment.yaml`.\n- **Pull Request**: Triggers on pull requests to the `master` branch, excluding changes to `k8s/deployment.yaml`.\n\n### Jobs\n\n#### 1. Test\n\n- **Runs on**: `ubuntu-latest`\n- **Steps**:\n    - Checkout code\n    - Run Approval Action\n    - Store the approval output as an environment variable\n    - Get the output\n\n#### 2. Backend\n\n- **Runs on**: `ubuntu-latest`\n- **Needs**: `test` job\n- **Condition**: Runs if the `test` job's approval output is `true`\n- **Steps**:\n    - Checkout code\n    - Set up Node.js\n    - Install dependencies\n    - Debug Run Number\n    - Check current version\n\n#### 3. Frontend\n\n- **Runs on**: `ubuntu-latest`\n- **Needs**: `backend` job\n- **Steps**:\n    - Checkout code\n    - Set up Node.js\n    - Install dependencies\n    - Debug Run Number\n    - Check current version\n\n#### 4. Version Check\n\n- **Runs on**: `ubuntu-latest`\n- **Needs**: `frontend` and `backend` jobs\n- **Steps**:\n    - Checkout code\n    - Extract current version\n    - Read previous version from `deployment.yaml`\n    - Check if current version differs from previous\n\n#### 5. Docker\n\n- **Runs on**: `ubuntu-latest`\n- **Needs**: `frontend`, `backend`, and `version_check` jobs\n- **Condition**: Runs if the `version_check` job's version_diff output is `true`\n- **Steps**:\n    - Checkout code\n    - Login to Docker Hub\n    - Set up Docker Buildx\n    - Build and push frontend image\n    - Build and push backend image\n\n#### 6. Tags\n\n- **Runs on**: `ubuntu-latest`\n- **Needs**: `docker` and `version_check` jobs\n- **Condition**: Runs if the `version_check` job's version_diff output is `true`\n- **Steps**:\n    - Checkout code\n    - Set the new image version\n    - Update Kubernetes `deployment.yaml` image tags\n    - Commit and push changes\n\n## CI/CD Pipeline Build with Jenkins\n\nThis [Jenkins pipeline ](https://github.com/MdShimulMahmud/goal-projects/blob/master/Jenkinsfile) is designed to automate the build and deployment process for the Goals project. The pipeline consists of three main stages: Backend, Frontend, and Docker. It also includes environment variables for GitHub and Docker credentials.\n\nYour jenkins server running on http://localhost:8080 or ```your_server_ip_address:8080```\n\n## Environment Variables\n\n- `GH_TOKEN`: GitHub token for accessing private repositories.\n- `DOCKER_USERNAME`: Docker Hub username for logging in and pushing images.\n- `DOCKER_PASSWORD`: Docker Hub access token for authentication.\n\n## Stages\n\n### 1. Backend\n\n- **Agent**: Any available agent.\n- **Steps**:\n    - Change directory to `backend`.\n    - Install npm dependencies.\n    - Print the current build number.\n    - Read and print the current version from the `VERSION` file.\n\n### 2. Frontend\n\n- **Agent**: Any available agent.\n- **Steps**:\n    - Change directory to `frontend`.\n    - Install npm dependencies.\n    - Build the frontend application.\n    - Print the current build number.\n    - Read and print the current version from the `VERSION` file.\n\n### 3. Docker\n\n- **Agent**: Any available agent.\n- **Steps**:\n    - Read the current version from the `VERSION` file.\n    - Log in to Docker Hub using the provided credentials.\n    - Build and push Docker images for both frontend and backend using the current version as the tag.\n    - Handle any exceptions that occur during the Docker build or push process.\n\n### 4. Update Manifest Pipeline Trigger\n\nThis project contains a Jenkins pipeline stage to trigger the `update-k8s-manifests` job by passing the current version as an `IMAGE_TAG` parameter.\n\nThe `Trigger Update Manifest Pipeline` stage performs the following tasks:\n1. Reads the current version from a `VERSION` file.\n2. Triggers the `update-k8s-manifests` pipeline with the current version as a parameter.\n\n#### Code Snippet\n\n```groovy\nstage('Trigger Update Manifest Pipeline') {\n    agent any\n    steps {\n        script {\n            def current_version = sh(script: \"cat VERSION\", returnStdout: true).trim()\n            \n            build job: 'update-k8s-manifests', parameters: [\n                string(name: 'IMAGE_TAG', value: \"${current_version}\")\n            ]\n        }\n    }\n}\n```\nIn Infra Repository, you will find all the manifests used in this project. [Repo url](https://github.com/MdShimulMahmud/goal-projects-infra.git)\n\n\n## Post Actions\n\n- **Always**: Print a message indicating that the pipeline has completed.\n- **Failure**: Print a message indicating that the pipeline has failed and suggest checking the logs for errors.\n- **Success**: Print a message indicating that the pipeline has succeeded.\n\n## Example Usage\n\nTo use this Jenkinsfile, place it in the root directory of your project and configure your Jenkins job to use it. Ensure that the necessary credentials (`github-token`, `docker-username`, and `docker-password`) are configured in Jenkins.\n\nHit your jenkins url to checkout either it's working or not!\n\nHappy Coding!!!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdshimulmahmud%2Fgoal-projects","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmdshimulmahmud%2Fgoal-projects","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmdshimulmahmud%2Fgoal-projects/lists"}