Skip to content

Commit 63a07fe

Browse files
pbeneficetraefiker
authored andcommitted
Add a docker-compose & let's encrypt user-guide
1 parent c2d440a commit 63a07fe

File tree

10 files changed

+629
-0
lines changed

10 files changed

+629
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
version: "3.3"
2+
3+
services:
4+
5+
traefik:
6+
image: "traefik:v2.0.0-beta1"
7+
container_name: "traefik"
8+
command:
9+
#- "--log.level=DEBUG"
10+
- "--api=true"
11+
- "--providers.docker=true"
12+
- "--providers.docker.exposedbydefault=false"
13+
- "--entrypoints.web.address=:80"
14+
- "--entrypoints.websecure.address=:443"
15+
- "--certificatesresolvers.mydnschallenge.acme.dnschallenge=true"
16+
- "--certificatesresolvers.mydnschallenge.acme.dnschallenge.provider=ovh"
17+
#- "--certificatesresolvers.mydnschallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
18+
- "--certificatesresolvers.mydnschallenge.acme.email=postmaster@mydomain.com"
19+
- "--certificatesresolvers.mydnschallenge.acme.storage=/letsencrypt/acme.json"
20+
ports:
21+
- "80:80"
22+
- "443:443"
23+
- "8080:8080"
24+
environment:
25+
- "OVH_ENDPOINT=xxx"
26+
- "OVH_APPLICATION_KEY=xxx"
27+
- "OVH_APPLICATION_SECRET=xxx"
28+
- "OVH_CONSUMER_KEY=xxx"
29+
volumes:
30+
- "./letsencrypt:/letsencrypt"
31+
- "/var/run/docker.sock:/var/run/docker.sock:ro"
32+
33+
whoami:
34+
image: "containous/whoami"
35+
container_name: "simple-service"
36+
labels:
37+
- "traefik.enable=true"
38+
- "traefik.http.routers.whoami.rule=Host(`whoami.mydomain.com`)"
39+
- "traefik.http.routers.whoami.entrypoints=websecure"
40+
- "traefik.http.routers.whoami.tls.certresolver=mydnschallenge"
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
version: "3.3"
2+
3+
secrets:
4+
ovh_endpoint:
5+
file: "./secrets/ovh_endpoint.secret"
6+
ovh_application_key:
7+
file: "./secrets/ovh_application_key.secret"
8+
ovh_application_secret:
9+
file: "./secrets/ovh_application_secret.secret"
10+
ovh_consumer_key:
11+
file: "./secrets/ovh_consumer_key.secret"
12+
13+
services:
14+
15+
traefik:
16+
image: "traefik:v2.0.0-beta1"
17+
container_name: "traefik"
18+
command:
19+
#- "--log.level=DEBUG"
20+
- "--api=true"
21+
- "--providers.docker=true"
22+
- "--providers.docker.exposedbydefault=false"
23+
- "--entrypoints.web.address=:80"
24+
- "--entrypoints.websecure.address=:443"
25+
- "--certificatesresolvers.mydnschallenge.acme.dnschallenge=true"
26+
- "--certificatesresolvers.mydnschallenge.acme.dnschallenge.provider=ovh"
27+
#- "--certificatesresolvers.mydnschallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
28+
- "--certificatesresolvers.mydnschallenge.acme.email=postmaster@mydomain.com"
29+
- "--certificatesresolvers.mydnschallenge.acme.storage=/letsencrypt/acme.json"
30+
ports:
31+
- "80:80"
32+
- "443:443"
33+
- "8080:8080"
34+
secrets:
35+
- "ovh_endpoint"
36+
- "ovh_application_key"
37+
- "ovh_application_secret"
38+
- "ovh_consumer_key"
39+
environment:
40+
- "OVH_ENDPOINT_FILE=/run/secrets/ovh_endpoint"
41+
- "OVH_APPLICATION_KEY_FILE=/run/secrets/ovh_application_key"
42+
- "OVH_APPLICATION_SECRET_FILE=/run/secrets/ovh_application_secret"
43+
- "OVH_CONSUMER_KEY_FILE=/run/secrets/ovh_consumer_key"
44+
volumes:
45+
- "./letsencrypt:/letsencrypt"
46+
- "/var/run/docker.sock:/var/run/docker.sock:ro"
47+
48+
whoami:
49+
image: "containous/whoami"
50+
container_name: "simple-service"
51+
labels:
52+
- "traefik.enable=true"
53+
- "traefik.http.routers.whoami.rule=Host(`whoami.mydomain.com`)"
54+
- "traefik.http.routers.whoami.entrypoints=websecure"
55+
- "traefik.http.routers.whoami.tls.certresolver=mydnschallenge"
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# Docker-compose with let's encrypt: DNS Challenge
2+
3+
This guide aim to demonstrate how to create a certificate with the let's encrypt DNS challenge to use https on a simple service exposed with Traefik.
4+
Please also read the [basic example](../basic-example) for details on how to expose such a service.
5+
6+
## Prerequisite
7+
8+
For the DNS challenge, you'll need:
9+
10+
- A working [provider](https://docs.traefik.io/v2.0/https/acme/#providers) along with the credentials allowing to create and remove DNS records.
11+
12+
!!! info "Variables may vary depending on the Provider."
13+
Please note this guide may vary depending on the provider you use.
14+
The only things changing are the names of the variables you will need to define in order to configure your provider so it can create DNS records.
15+
Please refer the [list of providers](../../../https/acme.md#providers) given right above and replace all the environment variables with the ones described in this documentation.
16+
17+
## Setup
18+
19+
- Create a `docker-compose.yml` file with the following content:
20+
21+
```yaml
22+
--8<-- "content/user-guides/docker-compose/acme-dns/docker-compose.yml"
23+
```
24+
25+
- Replace the environment variables by your own:
26+
27+
```yaml
28+
environment:
29+
- "OVH_ENDPOINT=[YOUR_OWN_VALUE]"
30+
- "OVH_APPLICATION_KEY=[YOUR_OWN_VALUE]"
31+
- "OVH_APPLICATION_SECRET=[YOUR_OWN_VALUE]"
32+
- "OVH_CONSUMER_KEY=[YOUR_OWN_VALUE]"
33+
```
34+
35+
- Replace `[email protected]` by your **own email** within the `certificatesresolvers.mydnschallenge.acme.email` command line argument of the `traefik` service.
36+
- Replace `whoami.mydomain.com` by your **own domain** within the `traefik.http.routers.whoami.rule` label of the `whoami` service.
37+
- Optionally uncomment the following lines if you want to test/debug:
38+
39+
```yaml
40+
#- "--log.level=DEBUG"
41+
#- "--certificatesresolvers.mydnschallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
42+
```
43+
44+
- Run `docker-compose up -d` within the folder where you created the previous file.
45+
- Wait a bit and visit `https://your_own_domain` to confirm everything went fine.
46+
47+
!!! Note
48+
49+
If you uncommented the `acme.caserver` line, you will get an SSL error, but if you display the certificate and see it was emitted by `Fake LE Intermediate X1` then it means all is good.
50+
(It is the staging environment intermediate certificate used by let's encrypt).
51+
You can now safely comment the `acme.caserver` line, remove the `letsencrypt/acme.json` file and restart Traefik to issue a valid certificate.
52+
53+
## Explanation
54+
55+
What changed between the initial setup:
56+
57+
- We configure a second entry point for the https traffic:
58+
59+
```yaml
60+
command:
61+
# Traefik will listen to incoming request on the port 443 (https)
62+
- "--entrypoints.websecure.address=:443"
63+
ports:
64+
- "443:443"
65+
```
66+
67+
- We configure the DNS let's encrypt challenge:
68+
69+
```yaml
70+
command:
71+
# Enable a dns challenge named "mydnschallenge"
72+
- "--certificatesresolvers.mydnschallenge.acme.dnschallenge=true"
73+
# Tell which provider to use
74+
- "--certificatesresolvers.mydnschallenge.acme.dnschallenge.provider=ovh"
75+
# The email to provide to let's encrypt
76+
- "--certificatesresolvers.mydnschallenge.acme.email=postmaster@mydomain.com"
77+
```
78+
79+
- We provide the required configuration to our provider via environment variables:
80+
81+
```yaml
82+
environment:
83+
- "OVH_ENDPOINT=xxx"
84+
- "OVH_APPLICATION_KEY=xxx"
85+
- "OVH_APPLICATION_SECRET=xxx"
86+
- "OVH_CONSUMER_KEY=xxx"
87+
```
88+
89+
!!! Note
90+
91+
This is the step that may vary depending on the provider you use.
92+
Just define the variables required by your provider.
93+
(see the prerequisite for a list)
94+
95+
- We add a volume to store our certificates:
96+
97+
```yaml
98+
volumes:
99+
# Create a letsencrypt dir within the folder where the docker-compose file is
100+
- "./letsencrypt:/letsencrypt"
101+
102+
command:
103+
# Tell to store the certificate on a path under our volume
104+
- "--certificatesresolvers.mydnschallenge.acme.storage=/letsencrypt/acme.json"
105+
```
106+
107+
- We configure the `whoami` service to tell Traefik to use the certificate resolver named `mydnschallenge` we just configured:
108+
109+
```yaml
110+
labels:
111+
- "traefik.http.routers.whoami.tls.certresolver=mydnschallenge" # Uses the Host rule to define which certificate to issue
112+
```
113+
114+
## Use Secrets
115+
116+
To configure the provider, and avoid having the secrets exposed in plaintext within the docker-compose environment section,
117+
you could use docker secrets.
118+
The point is to manage those secret files by another mean, and read them from the `docker-compose.yml` file making the docker-compose file itself less sensitive.
119+
120+
- Create a directory named `secrets`, and create a file for each parameters required to configure you provider containing the value of the parameter:
121+
for example, the `ovh_endpoint.secret` file contain `ovh-eu`
122+
123+
```text
124+
./secrets
125+
├── ovh_application_key.secret
126+
├── ovh_application_secret.secret
127+
├── ovh_consumer_key.secret
128+
└── ovh_endpoint.secret
129+
```
130+
131+
!!! Note
132+
133+
You could store those secrets anywhere on the server,
134+
just make sure to use the proper path for the `file` directive fo the secrets definition in the `docker-compose.yml` file.
135+
136+
- Use this `docker-compose.yml` file:
137+
138+
```yaml
139+
--8<-- "content/user-guides/docker-compose/acme-dns/docker-compose_secrets.yml"
140+
```
141+
142+
!!! Note
143+
144+
Still think about changing `[email protected]` & `whoami.mydomain.com` by your own values.
145+
146+
Let's explain a bit what we just did:
147+
148+
- The following section allow to read files on the docker host, and expose those file under `/run/secrets/[NAME_OF_THE_SECRET]` within the container:
149+
150+
```yaml
151+
secrets:
152+
# secret name also used to name the file exposed within the container
153+
ovh_endpoint:
154+
# path on the host
155+
file: "./secrets/ovh_endpoint.secret"
156+
ovh_application_key:
157+
file: "./secrets/ovh_application_key.secret"
158+
ovh_application_secret:
159+
file: "./secrets/ovh_application_secret.secret"
160+
ovh_consumer_key:
161+
file: "./secrets/ovh_consumer_key.secret"
162+
163+
services:
164+
traefik:
165+
# expose the predefined secret to the container by name
166+
secrets:
167+
- "ovh_endpoint"
168+
- "ovh_application_key"
169+
- "ovh_application_secret"
170+
- "ovh_consumer_key"
171+
```
172+
173+
- The environment variable within our `whoami` service are suffixed by `_FILE` which allow us to point to files containing the value, instead of exposing the value itself.
174+
The acme client will read the content of those file to get the required configuration values.
175+
176+
```yaml
177+
environment:
178+
# expose the path to file provided by docker containing the value we want for OVH_ENDPOINT.
179+
- "OVH_ENDPOINT_FILE=/run/secrets/ovh_endpoint"
180+
- "OVH_APPLICATION_KEY_FILE=/run/secrets/ovh_application_key"
181+
- "OVH_APPLICATION_SECRET_FILE=/run/secrets/ovh_application_secret"
182+
- "OVH_CONSUMER_KEY_FILE=/run/secrets/ovh_consumer_key"
183+
```
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
version: "3.3"
2+
3+
services:
4+
5+
traefik:
6+
image: "traefik:v2.0.0-beta1"
7+
container_name: "traefik"
8+
command:
9+
#- "--log.level=DEBUG"
10+
- "--api=true"
11+
- "--providers.docker=true"
12+
- "--providers.docker.exposedbydefault=false"
13+
- "--entrypoints.web.address=:80"
14+
- "--entrypoints.websecure.address=:443"
15+
- "--certificatesresolvers.myhttpchallenge.acme.httpchallenge=true"
16+
- "--certificatesresolvers.myhttpchallenge.acme.httpchallenge.entrypoint=web"
17+
#- "--certificatesresolvers.myhttpchallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
18+
- "--certificatesresolvers.myhttpchallenge.acme.email=postmaster@mydomain.com"
19+
- "--certificatesresolvers.myhttpchallenge.acme.storage=/letsencrypt/acme.json"
20+
ports:
21+
- "80:80"
22+
- "443:443"
23+
- ":8080:8080"
24+
volumes:
25+
- "./letsencrypt:/letsencrypt"
26+
- "/var/run/docker.sock:/var/run/docker.sock:ro"
27+
28+
whoami:
29+
image: "containous/whoami"
30+
container_name: "simple-service"
31+
labels:
32+
- "traefik.enable=true"
33+
- "traefik.http.routers.whoami.rule=Host(`whoami.mydomain.com`)"
34+
- "traefik.http.routers.whoami.entrypoints=websecure"
35+
- "traefik.http.routers.whoami.tls.certresolver=myhttpchallenge"

0 commit comments

Comments
 (0)