e53b9d7cc2569a1730307022c4bf1d4318bcc4d7
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 | - |