haproxy-letsencrypt-docker.md
... ...
@@ -1,4 +1,4 @@
1
-<!-- TITLE: Haproxy with Lets Encrypt in Docker -->
1
+<!-- TITLE: HAProxy with Lets Encrypt in Docker -->
2 2
<!-- SUBTITLE: This is 3 lines of bash when docker's not involved -->
3 3
4 4
# What are we doing here?
... ...
@@ -176,13 +176,13 @@ backend wiki
176 176
```
177 177
178 178
What's going on here then?
179
-1. The global section logs everything to stdout, because that's what you do with docker. [rule 6](/rules#thou-shalt-respect-the-sanctity-of-stdout) does not apply in dockerland.
180
-2. We're setting the Mozilla recommended ciphers and DH values. Check the [current recommendations](https://mozilla.github.io/server-side-tls/ssl-config-generator/) if you're foolish enough to go into production with this stuff.
181
-3. We're using 'resolvers' and 'default-server init-addr none' to get around the problem of containers not being up at haproxy startup time. Docker with user-defined networks always puts a resolver at 127.0.0.11:53, and haproxy can use that to resolve container names at *runtime* instead of *startup *time.
182
-4. We're binding to port 8080 and 8443, and setting the cert to the Let's Encrypt cert we dumped out in the previous section. The ports will be mapped back to 80 and 443 by docker later on.
183
-5. Always redirect to https.
184
-6. All traffic that matches the certbot [ACME](https://ietf-wg-acme.github.io/acme/draft-ietf-acme-acme.html) challenge protocol is directed to our letsencrypt container (to be created later).
185
-7. Other traffic is matched by request hostname to their respective containers. Your routing will probably be more complicated than this, but it's a start.
179
+* The global section logs everything to stdout, because that's what you do with docker. [rule 6](/rules#thou-shalt-respect-the-sanctity-of-stdout) does not apply in dockerland.
180
+* We're setting the Mozilla recommended ciphers and DH values. Check the [current recommendations](https://mozilla.github.io/server-side-tls/ssl-config-generator/) if you're foolish enough to go into production with this stuff.
181
+* We're using 'resolvers' and 'default-server init-addr none' to get around the problem of containers not being up at haproxy startup time. Docker with user-defined networks always puts a resolver at 127.0.0.11:53, and haproxy can use that to resolve container names at *runtime* instead of *startup *time.
182
+* We're binding to port 8080 and 8443, and setting the cert to the Let's Encrypt cert we dumped out in the previous section. The ports will be mapped back to 80 and 443 by docker later on.
183
+* Always redirect to https.
184
+* All traffic that matches the certbot [ACME](https://ietf-wg-acme.github.io/acme/draft-ietf-acme-acme.html) challenge protocol is directed to our letsencrypt container (to be created later).
185
+* Other traffic is matched by request hostname to their respective containers. Your routing will probably be more complicated than this, but it's a start.
186 186
187 187
Let's wrap this up in docker-compose...
188 188
... ...
@@ -214,12 +214,12 @@ networks:
214 214
haproxy:
215 215
```
216 216
Here we have:
217
-1. The container_name is 'haproxy'. We'll be referring to this container name later on for sending signals when certs are renewed.
218
-2. The 'haproxy/bind' dir is mounted at /usr/local/etc/haproxy, so the haproxy.cfg file we created is in the right place for haproxy to read it. Mounted read-only, and with the 'Z' selinux flag (I'm running RedHat-ish host OSes here, so it's required - leave off the ',Z' if docker complains).
219
-3. The letsencrypt volume is mounted at /etc/letsencrypt so haproxy can read the cert file
220
-4. We're creating a user-defined network called 'haproxy' so we an talk to other containers
221
-5. The high port numbers are mapped down to the usual 80/443
222
-6. We're setting a non-priv UID to run as. Because [containers don't need to run as root](https://medium.com/@mccode/processes-in-containers-should-not-run-as-root-2feae3f0df3b)
217
+* The container_name is 'haproxy'. We'll be referring to this container name later on for sending signals when certs are renewed.
218
+* The 'haproxy/bind' dir is mounted at /usr/local/etc/haproxy, so the haproxy.cfg file we created is in the right place for haproxy to read it. Mounted read-only, and with the 'Z' selinux flag (I'm running RedHat-ish host OSes here, so it's required - leave off the ',Z' if docker complains).
219
+* The letsencrypt volume is mounted at /etc/letsencrypt so haproxy can read the cert file
220
+* We're creating a user-defined network called 'haproxy' so we an talk to other containers
221
+* The high port numbers are mapped down to the usual 80/443
222
+* We're setting a non-priv UID to run as. Because [containers don't need to run as root](https://medium.com/@mccode/processes-in-containers-should-not-run-as-root-2feae3f0df3b)
223 223
224 224
## Go!
225 225
Run that bad boy with `docker-compose up`. You should see some startup messages and hopefully no errors. haproxy might complain about the backends being down, but that's OK for now.
... ...
@@ -280,8 +280,7 @@ networks:
280 280
```
281 281
What doing?
282 282
* We're mounting the letsencrypt volume back up at /etc/letsencrypt
283
-* The docker socket from the host is mounted at /var/run/docker.sock. This lets us do docker operations from inside the container
284
-* There's a small sleep to let haproxy start up, then we attempt a renew, and run the deploy-hook script (see stage 1) if anything changed.
283
+* The docker socket from the host is mounted at /var/run/docker.sock. This lets us do docker operations from inside the container.
284
+* There's a small sleep to let haproxy start up (ewww, but also, whatever), then we attempt a renew and run the deploy-hook script (see stage 1) if anything changed.
285 285
* The deploy-hook script cats the cert chain and key into an haproxy style .pem file, then sends a SIGHUP via the docker command to the haproxy container, causing it to re-read its config
286 286
* The container is granted privileged permissions to let the docker socket work
287
-