{"id":13490006,"url":"https://github.com/lebinh/nginx-conf","last_synced_at":"2025-04-09T05:01:30.805Z","repository":{"id":27070984,"uuid":"30537345","full_name":"lebinh/nginx-conf","owner":"lebinh","description":"A collection of useful Nginx configuration snippets","archived":false,"fork":false,"pushed_at":"2017-10-13T14:36:47.000Z","size":205,"stargazers_count":2127,"open_issues_count":2,"forks_count":351,"subscribers_count":83,"default_branch":"master","last_synced_at":"2025-04-02T04:01:34.400Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"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/lebinh.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}},"created_at":"2015-02-09T13:36:26.000Z","updated_at":"2025-03-27T20:03:20.000Z","dependencies_parsed_at":"2022-08-17T19:05:12.988Z","dependency_job_id":null,"html_url":"https://github.com/lebinh/nginx-conf","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/lebinh%2Fnginx-conf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lebinh%2Fnginx-conf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lebinh%2Fnginx-conf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lebinh%2Fnginx-conf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lebinh","download_url":"https://codeload.github.com/lebinh/nginx-conf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247980815,"owners_count":21027804,"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-07-31T19:00:39.238Z","updated_at":"2025-04-09T05:01:30.749Z","avatar_url":"https://github.com/lebinh.png","language":null,"funding_links":[],"categories":["Others","Books and Tutorials","tech","Third Modules","Tools"],"sub_categories":["C Modules","Lua Modules"],"readme":"# Nginx Configuration Snippets\nA collection of useful Nginx configuration snippets inspired by\n[.htaccess snippets](https://github.com/phanan/htaccess).\n\n## Table of Contents\n- [The Nginx Command](#the-nginx-command)\n- [Rewrite and Redirection](#rewrite-and-redirection)\n    - [Force www](#force-www)\n    - [Force no-www](#force-no-www)\n    - [Force HTTPS](#force-https)\n    - [Force Trailing Slash](#force-trailing-slash)\n    - [Redirect a Single Page](#redirect-a-single-page)\n    - [Redirect an Entire Site](#redirect-an-entire-site)\n    - [Redirect an Entire Sub Path](#redirect-an-entire-sub-path)\n- [Performance](#performance)\n    - [Contents Caching](#contents-caching)\n    - [Gzip Compression](#gzip-compression)\n    - [Open File Cache](#open-file-cache)\n    - [SSL Cache](#ssl-cache)\n    - [Upstream Keepalive](#upstream-keepalive)\n- [Monitoring](#monitoring)\n- [Security](#security)\n    - [Enable Basic Authentication](#enable-basic-authentication)\n    - [Only Allow Access From Localhost](#only-allow-access-from-localhost)\n    - [Secure SSL settings](#secure-ssl-settings)\n- [Miscellaneous](#miscellaneous)\n    - [Sub-Request Upon Completion](#sub-request-upon-completion)\n    - [Enable Cross Origin Resource Sharing](#enable-cross-origin-resource-sharing)\n- [Links](#links)\n\n## The Nginx Command\nThe `nginx` command can be used to perform some useful actions when Nginx is running.\n\n- Get current Nginx version and its configured compiling parameters: `nginx -V`\n- Test the current Nginx configuration file and / or check its location: `nginx -t`\n- Reload the configuration without restarting Nginx: `nginx -s reload`\n\n\n## Rewrite and Redirection\n\n### Force www\nThe [right way](http://nginx.org/en/docs/http/converting_rewrite_rules.html)\nis to define a separated server for the naked domain and redirect it.\n```nginx\nserver {\n    listen 80;\n    server_name example.org;\n    return 301 $scheme://www.example.org$request_uri;\n}\n\nserver {\n    listen 80;\n    server_name www.example.org;\n    ...\n}\n```\n\nNote that this also works with HTTPS site.\n\n### Force no-www\nAgain, the right way is to define a separated server for the www domain and redirect it.\n```nginx\nserver {\n    listen 80;\n    server_name example.org;\n}\n\nserver {\n    listen 80;\n    server_name www.example.org;\n    return 301 $scheme://example.org$request_uri;\n}\n```\n\n### Force HTTPS\nThis is also handled by the 2 server blocks approach.\n```nginx\nserver {\n    listen 80;\n    return 301 https://$host$request_uri;\n}\n\nserver {\n    listen 443 ssl;\n\n    # let the browsers know that we only accept HTTPS\n    add_header Strict-Transport-Security max-age=2592000;\n\n    ...\n}\n```\n\n### Force Trailing Slash\nThis configuration only add trailing slash to URL that does not contain a dot because you probably don't want to add that trailing slash to your static files.\n[Source](http://stackoverflow.com/questions/645853/add-slash-to-the-end-of-every-url-need-rewrite-rule-for-nginx).\n```nginx\nrewrite ^([^.]*[^/])$ $1/ permanent;\n```\n\n### Redirect a Single Page\n```nginx\nserver {\n    location = /oldpage.html {\n        return 301 http://example.org/newpage.html;\n    }\n}\n```\n\n### Redirect an Entire Site\n```nginx\nserver {\n    server_name old-site.com\n    return 301 $scheme://new-site.com$request_uri;\n}\n```\n\n### Redirect an Entire Sub Path\n```nginx\nlocation /old-site {\n    rewrite ^/old-site/(.*) http://example.org/new-site/$1 permanent;\n}\n```\n\n\n## Performance\n\n### Contents Caching\nAllow browsers to cache your static contents for basically forever. Nginx will set both `Expires` and `Cache-Control` header for you.\n```nginx\nlocation /static {\n    root /data;\n    expires max;\n}\n```\n\nIf you want to ask the browsers to **never** cache the response (e.g. for tracking requests), use `-1`.\n```nginx\nlocation = /empty.gif {\n    empty_gif;\n    expires -1;\n}\n```\n\n### Gzip Compression\n```nginx\ngzip  on;\ngzip_buffers 16 8k;\ngzip_comp_level 6;\ngzip_http_version 1.1;\ngzip_min_length 256;\ngzip_proxied any;\ngzip_vary on;\ngzip_types\n    text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml\n    text/javascript application/javascript application/x-javascript\n    text/x-json application/json application/x-web-app-manifest+json\n    text/css text/plain text/x-component\n    font/opentype application/x-font-ttf application/vnd.ms-fontobject\n    image/x-icon;\ngzip_disable  \"msie6\";\n```\n\n### Open File Cache\nIf you have _a lot_ of static files to serve through Nginx then caching of the files' metadata (not the actual files' contents) can save some latency.\n```nginx\nopen_file_cache max=1000 inactive=20s;\nopen_file_cache_valid 30s;\nopen_file_cache_min_uses 2;\nopen_file_cache_errors on;\n```\n\n### SSL Cache\nEnable SSL cache for SSL sessions resumption, so that sub sequent SSL/TLS connection handshakes can be shortened and reduce total SSL overhead.\n```nginx\nssl_session_cache shared:SSL:10m;\nssl_session_timeout 10m;\n```\n\n### Upstream Keepalive\nEnable the upstream connection cache for better reuse of connections to upstream servers. [Source](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive).\n```nginx\nupstream backend {\n    server 127.0.0.1:8080;\n    keepalive 32;\n}\n\nserver {\n    ...\n    location /api/ {\n        proxy_pass http://backend;\n        proxy_http_version 1.1;\n        proxy_set_header Connection \"\";\n    }\n}\n```\n\n\n## Monitoring\n\nThe [Stub Status](http://nginx.org/en/docs/http/ngx_http_stub_status_module.html), which is not built by default, is a very simple to setup module but only provide basic status of Nginx.\n```nginx\nlocation /status {\n    stub_status on;\n    access_log off;\n}\n```\n\nIt provides the following status for the whole Nginx server in plain text(!) format:\n- Client connections: accepted, handled, active (includes reading, writing and waiting).\n- Total number of client requests.\n\n**[Shameless Plug]** A _better_ way to capture Nginx status can be added by using [Luameter](https://luameter.com) which is a bit more complicated to setup and required the Nginx Lua module (which is awesome). It provides following metrics for each [configurable group](https://luameter.com/configuration) as a JSON API:\n- Total number of requests / responses.\n- Total number of responses groupped by status code: 1xx, 2xx, 3xx, 4xx, 5xx.\n- Total bytes received from / sent to client.\n- Sampled latency snapshot for estimation of: mean, max, median, 99th percentile, etc., latency.\n- Moving average rate of requests for easier monitoring and predicting.\n- And [some more](https://luameter.com/metrics).\n\n[Here is a sample dashboard built with Luameter's metrics](https://luameter.com/demo).\n\n[ngxtop](https://github.com/lebinh/ngxtop) is also a good way to check for Nginx status and checking / troubleshooting a live server.\n\n\n## Security\n\n### Enable Basic Authentication\nYou will need a user password file somewhere first.\n```\nname:{PLAIN}plain-text-password\n```\n\nThen add below config to `server`/`location` block that need to be protected.\n```nginx\nauth_basic \"This is Protected\";\nauth_basic_user_file /path/to/password-file;\n```\n\n### Only Allow Access From Localhost\n```nginx\nlocation /local {\n    allow 127.0.0.1;\n    deny all;\n    ...\n}\n```\n\n### Secure SSL settings\n- Disable SSLv3 which is enabled by default. This prevents [POODLE SSL Attack](http://nginx.com/blog/nginx-poodle-ssl/).\n- Ciphers that best allow protection from Beast. [Mozilla Server Side TLS and Nginx]( https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx)\n```nginx\n# don’t use SSLv3 ref: POODLE CVE-2014-356 - http://nginx.com/blog/nginx-poodle-ssl/\nssl_protocols  TLSv1 TLSv1.1 TLSv1.2;  \n\n# Ciphers set to best allow protection from Beast, while providing forwarding secrecy, as defined by Mozilla (Intermediate Set) - https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx\n    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';\nssl_prefer_server_ciphers  on;\n\n```\n\n## Miscellaneous\n\n### Sub-Request Upon Completion\nThere are some cases that you want to pass the request to another backend _in addition to and after_ serving it. One use case is to track the number of completed downloads by calling an API after user completed download a file. Another use case is for tracking request where you want to return as fast as possible (perhaps with an `empty_gif`) and then do the actual recording in background. The [post_action](http://wiki.nginx.org/HttpCoreModule#post_action) that allows you to define a sub-request that will be fired upon completion of the current request are [perfect solution](http://mailman.nginx.org/pipermail/nginx/2008-April/004524.html) for these use cases.\n```nginx\nlocation = /empty.gif {\n    empty_gif;\n    expires -1;\n    post_action @track; \n}\n\nlocation @track {\n    internal;\n    proxy_pass http://tracking-backend;\n}\n```\n\n### Enable Cross Origin Resource Sharing\nSimple, wide-open configuration to allow cross-domain requests to your server.\n```nginx\nlocation ~* \\.(eot|ttf|woff) {\n    add_header Access-Control-Allow-Origin *;\n}\n```\n\n\n## Links\nSome other awesome resources for configuring Nginx:\n\n- [Nginx Official Guide](http://nginx.com/resources/admin-guide/)\n- [HTML 5 Boilerplate's Sample Nginx Configuration](https://github.com/h5bp/server-configs-nginx)\n- [Nginx Pitfalls](http://wiki.nginx.org/Pitfalls)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flebinh%2Fnginx-conf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flebinh%2Fnginx-conf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flebinh%2Fnginx-conf/lists"}