{"id":17651014,"url":"https://github.com/g-mark/test-nginx-vapor","last_synced_at":"2025-03-30T08:27:19.113Z","repository":{"id":91822557,"uuid":"241232156","full_name":"g-mark/test-nginx-vapor","owner":"g-mark","description":"Example of putting NGiNx in front of Vapor on Heroku","archived":false,"fork":false,"pushed_at":"2020-03-01T23:59:12.000Z","size":59,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-05T10:34:38.421Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","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/g-mark.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}},"created_at":"2020-02-17T23:48:16.000Z","updated_at":"2020-03-01T23:59:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"43e9b31f-5808-4064-94fa-2cb7f868de7d","html_url":"https://github.com/g-mark/test-nginx-vapor","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/g-mark%2Ftest-nginx-vapor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/g-mark%2Ftest-nginx-vapor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/g-mark%2Ftest-nginx-vapor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/g-mark%2Ftest-nginx-vapor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/g-mark","download_url":"https://codeload.github.com/g-mark/test-nginx-vapor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246293787,"owners_count":20754320,"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":[],"created_at":"2024-10-23T11:39:59.686Z","updated_at":"2025-03-30T08:27:19.107Z","avatar_url":"https://github.com/g-mark.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# test-nginx-vapor\nExample of putting NGiNx in front of Vapor on Heroku\n\nThere are two requests handled by NGiNx:\n\n```\n/index.html\n/other.html\n```\n\nThere are two Vapor routes:\n\n```\n/\n/hello/:string\n```\n\nThe setup of this branch is that NGiNx will try for a static file and deliver that.  If it can't find a static file, it will pass the request on to Vapor.  This means that all 404 errors are handled by Vapor.\n\n#### Heroku setup\n\n1. Create an app\n2. Add official ngnix buildpack, I used:  \n   [Heroku Buildpack: NGINX](https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-nginx)  \n   `heroku-community/nginx` (or https://github.com/heroku/heroku-buildpack-nginx.git)\n3. Add official Vapor buildpack - I used:  \n   [Heroku buildpack: swift](https://elements.heroku.com/buildpacks/vapor-community/heroku-buildpack)  \n   `vapor/vapor`\n4. Grab the app's git URL.  (in `Settings`, something like `https://git.heroku.com/YOUR-APP-NAME-HERE.git`)\n5. Fork this repo, clone it locally\n6. Add your app's git URL as an origin for you local repo\n7. Push the repo to the Heroku origin.\n   This will deploy the app.\n\n#### How it works\n\nWhen code is pushed to the app's git repo, Heroku will run a post_receive hook that triggers each of the buildpacks added to the app, in the order that they are listed in your `Settings` pane.  This also happens to be the same order that they were added in the above steps: `ngnix` then `vapor`.\n\nOnce both buildpacks have finished building, the `Procfile` is executed.\n\nThe `Procfile` in this repo has a single line, that runs two commands:\n```\nweb: bin/start-nginx Run serve --env production --port 8080 --hostname 0.0.0.0\n```\n\n- `bin/start-nginx` starts ngnix\n- `Run serve --env production --port 8080 --hostname 0.0.0.0` runs the vapor app.\n\nWhen ngnix is built, it uses the config file at `config/nginx.conf.erb` as the primary configuration for the ngnix server.  Towards the bottom of the file is where you'll find the magic sauce:\n\n```\n   root /app/Public;\n   \n   # Serve all public/static files via nginx and then fallback to Vapor for the rest\n   try_files $uri @proxy;\n   \n   location @proxy {\n      proxy_pass http://127.0.0.1:8080;\n      proxy_pass_header Server;\n      proxy_set_header Host $host;\n      proxy_set_header X-Real-IP $remote_addr;\n      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n      proxy_connect_timeout 3s;\n      proxy_read_timeout 10s;\n      proxy_redirect off;\n   }\n```\n\nSo, when a URL is requested, ngnix will see if there's a file it can deliver from the `Public` directory (everything in the git repo is installed at `/app`, so the `root /app/Public` directive in the config file points to our `Public` directory as the root of the web server).  If it can't find a file, it'll pas the URL on to the Vapor app.\n\nNGiNx listens on the normal http port (80), and when needed, proxies the requests on to port 8080, where the Vapor app is listening.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fg-mark%2Ftest-nginx-vapor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fg-mark%2Ftest-nginx-vapor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fg-mark%2Ftest-nginx-vapor/lists"}