{"id":20181946,"url":"https://github.com/devteds/demo-apps-on-k8s","last_synced_at":"2025-06-21T01:33:36.507Z","repository":{"id":55523915,"uuid":"240727161","full_name":"devteds/demo-apps-on-k8s","owner":"devteds","description":"Demo Application: Services of book-store application deployed on K8S","archived":false,"fork":false,"pushed_at":"2022-08-09T21:55:33.000Z","size":11,"stargazers_count":13,"open_issues_count":0,"forks_count":25,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-10T05:12:25.249Z","etag":null,"topics":["docker","docker-compose","ingress","kubernetes","kubernetes-application","microservices","microservices-example","mysql","nginx-ingress","ruby-on-rails","ruby-on-rails-api","vuejs"],"latest_commit_sha":null,"homepage":"","language":"HCL","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/devteds.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}},"created_at":"2020-02-15T14:29:56.000Z","updated_at":"2025-02-20T07:23:58.000Z","dependencies_parsed_at":"2022-08-15T02:20:46.864Z","dependency_job_id":null,"html_url":"https://github.com/devteds/demo-apps-on-k8s","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/devteds/demo-apps-on-k8s","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devteds%2Fdemo-apps-on-k8s","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devteds%2Fdemo-apps-on-k8s/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devteds%2Fdemo-apps-on-k8s/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devteds%2Fdemo-apps-on-k8s/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devteds","download_url":"https://codeload.github.com/devteds/demo-apps-on-k8s/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devteds%2Fdemo-apps-on-k8s/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261046408,"owners_count":23102260,"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":["docker","docker-compose","ingress","kubernetes","kubernetes-application","microservices","microservices-example","mysql","nginx-ingress","ruby-on-rails","ruby-on-rails-api","vuejs"],"created_at":"2024-11-14T02:37:13.074Z","updated_at":"2025-06-21T01:33:31.479Z","avatar_url":"https://github.com/devteds.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Demo Application: BookStore App services on K8S \n\nFollows micro-services approach. Run locally using docker-compose and traefik as loadbalancer/proxy; and on Kubernetes (DigitalOcean Managed).\n\n\u003e ## Announcement: Course on Kubernetes\n\u003e If you're want to start deploying your containers to Kubernetes, especially on AWS EKS, [check this course on Kubernetes](https://courses.devteds.com/kubernetes-get-started) that walkthrough creating Kubernetes cluster on AWS EKS using Terraform and deploying multiple related containers applications to Kubernetes and more. https://courses.devteds.com/kubernetes-get-started\n\n![DemoStoreAppArchitecture](https://github.com/devteds/demo-app-bookstore/blob/master/doc/demo-app-architecture.png)\n\n## Code directory\n\n```\nmkdir -p ~/proj\ncd ~/proj\ngit clone git@github.com:devteds/demo-apps-on-k8s.git\n```\n\n## Run locally\n\n```\ncd ~/proj/demo-apps-on-k8s/local\n\n# one time\ndocker network create demoapp\n\ndocker-compose up\n# on a separate terminal window\ndocker-compose ps\n```\n\nOnce `shopapi` is up, run schema migration script and seed some test data\n\n```\ndocker-compose exec shopapi rails db:migrate\ndocker-compose exec shopapi rails db:seed\n```\n\nOnce all the services start up,\n\n```\nopen http://localhost\n```\n\n- http://localhost =\u003e routes to `website` service\n- Clicking on `Shop` goes to http://localhost/shop =\u003e routes to `shopui` service\n- Shopping page calls http://localhost/api/books =\u003e routes to `shopapi` service\n\n\n**Note:** You may change the port mapping if port 80 is taken on dev machine\n\n\n## On Kubernetes\n\nCreate Kubernetes cluster on DigitalOcean\n\n### DigitalOcean API Token\n\nSignup/Login to DigitalOcean and genereate API Token\n\n### Create Kubernetes Cluster\n\n```\ncd ~/proj/demo-apps-on-k8s/infra\ncp secret.auto.example.tfvars secret.auto.tfvars\n# edit to assign DigitalOcean API token and save\n```\n\nOptionally edit `main.tf` as needed. For example, if you need to change the region or number of worker nodes or kubernetes version\n\n```\nterraform init\nterraform plan\nterraform apply\n```\n\nYou may login to DigitalOcean and verify Kubernetes status.\n\nUpdate `kubeconfig` for `kubectl`\n\n```\nmkdir -p ~/.kube\nterraform output config \u003e ~/.kube/config\n```\n\nVerify Kubernetes cluster status\n\n```\nkubectl get nodes\nkubectl version\n# this must give you both client and server version. Client is kubectl. Server is K8S api server\n```\n\n### Service 1: Website\n\n```\ncd ~/proj/demo-apps-on-k8s\n\nkubectl apply -f services/website/deploy.yaml\nkubectl get deploy\nkubectl get po\n\nkubectl apply -f services/website/service.yaml\nkubectl get svc\nkubectl describe svc/website\n```\n\nVerify using port-forward\n\n```\nkubectl port-forward svc/website 8082:80\nopen http://localhost:8082\n```\n\n### Service 2: Shopping API\n\nInstall database\n\n```\nhelm install bookstore stable/mysql --set mysqlUser=appuser,mysqlPassword=appuser123,mysqlDatabase=bookstore\n\nkubectl get  svc -l app=bookstore-mysql\nkubectl get  po -l app=bookstore-mysql\nkubectl get  deploy -l app=bookstore-mysql\n```\n\nVerify\n\n```\nkubectl run -i --tty mysql-client --image=devteds/mysql-client:5.7_b1 --restart=Never -- bash -il\n\nmysql -uappuser -pappuser123 -hbookstore-mysql bookstore\n\u003e show tables;\n\u003e show databases;\n\u003e exit\n\nmysql -uappuser -pappuser123 -hbookstore-mysql.default.svc.cluster.local bookstore\n\u003e exit\n```\n\nConfigs \u0026 Secrets\n\n```\nkubectl apply -f services/shopapi/config.yaml\nkubectl get cm\nkubectl describe cm/shopapi-cm\n\nkubectl apply -f services/shopapi/secret.yaml\nkubectl get secret/shopapi-sec -o yaml\n```\n\nDatabase schema script - use Job\n\n```\nkubectl create -f services/shopapi/job-dbc.yaml\nkubectl get job -l app=shopapi-db\nkubectl describe job/shopapi-job-dbc\n\n# delete job when complete\nkubectl delete job/shopapi-job-dbc\n```\n\nDeployment \u0026 Service\n\n```\nkubectl apply -f services/shopapi/deploy.yaml\nkubectl get po -l app=shopapi\n\nkubectl apply -f services/shopapi/service.yaml\nkubectl get svc -l app=shopapi\n```\n\nVerify\n\n```\nkubectl port-forward svc/shopapi 3200:3000\nopen http://localhost:3200/api/books\n```\n\n### Service 3: Shopping UI\n\nDeploy \u0026 Service\n\n```\nkubectl apply -f services/shopui/deploy.yaml\nkubectl get po -l app=shopui\n\nkubectl apply -f services/shopui/service.yaml\nkubectl get svc -l app=shopui\n```\n\nYou may verify using port forward but let's to integrated test using ingress\n\n### Ingress Controller\n\n****Install controller:** install Ingress controller\n\n```\nkubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.1/deploy/static/mandatory.yaml\n```\n\nCreate loadbalancer services which will create LB instance on DigitialOcean and route http/https traffic to the ingress controller pod created above.\n\n```\nkubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.1/deploy/static/provider/cloud-generic.yaml\n```\n\nVerify\n\n```\nkubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx\nkubectl get svc --namespace=ingress-nginx\n```\n\nRuns a service and triggers a new loadbalancer IP of which will be assigned to this service as an external IP. Notice the type of this service is LoadBalancer.\n\nGive it a minute or so and try again,\n\n```\nkubectl get svc/ingress-nginx -n ingress-nginx\n\nNAME            TYPE           CLUSTER-IP       EXTERNAL-IP         PORT(S)                      AGE\ningress-nginx   LoadBalancer   10.245.203.250   \u003cLoadBalancer IP\u003e   80:31323/TCP,443:32325/TCP   2m\n```\n\nVerify the loadbalancer on Cloud provider web console. On Digital Ocean, under `Networking \u003e Loadbalancers`. \n\n## Ingress resource\n\nIngress resource is where we define the routing requirments and rules\n\n\n```\nkubectl apply -f route/ingress.yaml\nkubectl get ing\n```\n\n```\nLB_IP=$(kubectl get svc/ingress-nginx -n ingress-nginx | grep ingress | awk '{print $4}')\necho $LB_IP\n\n# website\nopen http://$LB_IP\n\n# shopapi\nopen http://$LB_IP/api/books\nopen http://$LB_IP/api/books/1\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevteds%2Fdemo-apps-on-k8s","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevteds%2Fdemo-apps-on-k8s","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevteds%2Fdemo-apps-on-k8s/lists"}