{"id":16895948,"url":"https://github.com/stevenacoffman/static-app-nginx-kubernetes","last_synced_at":"2025-03-23T17:30:33.599Z","repository":{"id":40946324,"uuid":"193125434","full_name":"StevenACoffman/static-app-nginx-kubernetes","owner":"StevenACoffman","description":"Containerizing a static application for Kubernetes ","archived":false,"fork":false,"pushed_at":"2024-11-20T11:37:34.000Z","size":706,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-18T05:40:35.893Z","etag":null,"topics":["kubernetes","nginx","prometheus","svelte","sveltejs"],"latest_commit_sha":null,"homepage":null,"language":"CSS","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/StevenACoffman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2019-06-21T15:56:55.000Z","updated_at":"2024-12-13T15:29:39.000Z","dependencies_parsed_at":"2024-06-22T11:47:16.551Z","dependency_job_id":"0b45bb83-2791-4b1b-9730-96f13bdab1f8","html_url":"https://github.com/StevenACoffman/static-app-nginx-kubernetes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StevenACoffman%2Fstatic-app-nginx-kubernetes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StevenACoffman%2Fstatic-app-nginx-kubernetes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StevenACoffman%2Fstatic-app-nginx-kubernetes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StevenACoffman%2Fstatic-app-nginx-kubernetes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StevenACoffman","download_url":"https://codeload.github.com/StevenACoffman/static-app-nginx-kubernetes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245140660,"owners_count":20567423,"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":["kubernetes","nginx","prometheus","svelte","sveltejs"],"created_at":"2024-10-13T17:27:09.269Z","updated_at":"2025-03-23T17:30:33.303Z","avatar_url":"https://github.com/StevenACoffman.png","language":"CSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"# static-app-nginx-kubernetes\nContainerizing a static application for Kubernetes\n\n## What the heck?\n\n\u003e Single page apps deliver fantastically rich user experiences, and they open up an entirely different avenue for continuous deployment. Separating out a front-end application from the server is a sound strategy for breaking up the responsibilities of the team. Maintaining a separate front-end code base allows teams to iterate on features quickly and interact through formalized contracts in the form of an API.\n\n\u003e Not everything about delivering static assets is so rosy though.\nFrom [Continuously Deploying Single Page Apps](https://blog.codeship.com/continuously-deploying-single-page-apps/)\n\n### Routing in a Single Page Application\nIf you are build a SPA with react, you probably use `react-router`. There's svelte and angular equivalents.\nYou should be clear that when we click on an internal link in a static app page, things are a little different\nfrom the traditional web page:\n- In a traditional static html web page, the browser will send a request to nginx server for a new html page\n  matching that url.\n- In react-router, history will listen to the url of the browser, and when it changes,\n  it will find the proper component to render, and maybe send async request to ask for data.\n\nFor example, when the single page application changes the location to `/users`, there is no static file `/users.html` to serve on nginx.\nThe browser just changes the url and renders some new component. This works great, until that URL gets bookmarked, reloaded, or shared outside the context of that running application.\n\nIn this setup, when a user bookmarks this URL, and restarts the page with the url `/users`, nginx should first try to\nfind `/users.html`. Of course NGINX fails to find this file, and so it will try to return `index.html`, and let the browser\nhandle the rest.\n\n### Continuous Integration for a Single Page Application\n\nIf you want to perform continuous integration or continuous delivery of a static (single page) application, you need an ephemeral version of it somewhere you can test against.\n\n### Multistage docker builds\n\nAn ephemeral, immutable web app container that is optimized for production is great, but the developer needs to have a richer experience without comprimising the fidelity of simulating the production environment. Rex Roof had a genius solution for this.\n\nWhen building a Dockerfile with multiple build stages, `--target` can be used to specify an intermediate build stage by name as a final stage for the resulting image. Commands after the target stage will be skipped. This way the local development container can be part of the production build pipeline, but each can be tailored for specific needs.\n\n```\nFROM node:10.15.0-alpine as development\n...\nFROM node:10.15.0-alpine as build\n...\nFROM nginx:1.15.8-alpine as production\n...\n\n$ docker build -t development --target development .\n$ docker run development\n...\n$ export GIT_REVISION=$(git rev-parse HEAD)\n$ docker build --build-arg GIT_REVISION -t \"${REPOSITORY}:${GIT_REVISION}\" .\n```\nSome other nginx configs to look at:\n+ https://github.com/h5bp/server-configs-nginx\n+ https://github.com/SaraVieira/rick-morty-random-episode/blob/master/nginx.conf\n+ https://gist.github.com/huangzhuolin/24f73163e3670b1cd327f2b357fd456a\n+ https://gist.github.com/thoop/8165802\n\n### Prometheus Metrics and Horizontal Pod Autoscaling\nAutoscaling deployments in Kubernetes is more exciting since HorizontalPodAutoscaler can scale on custom and external metrics instead of simply CPU and memory like before. Requests per second is really a better metric for scaling certain applications.\n\nThis setup has metrics available on `/metrics`\n\n## svelte-todomvc\n\n**[svelte-todomvc.surge.sh](http://svelte-todomvc.surge.sh/)**\n\n[TodoMVC](http://todomvc.com/) implemented in [Svelte](https://github.com/sveltejs/svelte). The entire app weighs 3.5kb zipped.\n\n## Where did this content actually come from (useful links):\n- https://github.com/SaraVieira/rick-morty-random-episode\n- https://github.com/sveltejs/svelte-todomvc\n- https://immutablewebapps.org/\n- https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-on-centos-7\n- https://blog.codeship.com/continuously-deploying-single-page-apps/\n- [History api](https://developer.mozilla.org/en-US/docs/Web/API/History_API)\n- [Deploy create-react-app with react-router to NGINX](https://gist.github.com/huangzhuolin/24f73163e3670b1cd327f2b357fd456a)\n- [Monitoring nginx with Prometheus and Grafana](https://g00glen00b.be/monitoring-nginx-with-prometheus-and-grafana/)\n- [Horizontal Pod Autoscale with Custom Prometheus Metrics](https://itnext.io/horizontal-pod-autoscale-with-custom-metrics-8cb13e9d475)\n- [Kubernetes HPA Autoscaling with Custom and External Metrics](https://medium.com/uptime-99/kubernetes-hpa-autoscaling-with-custom-and-external-metrics-da7f41ff7846)\n- Rex Roof at Blue Newt made the snazzy multistage docker image\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstevenacoffman%2Fstatic-app-nginx-kubernetes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstevenacoffman%2Fstatic-app-nginx-kubernetes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstevenacoffman%2Fstatic-app-nginx-kubernetes/lists"}