├── .gitignore
├── LICENSE
├── README.md
├── conf.d
├── custom-nginx
├── default.conf
└── example.com
├── docker-compose.yml
├── nginx-amplify.yml
├── snippets
├── certbot-standalone.conf
├── certbot-webroot.conf
├── proxy.conf
└── ssl.conf
├── ssl
└── cli.ini
├── swarm-scripts
├── certbot-certonly.sh
├── certbot-renew.sh
├── certbot.sh
├── nginx-test.sh
├── nginx-update.sh
└── stack-deploy.sh
└── swarm.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | conf.d/*
2 | !conf.d/custom-nginx
3 | !conf.d/default.conf
4 | !conf.d/example.com
5 | ssl
6 | !ssl/cli.ini
7 | ssl-log
8 | www
9 | geoip
10 | protect
11 | snippets/*
12 | !snippets/certbot-standalone.conf
13 | !snippets/certbot-webroot.conf
14 | !snippets/proxy.conf
15 | !snippets/ssl.conf
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Nginx-Proxy
2 |
3 | This docker-compose.yml users the **official nginx** and the **official certbot** container. It has optimized nginx configuration to be used as a https proxy together with certbot. Following my instructions you should get an A+ rating at [ssllabs.com](https://www.ssllabs.com/ssltest).
4 |
5 | The container will use the network **www-network** as a proxy-tier. Add every container to this network that servers as a upstream http host.
6 |
7 | ### Table of Contents
8 | **[How To Use](#how-to-use)**
9 | **[Docker Swarm](#docker-swarm)**
10 | **[Update](#update)**
11 | **[Nginx](#nginx)**
12 | **[Let's Encrypt SSL Certificates](#lets-encrypt-ssl-certificates)**
13 | **[Let's Encrypt SSL Certificates on Swarm Mode](#lets-encrypt-ssl-certificates-on-swarm-mode)**
14 | **[Get A+ SSL Rating](#get-a-ssl-rating)**
15 | **[Password protection](#password-protection)**
16 | **[IP-based protection](#ip-based-protection)**
17 | **[GeoIP blocking](#geoip-blocking)**
18 |
19 | ## Directory structure
20 |
21 | ```
22 | .
23 | ├── conf.d # Site-specific configuration
24 | │ ├── example.com.conf
25 | │ ├── ...
26 | ├── protect # HTTP Password Protection
27 | │ ├── .htpasswd
28 | ├── snippets # Config we want to reuse at conf.d files
29 | │ ├── certbot-webroot.conf # Serves Let's encrypt .well-known files
30 | │ ├── certbot-standalone.conf # as alternative method
31 | │ ├── proxy.conf
32 | │ ├── ssl.conf
33 |
34 | ```
35 |
36 | ## How To Use
37 |
38 | ### 1. Clone this repo
39 |
40 | ```bash
41 | mkdir -p /docker/00-nginx-proxy
42 | cd /docker/00-nginx-proxy
43 | git clone https://github.com/sebastian13/docker-compose-nginx-proxy.git .
44 | ```
45 |
46 | ### 2. Prepare for SSL
47 | ```bash
48 | mkdir -p ./ssl/test
49 | openssl req -x509 -nodes -days 3650 -newkey rsa:4096 \
50 | -keyout ./ssl/test/selfsigned.key \
51 | -out ./ssl/test/selfsigned.crt
52 | # Optional, run in a separate session
53 | screen
54 | openssl dhparam -out ssl/dhparams4096.pem 4096
55 | ```
56 |
57 | ### 3. Create your site's config
58 | ```bash
59 | cp conf.d/{example.com,yoursite.com.conf}
60 | ```
61 | Replace *example.com* with your domain, and set your *$upstream container*.
62 |
63 | ### 4. Enable recommended http settings
64 | ```bash
65 | cp conf.d/custom-nginx{,.conf}
66 | ```
67 |
68 | ### 5. Create docker network www-network
69 | ```bash
70 | docker network create www-network
71 | ```
72 |
73 | ### 6. Ready to go
74 | ```bash
75 | docker compose up -d
76 | ```
77 |
78 | ## Docker Swarm
79 |
80 | To run this project on a docker stack, skip 5. and 6. and continue here:
81 |
82 | ### 0. Network
83 | If you previously used the `www-network`, stop all containers and remove the network. The stack will recreate the network in swarm scope.
84 |
85 | ```bash
86 | docker stop $(docker ps -q)
87 | docker network remove www-network
88 | ```
89 |
90 | ### 1. Create Swarm
91 | ```bash
92 | docker swarm init
93 | ```
94 |
95 | ### 2. Deploy Stack
96 | ```bash
97 | docker stack deploy proxystack -c swarm.yml
98 |
99 | # Alternatively, run the helper script
100 | cd swarm-scripts
101 | ./stack-deploy.sh
102 | ```
103 |
104 |
105 | ## Update
106 |
107 | To get the most recent version of this repo run:
108 |
109 | ```
110 | git fetch --all && \
111 | git reset --hard origin/master && \
112 | docker compose pull && \
113 | docker compose down && \
114 | docker compose up -d
115 | ```
116 |
117 | ## Nginx
118 |
119 | I'm using the [official nginx container](https://hub.docker.com/_/nginx/) here. All volumes will be mounted read-only.
120 |
121 | ### Manually reload the configuration
122 | As you change site-specific configuration in *conf.d*, you should consider reloading the configuration instead of restarting the container. This is because your container will not start if the configuration contains errors.
123 |
124 | ```
125 | docker exec nginx-proxy nginx -s reload
126 | ```
127 |
128 | ### Amplify Agent
129 | You can use the free monitoring tool [NGINX Amplify](https://amplify.nginx.com) the following way:
130 |
131 | 1. Create a **amplify.env** containing
132 |
133 | ```
134 | AMPLIFY_IMAGENAME=example.com
135 | API_KEY=123456
136 | ```
137 |
138 | 2. Start the container the following way:
139 |
140 | ```
141 | docker compose -f nginx-amplify.yml up -d --build
142 | ```
143 |
144 | ## Let's Encrypt SSL Certificates
145 |
146 | *If using docker swarm, jump to [Let's Encrypt SSL Certificates on Swarm Mode](#lets-encrypt-ssl-certificates-on-swarm-mode)*
147 |
148 | ### Request a new Certificate
149 |
150 | ```
151 | docker compose run --rm certbot certonly \
152 | --agree-tos --no-eff-email --hsts --webroot -w /var/www \
153 | --rsa-key-size 4096 --cert-name=example.com \
154 | -m mail@example.com -d example.com
155 | ```
156 |
157 | Then, link the certificate in your nginx site.conf + reload the nginx-proxy.
158 |
159 |
160 | ### List existing Certificates
161 | ```shell
162 | docker compose run --rm certbot certificates
163 | ```
164 |
165 | ### Delete existing Certificates
166 | ```shell
167 | docker compose run --rm certbot delete --cert-name example.com
168 | ```
169 |
170 | ### Renew Certificates
171 |
172 | Define a Cronjob like this, to renew the certificates periodically. Use chronic from [moreutils](https://manpages.debian.org/jessie/moreutils/chronic.1.en.html) if you like.
173 |
174 | ```
175 | 0 0 * * * cd /docker/00-nginx-proxy && chronic docker compose run --rm --use-aliases certbot renew && chronic docker exec nginx-proxy nginx -s reload
176 | ```
177 |
178 | To manually check your certificates for renewal run `docker compose up certbot`.
179 |
180 | ## Let's Encrypt SSL Certificates on Swarm Mode
181 |
182 | ### Request a new Certificate
183 |
184 | ```
185 | ./swarm-scripts/certbot-certonly.sh -m mail@example.com -d example.com -d www.example.co
186 | ```
187 |
188 | ### List existing Certificates
189 | ```shell
190 | ./swarm-scripts/certbot.sh certificates
191 | ```
192 |
193 | ### Delete existing Certificates
194 | ```shell
195 | ./swarm-scripts/certbot.sh delete --cert-name example.com
196 | ```
197 |
198 | ### Renew Certificates
199 |
200 | ```shell
201 | ./swarm-scripts/certbot-renew.sh
202 | ```
203 |
204 | Define a Cronjob like this, to renew the certificates periodically. Use chronic from [moreutils](https://manpages.debian.org/jessie/moreutils/chronic.1.en.html) if you like.
205 |
206 | ```
207 | 0 0 * * * chronic /docker/00-nginx-proxy/swarm-scripts/certbot-renew.sh
208 | ```
209 |
210 | ## Get A+ SSL Rating
211 |
212 | 1. Generate your own Diffie-Hellman parameters. Put it inside the directory **ssl**.
213 |
214 | `openssl dhparam -out ssl/dhparams4096.pem 4096`
215 |
216 | 2. Include the **ssl.conf snippet** at your site specific configuration. Also, include the **ssl\_trusted\_certificate**.
217 |
218 | ```
219 | server {
220 | ...
221 | ssl_trusted_certificate /etc/nginx/ssl/live/example.com/chain.pem;
222 | include /etc/nginx/snippets/ssl.conf;
223 | ...
224 | }
225 | ```
226 |
227 | ## Password protection
228 |
229 | To protect your site with basic http authentication, create a .htpasswd file, spin up an apache container by running the following.
230 |
231 | ```bash
232 | docker run -i --rm -v /docker/00-nginx-proxy/protect:/etc/nginx/protect httpd /bin/bash
233 | ```
234 |
235 | For every user run the following. You will be asked to supply and confirm a password.
236 |
237 | ```bash
238 | htpasswd -c /etc/nginx/protect/.htpasswd first_user
239 | htpasswd /etc/nginx/protect/.htpasswd another_user
240 | ```
241 |
242 | In the site's .conf file add the following.
243 |
244 | ```
245 | server {
246 | ...
247 | location / {
248 | auth_basic "Restricted Content";
249 | auth_basic_user_file /etc/nginx/protect/.htpasswd;
250 | }
251 | }
252 | ```
253 |
254 | You can find detailed instructions at [digitalocean](https://www.digitalocean.com/community/tutorials/how-to-set-up-password-authentication-with-nginx-on-ubuntu-14-04)
255 |
256 | ## IP based protection
257 |
258 | Add your IP Address to the domain's .conf file, and deny everyone else.
259 |
260 | ```
261 | server {
262 | ...
263 | location / {
264 | allow 1.2.3.4;
265 | deny all;
266 | }
267 | }
268 | ```
269 |
270 | ## GeoIP blocking
271 |
272 | ```
273 | mkdir geoip
274 | cd geoip
275 | curl -O https://centminmod.com/centminmodparts/geoip-legacy/GeoIP.dat.gz
276 | curl -o GeoLiteCity.dat.gz https://centminmod.com/centminmodparts/geoip-legacy/GeoLiteCity.gz
277 | gunzip *.gz
278 | ```
279 |
280 | add to nginx.conf after pid ... :
281 |
282 | ```
283 | load_module modules/ngx_http_geoip_module.so;
284 | ```
285 |
286 |
--------------------------------------------------------------------------------
/conf.d/custom-nginx:
--------------------------------------------------------------------------------
1 | ## Additional http settings
2 |
3 | # hide server information
4 | server_tokens off;
5 |
6 | # Enable gzip
7 | gzip on;
8 | gzip_vary on;
9 | gzip_min_length 1024;
10 | gzip_proxied expired no-cache no-store private auth;
11 | gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
12 | gzip_disable "MSIE [1-6]\.";
13 |
--------------------------------------------------------------------------------
/conf.d/default.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80 default_server;
3 | listen [::]:80 default_server ipv6only=on;
4 |
5 | listen 443 ssl default_server;
6 | listen [::]:443 ssl default_server ipv6only=on;
7 | http2 on;
8 |
9 | # Catch-all
10 | server_name _;
11 |
12 | # Serve Let's Ecnrypt verification files
13 | include /etc/nginx/snippets/certbot-standalone.conf;
14 |
15 | # Self signed cert as a fallback and to handle the 'no "ssl_certificate" is defined' error log message
16 | ssl_certificate /etc/nginx/ssl/test/selfsigned.crt;
17 | ssl_certificate_key /etc/nginx/ssl/test/selfsigned.key;
18 |
19 | # Return nothing
20 | location / {
21 | return 444;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/conf.d/example.com:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | listen [::]:80;
4 | server_name example.com;
5 |
6 | include /etc/nginx/snippets/certbot-standalone.conf;
7 |
8 | # Discourage deep links by using a permanent redirect to home page of HTTPS site
9 | # return 301 https://$host;
10 |
11 | # Alternatively, redirect all HTTP links to the matching HTTPS page
12 | location / {
13 | return 301 https://$host$request_uri;
14 | }
15 | }
16 |
17 | server {
18 | server_name example.com;
19 | listen 443 ssl;
20 | http2 on;
21 |
22 | # ssl_certificate /etc/nginx/ssl/live/example.com/fullchain.pem;
23 | # ssl_certificate_key /etc/nginx/ssl/live/example.com/privkey.pem;
24 | # ssl_trusted_certificate /etc/nginx/ssl/live/example.com/chain.pem;
25 |
26 | include /etc/nginx/snippets/ssl.conf;
27 | include /etc/nginx/snippets/certbot-standalone.conf;
28 |
29 | location / {
30 | # Optional IP based restriction
31 | # allow 1.2.3.4;
32 | # deny all;
33 |
34 | # Optional Password protection
35 | # auth_basic "Restricted Content";
36 | # auth_basic_user_file /etc/nginx/protect/.htpasswd;
37 |
38 | # Upstream
39 | resolver 127.0.0.11 valid=30s;
40 | set $upstream container_name;
41 | proxy_pass http://$upstream;
42 |
43 | include /etc/nginx/snippets/proxy.conf;
44 |
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | ### NGINX-PROXY
2 | ###
3 | ### Author: Sebastian Plocek
4 | ### https://github.com/sebastian13/docker-compose-nginx-proxy
5 |
6 | services:
7 | nginx-proxy:
8 | image: nginx
9 | container_name: nginx-proxy
10 | restart: always
11 | ports:
12 | - "443:443"
13 | - "80:80"
14 | volumes:
15 | - ./www:/var/www:ro
16 | - ./conf.d:/etc/nginx/conf.d:ro
17 | - ./ssl:/etc/nginx/ssl:ro
18 | - ./snippets:/etc/nginx/snippets:ro
19 | - ./protect:/etc/nginx/protect:ro
20 |
21 | # Let's Encrypt / Certbot
22 | # Check README.md to know how to issue new certs.
23 | certbot:
24 | image: certbot/certbot
25 | container_name: certbot
26 | depends_on:
27 | - nginx-proxy
28 | volumes:
29 | - ./ssl:/etc/letsencrypt
30 | - ./ssl-log:/var/log/letsencrypt
31 | - ./www/.well-known:/var/www/.well-known
32 | profiles:
33 | - certbot
34 | command: [
35 | "renew",
36 | ]
37 |
38 | # Use the same external network in $upstream containers.
39 | networks:
40 | default:
41 | name: www-network
42 | external: true
43 |
--------------------------------------------------------------------------------
/nginx-amplify.yml:
--------------------------------------------------------------------------------
1 | ### NGINX-PROXY with Amplify Agent
2 | ###
3 | ### Author: Sebastian Plocek
4 | ### https://github.com/sebastian13/docker-compose-nginx-proxy
5 |
6 | version: '3'
7 |
8 | services:
9 | nginx-proxy:
10 | image: nginx-amplify
11 | build:
12 | context: https://github.com/nginxinc/docker-nginx-amplify.git
13 | container_name: nginx-proxy
14 | restart: always
15 | ports:
16 | - "443:443"
17 | - "80:80"
18 | volumes:
19 | - ./www:/var/www:ro
20 | - ./conf.d:/etc/nginx/conf.d:ro
21 | - ./ssl:/etc/nginx/ssl:ro
22 | - ./snippets:/etc/nginx/snippets:ro
23 | - ./protect:/etc/nginx/protect:ro
24 | networks:
25 | - proxy-tier
26 | env_file:
27 | - ./amplify.env
28 |
29 | # Let's Encrypt / Certbot
30 | # Check README.md to know how to issue new certs.
31 | certbot:
32 | image: certbot/certbot
33 | container_name: certbot
34 | depends_on:
35 | - nginx-proxy
36 | volumes:
37 | - ./ssl:/etc/letsencrypt
38 | - ./ssl-log:/var/log/letsencrypt
39 | - ./www/.well-known:/var/www/.well-known
40 | command: [
41 | "renew",
42 | ]
43 |
44 | # Use the same external network in $upstream containers.
45 | networks:
46 | proxy-tier:
47 | external:
48 | name: www-network
--------------------------------------------------------------------------------
/snippets/certbot-standalone.conf:
--------------------------------------------------------------------------------
1 | location ^~ /.well-known/acme-challenge/ {
2 | default_type "text/plain";
3 | resolver 127.0.0.11 valid=30s;
4 | set $certbot certbot:80;
5 | proxy_pass http://$certbot;
6 | }
7 |
--------------------------------------------------------------------------------
/snippets/certbot-webroot.conf:
--------------------------------------------------------------------------------
1 | location ^~ /.well-known/acme-challenge/ {
2 | default_type "text/plain";
3 | alias /var/www/.well-known/acme-challenge/;
4 | }
5 |
--------------------------------------------------------------------------------
/snippets/proxy.conf:
--------------------------------------------------------------------------------
1 | proxy_set_header Host $host;
2 | proxy_set_header X-Forwarded-For $remote_addr;
3 | proxy_set_header X-Real-IP $remote_addr;
4 | proxy_set_header X-Forwarded-Proto $scheme;
5 | proxy_buffering off;
6 |
--------------------------------------------------------------------------------
/snippets/ssl.conf:
--------------------------------------------------------------------------------
1 | # To generate run 'openssl dhparam -out ssl/dhparams4096.pem 4096'
2 | ssl_dhparam /etc/nginx/ssl/dhparams4096.pem;
3 |
4 | # SSL session cache
5 | ssl_session_timeout 1h;
6 | ssl_session_cache shared:SSL:5m;
7 | ssl_session_tickets off;
8 |
9 | # TLS Support
10 | ssl_protocols TLSv1.2 TLSv1.3;
11 | ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM';
12 | ssl_prefer_server_ciphers on;
13 | ssl_ecdh_curve secp384r1;
14 |
15 | # OCSP Stapling
16 | ssl_stapling on;
17 | ssl_stapling_verify on;
18 | resolver 127.0.0.11 ipv6=off valid=600s;
19 | resolver_timeout 5s;
20 |
21 | # Reduce ssl buffer size
22 | ssl_buffer_size 4k;
23 |
24 | # Enable HSTS
25 | add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains; preload';
26 |
27 | # Prevent the browser from doing MIME-type sniffing
28 | add_header X-Content-Type-Options nosniff;
29 |
30 | # Avoid click-jacking attacks
31 | # The frame-ancestors directive obsoletes the X-Frame-Options header.
32 | add_header Content-Security-Policy "frame-ancestors 'self';";
33 |
--------------------------------------------------------------------------------
/ssl/cli.ini:
--------------------------------------------------------------------------------
1 | # Certbot's global configuration file
2 | # https://certbot.eff.org/docs/using.html#configuration-file
3 |
4 | # Use a 4096 bit RSA key instead of 2048
5 | rsa-key-size = 4096
--------------------------------------------------------------------------------
/swarm-scripts/certbot-certonly.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | #
5 | # This helper requests a new certificate by running
6 | # ./certbot-certonly.sh -m mail@example.com -d example.com -d www.example.com
7 | #
8 |
9 | # If no argument is passed, display help
10 | if [ $# -eq 0 ]
11 | then
12 | echo "To request a new certificate run:"
13 | echo "./certbot-certonly.sh -m mail@example.com -d example.com -d www.example.co"
14 | exit
15 | fi
16 |
17 | docker run -it --rm \
18 | --name="certbot" \
19 | --network="www-network" \
20 | -v /docker/00-nginx-proxy/ssl:/etc/letsencrypt \
21 | -v /docker/00-nginx-proxy/ssl-log:/var/log/letsencrypt \
22 | certbot/certbot certonly --standalone \
23 | --agree-tos --no-eff-email --hsts --rsa-key-size 4096 \
24 | $@
25 |
26 | scriptPath="$(dirname "$0")"
27 | source $scriptPath/nginx-test.sh
28 | source $scriptPath/nginx-update.sh
29 |
--------------------------------------------------------------------------------
/swarm-scripts/certbot-renew.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | #
5 | # Renews existing certificates, tests the nginx configuration
6 | # and restarts the nginx proxy service on all nodes
7 | #
8 |
9 | docker run --rm \
10 | --name="certbot" \
11 | --network="www-network" \
12 | -v /docker/00-nginx-proxy/ssl:/etc/letsencrypt \
13 | -v /docker/00-nginx-proxy/ssl-log:/var/log/letsencrypt \
14 | certbot/certbot renew \
15 | --standalone
16 |
17 | scriptPath="$(dirname "$0")"
18 | source $scriptPath/nginx-update.sh
19 |
--------------------------------------------------------------------------------
/swarm-scripts/certbot.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | #
5 | # Run an arbitrary certbot. Use
6 | # ./certbot.sh help
7 | # to display available commands.
8 | #
9 | # Use
10 | # ./certbot.sh certificates
11 | # to list existing certificates
12 | #
13 |
14 | # If no argument is passed, display help
15 | if [ $# -eq 0 ]
16 | then
17 | echo "Run an arbitrary certbot command, e.g.:"
18 | echo " > ./certbot.sh help ... to display help"
19 | echo " > ./certbot.sh certificates ... to list certificates"
20 | exit
21 | fi
22 |
23 | docker run -it --rm \
24 | --name="certbot" \
25 | --network="www-network" \
26 | -v /docker/00-nginx-proxy/ssl:/etc/letsencrypt \
27 | -v /docker/00-nginx-proxy/ssl-log:/var/log/letsencrypt \
28 | certbot/certbot $@
29 |
--------------------------------------------------------------------------------
/swarm-scripts/nginx-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Test the nginx configuration on the current node
5 | #
6 |
7 | SERVICE="proxystack_nginx"
8 | docker exec -it $(docker ps --filter "name=$SERVICE" -q --no-trunc | head -n1) nginx -t
9 |
--------------------------------------------------------------------------------
/swarm-scripts/nginx-update.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Restart the nginx service on all nodes
5 | #
6 |
7 | SERVICE="proxystack_nginx"
8 | docker exec $(docker ps --filter "name=$SERVICE" -q --no-trunc | head -n1) nginx -t
9 | docker service update --force --quiet --update-parallelism 1 --update-delay 30s $SERVICE
10 |
--------------------------------------------------------------------------------
/swarm-scripts/stack-deploy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Deploy nginx proxy to your nodes
5 | #
6 | # To stop the services, run
7 | # > docker stack rm proxystack
8 | #
9 |
10 | docker stack deploy proxystack -c ../swarm.yml
11 |
--------------------------------------------------------------------------------
/swarm.yml:
--------------------------------------------------------------------------------
1 | ### NGINX-PROXY
2 | ### Works in Swarm Mode
3 | ###
4 | ### Author: Sebastian Plocek
5 | ### https://github.com/sebastian13/docker-compose-nginx-proxy/tree/docker-swarm
6 |
7 | version: '3.9'
8 |
9 | services:
10 | nginx:
11 | image: nginx
12 | ports:
13 | - target: 443
14 | published: 443
15 | mode: host
16 | - target: 80
17 | published: 80
18 | mode: host
19 | volumes:
20 | - /docker/00-nginx-proxy/www:/var/www:ro
21 | - /docker/00-nginx-proxy/conf.d:/etc/nginx/conf.d:ro
22 | - /docker/00-nginx-proxy/ssl:/etc/nginx/ssl:ro
23 | - /docker/00-nginx-proxy/snippets:/etc/nginx/snippets:ro
24 | - /docker/00-nginx-proxy/protect:/etc/nginx/protect:ro
25 | networks:
26 | - attachable
27 | deploy:
28 | mode: global
29 | update_config:
30 | parallelism: 1
31 | delay: 30s
32 | restart_policy:
33 | condition: any
34 | delay: 30s
35 | max_attempts: 120
36 | window: 30s
37 | endpoint_mode: dnsrr
38 |
39 | networks:
40 | attachable:
41 | name: www-network
42 | driver: overlay
43 | attachable: true
44 | driver_opts:
45 | encrypted: "true"
46 |
--------------------------------------------------------------------------------