{"id":23483562,"url":"https://github.com/hamdiz0/qr-code-generator","last_synced_at":"2026-02-13T20:06:07.138Z","repository":{"id":257999855,"uuid":"868254085","full_name":"hamdiz0/qr-code-generator","owner":"hamdiz0","description":"A containerized app that generates QR codes with urls as an input ,Built ,Pushed and Deployed with a CI/CD Pipeline using Docker ,Jenkins and an EKS cluseter set up with Terrafrom .This repo contains details on running this app using docker compose along with steps to deploy it on vercel and render","archived":false,"fork":false,"pushed_at":"2025-01-03T16:11:12.000Z","size":2853,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-12T09:06:33.126Z","etag":null,"topics":["api","devops","docker","docker-compose","front","jenkins","nextjs","postgresql","python","render","vercel"],"latest_commit_sha":null,"homepage":"https://qrcode-hz.vercel.app/","language":"JavaScript","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/hamdiz0.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}},"created_at":"2024-10-05T22:00:01.000Z","updated_at":"2025-10-24T21:11:50.000Z","dependencies_parsed_at":"2025-06-12T17:08:18.621Z","dependency_job_id":"2c0ed50f-41ae-46d9-8f0c-4e34e715fed5","html_url":"https://github.com/hamdiz0/qr-code-generator","commit_stats":null,"previous_names":["hamdiz0/qr-code-gen","hamdiz0/qr-code-generator"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hamdiz0/qr-code-generator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hamdiz0%2Fqr-code-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hamdiz0%2Fqr-code-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hamdiz0%2Fqr-code-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hamdiz0%2Fqr-code-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hamdiz0","download_url":"https://codeload.github.com/hamdiz0/qr-code-generator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hamdiz0%2Fqr-code-generator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29416046,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T06:24:03.484Z","status":"ssl_error","status_checked_at":"2026-02-13T06:23:12.830Z","response_time":78,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["api","devops","docker","docker-compose","front","jenkins","nextjs","postgresql","python","render","vercel"],"created_at":"2024-12-24T21:12:43.101Z","updated_at":"2026-02-13T20:06:07.123Z","avatar_url":"https://github.com/hamdiz0.png","language":"JavaScript","readme":"# Qr-Code-Generator\n\nBased on \u003ca href='https://github.com/rishabkumar7/devops-qr-code'\u003edevops-qr-code\u003c/a\u003e\n\nThis app generates QR codes based on input URLs. \nIt is designed to be flexible, working seamlessly in both internal environments like Kubernetes and external deployments on platforms like Vercel and Render by using NextJS routing features along with environment variables to switch between the two modes\n\n- [Prerequisites](#prerequisites-)\n- [Running the app using docker-compose](#runing-the-app-using-docker-compose-)\n- [Deploying an EKS cluster using Terraform](#deploying-an-eks-cluster-using-terraform-)\n- [Setting up Jenkins](#setting-up-jenkins-)\n- [YAML files](#yaml-files-)\n- [CI/CD Pipeline](#cicd-pipeline-)\n  - [CI Pipeline](#ci-pipeline-)\n    - [Building and Pushing the images](#building-and-pushing-the-images-)\n    - [Changing the YAML files image version](#changing-the-yaml-files-iamge-verion-)\n    - [Pushing the version change](#pushing-the-version-change-)\n  - [CD Pipeline](#cd-pipeline-)\n- [Deploying the app using render and vercel](#deploying-the-app-using-render-and-vercel-)\n  - [Deploying the front end on vercel](#deploying-the-front-end-on-vercel-)\n  - [Deploying both the api and postgres db on render](#deploying-both-the-api-and-postgres-db-on-render-)\n    - [Setting a Postgres data base](#setting-a-postgres-data-base-)\n    - [Setting up the API](#setting-up-the-api-)\n- [Results](#results-)\n  - [EKS deployment](#eks-deployment-)\n  - [Vercel and Render deployment](#vercel-and-render-deployment-)\n\n* Front-End built with NextJs\n* Api built with python FastApi\n* Data Base created with postgres\n\nThe user enters a url and clicks the button to send the url to the api ,the api checks if the url is present in the data-base or not :\n\n* if yes it retrieves the corresponding qr-code and sends it back to the user\n* if not it generates a qr-code sends it back to the user and save it in the data-base\n\n\u003cimg src='./imgs/qr-code.PNG' style=\"width:100%\"\u003e\n\n## `Prerequisites` :\n\n* Docker\n* Docker-compose\n* AWS account (Free Tier)\n* Jenkins (as a container)\n* AWS-CLI\n* Kubectl\n* Terraform\n\n ## `Runing the app using docker-compose` :\n\n* make sure to set up the right enviroment variables in the \u003ca href=\"./front/.env\"\u003e.env\u003c/a\u003e file for the internal docker compose environmnet\n  ```\n  NEXT_PUBLIC_USE_INTERNAL_ROUTE=true\n  NEXT_PUBLIC_INTERNAL_API=http://api (\"api\" is the service name for the api in the docker-compose.yml)\n  ```\n\n* the external network can be used but it's not practicle for this case \n  ```\n  NEXT_PUBLIC_USE_INTERNAL_ROUTE=false\n  NEXT_PUBLIC_EXTERNAL_API=http://localhost:3001 (the api service must be forwarded for this to work)\n  ```\n\n* run the app using the Docker files in build/context folders \u003ca href=\"./docker-compose.yml\"\u003eview file here\u003c/a\u003e :\n  ```\n  docker compose up --build\n  ```\n\n* run the app using the docker images from DockerHub \u003ca href=\"./docker-compose-images.yml\"\u003eview file here\u003c/a\u003e :\n  ```\n  docker compose up -f ./docker-compose-images.yml up\n  ```\n\n## `Deploying an EKS cluster using Terraform` :\n\n* here is a quick setup guide on how to deploy an minimal EKS cluster using terraform :\n\n  - \u003ca href=\"https://github.com/hamdiz0/eks-terraform-setup\"\u003eview the guide here\u003c/a\u003e\n\n* after creating the cluter make sure to add an access entry for the IAM user to access the cluster\n* go to the eks console `EKS\u003eCluster\u003e\"eks-cluster-name\"\u003eIAM access entries ` and add the user to the cluster with the necessary permissions :\n\n    \u003cimg src=\"./imgs/entry.png\" style=\"width:100%\"/\u003e\n  \n* The Terraform configuration is divided into three files:\n  - \u003ca href=\"./terraform/eks.tf\"\u003eeks.tf\u003c/a\u003e: Contains the main configuration for the EKS cluster.\n  - \u003ca href=\"./terraform/network.tf\"\u003enetwork.tf\u003c/a\u003e: Defines the network settings for the EKS cluster.\n  - \u003ca href=\"./terraform/provider.tf\"\u003eprovider.tf\u003c/a\u003e: Specifies the provider configuration for AWS.\n\n## `Setting up Jenkins` :\n\n* follow this guide to set up jenkins as a container \u003ca href=\"https://github.com/hamdiz0/LearningDevOps/blob/main/jenkins/README.md#doker-in-jenkins\"\u003eDocker in Jenkins\u003c/a\u003e\n\n* make sure docker is setup in jenkins (more details \u003ca href=\"https://github.com/hamdiz0/Learning-DevOps/tree/main/jenkins#doker-in-jenkins\"\u003ehere\u003c/a\u003e)\n\n* it's preferable to use a multibranch pipeline cause of the usefull plugins and features it provides\n\n* add \"Multibranch Scan Webhook Trigger\" plugin in jenkins \n\n\u003cimg src='./imgs/trigger.png' style='width:100%'\u003e\n\n* configure a webhook in the git repo webhook settings :\n    - `\u003cjenkins-url\u003e/multibranch-webhook-trigger/invoke?token=\u003ctoken\u003e`\n\n* more details about multibranch webhooks \u003ca href=\"https://github.com/hamdiz0/Learning-DevOps/blob/main/jenkins/README.md#multibranch-triggers-\"\u003ehere\u003c/a\u003e\n\n* install the aws cli in the jenkins container :\n    ```sh\n    docker exec -it jenkins bash\n    ```\n    ```sh\n    apt install unzip wget\n    wget \"https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip\"\n    unzip awscli-exe-linux-x86_64.zip\n    sudo ./aws/install\n    ```\n* configure the aws cli with the credentails of the IAM user used to cretae the EKS cluster or add a new user for jenkins with right permissions :\n    ```sh\n    aws configure\n    ```\n* verify the configuration :\n    ```sh\n    aws sts get-caller-identity\n    ```\n* install kubectl in the jenkins container :\n    ```sh\n    K8S_VERSION=1.32\n    apt-get update\n    apt-get install --quiet --yes apt-transport-https ca-certificates curl\n    curl -fsSL https://pkgs.k8s.io/core:/stable:/v${K8S_VERSION}/deb/Release.key | \\\n    gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg\n    echo \"deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v${K8S_VERSION}/deb/ /\" | \\\n    tee /etc/apt/sources.list.d/kubernetes.list\n    apt-get update\n    apt-get install --quiet --yes kubectl\n    ```\n* update the kubeconfig file :\n\n  ```sh\n  aws eks --region \u003cregion\u003e update-kubeconfig --name \u003ccluster-name\u003e\n  ```\n\n## `YAML files` :\n\n* set up a deployment with its corresponding service for each component of the app\n  - \u003ca href=\"./k8s-manifests/front-deployment_svc.yml\"\u003efront-end\u003c/a\u003e - (LoadBalancer)\n  - \u003ca href=\"./k8s-manifests/api-deployment_svc.yml\"\u003eapi\u003c/a\u003e - (ClusterIP)\n  - \u003ca href=\"./k8s-manifests/postgres-deployment_svc.yml\"\u003epostgres\u003c/a\u003e - (ClusterIP)\n\n## `CI/CD Pipeline` :\n\n  \u003cimg src=\"./imgs/arch.png\" style=\"width:100%\"\u003e\n\n### `CI Pipeline` :\n\n#### `Building and Pushing the images` :\n\n* utilized two \u003ca href=\"./script.groovy\"\u003eFunction Templates\u003c/a\u003e  to build and push the images \n  - hamdiz0/qr-front:latest\n  - hamdiz0/qr-api:latest\n  - postgres:15-alpine (default)\n\n\u003cimg src=\"./imgs/pushed with jenkins.PNG\" style=\"width:100%\"\u003e\n\n#### Changing the YAML files iamge verion :\n\n* utilized a script to change the demployment image version \u003ca href=\"./k8s-manifests/change_version.sh\"\u003echange_version.sh\u003c/a\u003e\n* in the `update version` stage, Jenkins runs the script to change both the front-end and api image versions \n    ```groovy\n    script {\n      sh \"\"\"\n        cd k8s-manifests\n        chmod +x change_version.sh\n        ./change_version.sh -v $VERSION\n      \"\"\"\n    }\n    ```\n### Pushing the version change :\n\n* set up jenkins to update the git repository with new version\n* set up a git `user.name` and `user.eamil` for Jenkins :\n    ```\n    docker exec -it jenkins bash\n    git config --global user.name \"jenkins\"\n    git config user.email \"jenkins@jenkins.com\"\n    ```\n* ustilized a function that adds and pushs changes to a git repository \n    - view the function \u003ca href=\"./script.groovy\"\u003ehere\u003c/a\u003e\n* the function uses a git access token wish must be configured and added to jenkins as a `Username and Password` credential\n  - set up an access token in git hub :\n    \u003cimg src=\"./imgs/token.PNG\" style=\"width:100%\"\u003e\n* make sure to add the `Ignore Commiter Strategy` plugin and ignore jenkins pushes to avoid infinite build loops :\n      \u003cimg src=\"./imgs/avoid.PNG\" style=\"width:100%\"\u003e\n* example of using the function :\n    ```groovy\n    gs.git_push(\n        'github.com/hamdiz0/qr-code-generator',     // url without \"https://\"\n        'github-api-token',                         // credentialsId\n        \"updated to version ${VERSION}\",            // commit message\n        'main'                                      // branch\n    )\n    ```\n\n### `CD Pipeline` :\n\n* after the `updated version` stage the `deploy` stage is triggered \n* the `deploy` stage runs the \u003ca href=\"./k8s-manifests/deploy.sh\"\u003edeploy.sh\u003c/a\u003e script wich applies the changes to the `EKS` cluster :\n    ```groovy\n    script {\n      sh \"\"\"\n          export KUBECONFIG=$KUBECONFIG  // eks kubeconfig's absolute path in the jenkins container\n          cd k8s-manifests               // change directory to the yaml files directory\n          chmod +x deploy.sh             // make the script executable\n          ./deploy.sh                    // run the script\n      \"\"\"\n    }\n    ```\n* the yaml files must be in the same directory as the script\n\n\n## `Deploying the app using render and vercel` :\n\n### `deploying the front end on vercel` :\n\n* create a new project on vercel and link the gitub repo hosting the front end\n* choose the right directory containing the front end files\n* make sure to select the NextJs framework\n\n  \u003cimg src=\"./imgs/vercel.png\" style=\"width:100%\"\u003e\n\n* add the necessary environment variables for the external routing mode in `Settings/Environment Varaibles`\n  ```\n  NEXT_PUBLIC_USE_INTERNAL_ROUTE=true\n  NEXT_PUBLIC_EXTERNAL_API=an external api url \"https://api.onrender.com\"\n  ```\n\n  \u003cimg src=\"./imgs/vercel-env.png\" style=\"width:100%\"\u003e\n\n### `deploying both the api and postgres db on render` :\n\n\u003cimg src=\"./imgs/render.png\" style=\"width:100%\"\u003e\n\n#### `Setting a Postgres data base` :\n\n* create a new webservice\n* make sure to select the nearest region \n* add all the needed information\n\n\u003cimg src=\"./imgs/db.png\" style=\"width:100%\"\u003e\n\n#### `Setting up the API` :\n\n* create a new webservice\n* make sure to select the nearest region \n* select python as the language\n\n\u003cimg src=\"./imgs/api.png\" style=\"width:100%\"\u003e\n\n* add the Start command :\n    ```\n    uvicorn main:app --host  0.0.0.0 --port 80\n    ```\n* add the environment variables along with their values from the postgres service\n    ```\n    CORS_ORIGIN         // \"*\" to allow all traffic or set a specific url\n    POSTGRES_HOST       // Hostname value from info/connections\n    POSTGRES_DB         // Database value from info/connections\n    POSTGRES_USER       // Username value from info/connections\n    POSTGRES_PASSWORD   // Password value from info/connections\n    ```\n\u003cimg src=\"./imgs/env.png\" style=\"width:100%\"\u003e\n\n* the required values are present in the connections part of the postgres db info tab\n\n\u003cimg src=\"./imgs/db-creds.png\" style=\"width:100%\"\u003e\n\n## `Results` :\n\n### `EKS deployment` :\n\n\u003cimg src=\"./imgs/eks-1.png\" style=\"width:100%\"\u003e\n\n\u003cimg src=\"./imgs/eks-2.png\" style=\"width:100%\"\u003e\n\n\u003cimg src=\"./imgs/eks-3.png\" style=\"width:100%\"\u003e\n\n\u003cimg src=\"./imgs/jen.png\" style=\"width:100%\"\u003e\n\n\u003cimg src=\"./imgs/eks-4.png\" style=\"width:100%\"\u003e\n\n### `Vercel and Render deployment` :\n\n\u003cimg src=\"./imgs/1.png\" style=\"width:100%\"\u003e\n\n\u003cimg src=\"./imgs/2.png\" style=\"width:100%\"\u003e\n\n## Checkout my \u003ca href=\"https://github.com/hamdiz0/LearningDevOps\"\u003eLearningDevops\u003c/a\u003e repo for more details about these tools and devops in general do not hesitate to contribute\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhamdiz0%2Fqr-code-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhamdiz0%2Fqr-code-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhamdiz0%2Fqr-code-generator/lists"}