In the last article, we learned how to set up a helper server for Docker boxes. Now, let’s make everything safe with HTTPS.
Did you miss it? Click here to read the previous post.
This time, we’ll add HTTPS to our helper server using a tool named acme-companion. Check out the repo here.
First, we need to look back at what we did last time and change the docker-compose.yaml file a bit. Let’s start!
services:
nginx-proxy-acme:
image: nginxproxy/acme-companion
container_name: nginx-proxy-acme
restart: on-failure:10
environment:
- DEFAULT_EMAIL=youremail@example.com
- NGINX_PROXY_CONTAINER=nginx-proxy
depends_on:
- nginx-proxy
volumes:
- certs:/etc/nginx/certs
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
- /var/run/docker.sock:/var/run/docker.sock:ro
- acme:/etc/acme.sh
nginx-proxy:
image: nginxproxy/nginx-proxy
container_name: nginx-proxy
restart: on-failure:10
depends_on:
nestjs:
condition: service_started
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- certs:/etc/nginx/certs
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
- ./nginx/my_proxy.conf:/etc/nginx/conf.d/my_proxy.conf:ro
nestjs:
image: travisnguyen20/sample-nestjs-with-docker:latest
container_name: nestjs
restart: on-failure:10
ports:
- "3000:3000"
depends_on:
mysql:
condition: service_started
env_file:
- .env
mysql:
image: mysql:8
container_name: mysql
restart: always
ports:
- "3306:3306"
env_file:
- .env.mysql
volumes:
- ./mysql/conf.d:/etc/mysql/conf.d
- mysql-data:/var/lib/mysql
volumes:
certs:
vhost:
html:
acme:
mysql-data:
Update .env file to hint nginx-proxy-acme
generate certs for it.
VIRTUAL_HOST=api.yourserver.com
VIRTUAL_PORT=3000
LETSENCRYPT_HOST=api.travisbytes.com
DATABASE_URL=yoursecret
OTHER_VAR=secret
nginx-proxy
need to know which service generates certs for virtual hosts so remember to set NGINX_PROXY_CONTAINER=nginx-proxy
Each minute, nginx-proxy
-acme will scan containers that have variable LETSENCRYPT_HOST set and generate certs for it and store in volume certs. nginx-proxy will use this cert to secure connections to the docker container
Make sure you point your domain to the server IP before starting the service otherwise no certificate is generated
Run this command to deploy new services
docker compose up -d
Output:
[+] Running 8/8
✔ nginx-proxy-acme 7 layers [⣿⣿⣿⣿⣿⣿⣿] 0B/0B Pulled 7.6s
✔ 4abcf2066143 Already exists 0.0s
✔ c58472a96df6 Pull complete 1.4s
✔ e0fd6dc3ac4d Pull complete 0.8s
✔ 8107d52fa040 Pull complete 0.8s
✔ 86858656e858 Pull complete 1.6s
✔ 3d2ba187a5bb Pull complete 1.9s
✔ 4f4fb700ef54 Pull complete 2.2s
[+] Running 4/6
⠦ Volume "home_certs" Created 1.7s
⠦ Volume "home_acme" Created 1.7s
✔ Container mysql Running 0.0s
✔ Container nestjs Running 0.0s
✔ Container nginx-proxy Started 1.2s
✔ Container nginx-proxy-acme Started
To debug if the certificate is generated. Checkout ngnix-proxy-acme
logs using this command
docker compose logs nginx-proxy-acme
If you see these lines that means a certificate is generated for your site.
nginx-proxy-acme | Reloading nginx proxy (nginx-proxy)...
nginx-proxy-acme | 2024/04/02 16:07:41 Generated '/etc/nginx/conf.d/default.conf' from 4 containers
nginx-proxy-acme | 2024/04/02 16:07:41 [notice] 66#66: signal process started
nginx-proxy-acme | Creating/renewal demo.travisbytes.com certificates... (demo.travisbytes.com)
nginx-proxy-acme | [Tue Apr 2 16:07:42 UTC 2024] Using CA: https://acme-v02.api.letsencrypt.org/directory
nginx-proxy-acme | [Tue Apr 2 16:07:42 UTC 2024] Creating domain key
nginx-proxy-acme | [Tue Apr 2 16:07:43 UTC 2024] The domain key is here: /etc/acme.sh/travisnguyen.me@gmail.com/demo.travisbytes.com/demo.travisbytes.com.key
nginx-proxy-acme | [Tue Apr 2 16:07:43 UTC 2024] Generate next pre-generate key.
nginx-proxy-acme | [Tue Apr 2 16:07:43 UTC 2024] Single domain='demo.travisbytes.com'
nginx-proxy-acme | [Tue Apr 2 16:07:43 UTC 2024] Getting domain auth token for each domain
nginx-proxy-acme | [Tue Apr 2 16:07:46 UTC 2024] Getting webroot for domain='demo.travisbytes.com'
nginx-proxy-acme | [Tue Apr 2 16:07:46 UTC 2024] Verifying: demo.travisbytes.com
nginx-proxy-acme | [Tue Apr 2 16:07:47 UTC 2024] Pending, The CA is processing your order, please just wait. (1/30)
nginx-proxy-acme | [Tue Apr 2 16:07:50 UTC 2024] Success
nginx-proxy-acme | [Tue Apr 2 16:07:50 UTC 2024] Verify finished, start to sign.
nginx-proxy-acme | [Tue Apr 2 16:07:50 UTC 2024] Lets finalize the order.
nginx-proxy-acme | [Tue Apr 2 16:07:50 UTC 2024] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/1650520217/257543242427'
nginx-proxy-acme | [Tue Apr 2 16:07:53 UTC 2024] Downloading cert.
nginx-proxy-acme | [Tue Apr 2 16:07:53 UTC 2024] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/044f162ffee3fe17ace831853bc8ea46de0b'
nginx-proxy-acme | [Tue Apr 2 16:07:54 UTC 2024] Cert success.
Checkout your website if you can access it via https://yourdomain.com/
Awesome! Now you can generate https for any services with just a few changes in docker-compose.yaml file.