Skip to content

Commit 849c676

Browse files
authored
Merge pull request #719 from nginx-proxy/acme.sh
Replace simp_le with acme.sh
2 parents 680b1a4 + 65520ff commit 849c676

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1066
-1103
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ certs/
22
conf.d/
33
data/
44
vhost.d/
5+
.vscode
56

67
# tests
78
go/

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ before_install:
2828
install:
2929
- docker build -t "$IMAGE" .
3030
- docker inspect "$IMAGE"
31-
- docker run --rm "$IMAGE" simp_le --version
32-
- docker run --rm "$IMAGE" simp_le -v --test
31+
- docker run --rm "$IMAGE" acme.sh --version
3332
- docker images
3433

3534
before_script:

Dockerfile

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,58 @@ FROM golang:1.15-alpine AS go-builder
22

33
ENV DOCKER_GEN_VERSION=0.7.4
44

5-
# Install build dependencies for docker-gen
6-
RUN apk add --update \
5+
# Build docker-gen
6+
RUN apk add --no-cache --virtual .build-deps \
77
curl \
88
gcc \
99
git \
1010
make \
11-
musl-dev
12-
13-
# Build docker-gen
14-
RUN go get github.com/jwilder/docker-gen \
11+
musl-dev \
12+
&& go get github.com/jwilder/docker-gen \
1513
&& cd /go/src/github.com/jwilder/docker-gen \
16-
&& git checkout $DOCKER_GEN_VERSION \
14+
&& git -c advice.detachedHead=false checkout $DOCKER_GEN_VERSION \
1715
&& make get-deps \
18-
&& make all
16+
&& make all \
17+
&& go clean -cache \
18+
&& mv docker-gen /usr/local/bin/ \
19+
&& rm -rf /go/src \
20+
&& apk del .build-deps
1921

20-
FROM alpine:3.11
22+
FROM alpine:3.12
2123

22-
LABEL maintainer="Yves Blusseau <90z7oey02@sneakemail.com> (@blusseau)"
24+
LABEL maintainer="Nicolas Duchon <nicolas.duchon@gmail.com> (@buchdag)"
2325

24-
ENV DEBUG=false \
25-
DOCKER_HOST=unix:///var/run/docker.sock
26+
ARG GIT_DESCRIBE
27+
ARG ACMESH_VERSION=2.8.7
28+
29+
ENV COMPANION_VERSION=$GIT_DESCRIBE \
30+
DOCKER_HOST=unix:///var/run/docker.sock \
31+
PATH=$PATH:/app
2632

2733
# Install packages required by the image
28-
RUN apk add --update \
34+
RUN apk add --no-cache --virtual .bin-deps \
2935
bash \
30-
ca-certificates \
3136
coreutils \
3237
curl \
3338
jq \
3439
openssl \
35-
&& rm /var/cache/apk/*
40+
socat
3641

3742
# Install docker-gen from build stage
38-
COPY --from=go-builder /go/src/github.com/jwilder/docker-gen/docker-gen /usr/local/bin/
43+
COPY --from=go-builder /usr/local/bin/docker-gen /usr/local/bin/
3944

40-
# Install simp_le
41-
COPY /install_simp_le.sh /app/install_simp_le.sh
42-
RUN chmod +rx /app/install_simp_le.sh \
45+
# Install acme.sh
46+
COPY /install_acme.sh /app/install_acme.sh
47+
RUN chmod +rx /app/install_acme.sh \
4348
&& sync \
44-
&& /app/install_simp_le.sh \
45-
&& rm -f /app/install_simp_le.sh
49+
&& /app/install_acme.sh \
50+
&& rm -f /app/install_acme.sh
4651

4752
COPY /app/ /app/
4853

4954
WORKDIR /app
5055

56+
VOLUME ["/etc/acme.sh", "/etc/nginx/certs"]
57+
5158
ENTRYPOINT [ "/bin/bash", "/app/entrypoint.sh" ]
5259
CMD [ "/bin/bash", "/app/start.sh" ]

README.md

Lines changed: 117 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,117 @@
1-
[![Build Status](https://travis-ci.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion.svg?branch=master)](https://travis-ci.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion)
2-
[![GitHub release](https://img.shields.io/github/release/nginx-proxy/docker-letsencrypt-nginx-proxy-companion.svg)](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/releases)
3-
[![Image info](https://images.microbadger.com/badges/image/jrcs/letsencrypt-nginx-proxy-companion.svg)](https://hub.docker.com/r/jrcs/letsencrypt-nginx-proxy-companion "Click to view the image on Docker Hub")
4-
[![Docker stars](https://img.shields.io/docker/stars/jrcs/letsencrypt-nginx-proxy-companion.svg)](https://hub.docker.com/r/jrcs/letsencrypt-nginx-proxy-companion "Click to view the image on Docker Hub")
5-
[![Docker pulls](https://img.shields.io/docker/pulls/jrcs/letsencrypt-nginx-proxy-companion.svg)](https://hub.docker.com/r/jrcs/letsencrypt-nginx-proxy-companion "Click to view the image on Docker Hub")
6-
7-
**letsencrypt-nginx-proxy-companion** is a lightweight companion container for [**nginx-proxy**](https://github.com/jwilder/nginx-proxy).
8-
9-
It handles the automated creation, renewal and use of Let's Encrypt certificates for proxied Docker containers.
10-
11-
Please note that **letsencrypt-nginx-proxy-companion** no longer supports ACME v1 endpoints. The last tagged version that supports ACME v1 is [v1.11](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion/releases/tag/v1.11.2)
12-
13-
### Features:
14-
* Automated creation/renewal of Let's Encrypt (or other ACME CAs) certificates using [**simp_le**](https://github.com/zenhack/simp_le).
15-
* Let's Encrypt / ACME domain validation through `http-01` challenge only.
16-
* Automated update and reload of nginx config on certificate creation/renewal.
17-
* Support creation of [Multi-Domain (SAN) Certificates](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/blob/master/docs/Let's-Encrypt-and-ACME.md#multi-domains-certificates).
18-
* Creation of a Strong Diffie-Hellman Group at startup.
19-
* Work with all versions of docker.
20-
21-
### Requirements:
22-
* Your host **must** be publicly reachable on **both** port `80` and `443`.
23-
* Check your firewall rules and **do not attempt to block port `80`** as that will prevent `http-01` challenges from completing.
24-
* For the same reason, you can't use nginx-proxy's [`HTTPS_METHOD=nohttp`](https://github.com/jwilder/nginx-proxy#how-ssl-support-works).
25-
* The (sub)domains you want to issue certificates for must correctly resolve to the host.
26-
* Your DNS provider must [answer correctly to CAA record requests](https://letsencrypt.org/docs/caa/).
27-
* If your (sub)domains have AAAA records set, the host must be publicly reachable over IPv6 on port `80` and `443`.
28-
29-
![schema](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion/blob/master/schema.png)
30-
31-
## Basic usage (with the nginx-proxy container)
32-
33-
Three writable volumes must be declared on the **nginx-proxy** container so that they can be shared with the **letsencrypt-nginx-proxy-companion** container:
34-
35-
* `/etc/nginx/certs` to store certificates, private keys and ACME account keys (readonly for the **nginx-proxy** container).
36-
* `/etc/nginx/vhost.d` to change the configuration of vhosts (required so the CA may access `http-01` challenge files).
37-
* `/usr/share/nginx/html` to write `http-01` challenge files.
38-
39-
Example of use:
40-
41-
### Step 1 - nginx-proxy
42-
43-
Start **nginx-proxy** with the three additional volumes declared:
44-
45-
```shell
46-
$ docker run --detach \
47-
--name nginx-proxy \
48-
--publish 80:80 \
49-
--publish 443:443 \
50-
--volume /etc/nginx/certs \
51-
--volume /etc/nginx/vhost.d \
52-
--volume /usr/share/nginx/html \
53-
--volume /var/run/docker.sock:/tmp/docker.sock:ro \
54-
jwilder/nginx-proxy
55-
```
56-
57-
Binding the host docker socket (`/var/run/docker.sock`) inside the container to `/tmp/docker.sock` is a requirement of **nginx-proxy**.
58-
59-
### Step 2 - letsencrypt-nginx-proxy-companion
60-
61-
Start the **letsencrypt-nginx-proxy-companion** container, getting the volumes from **nginx-proxy** with `--volumes-from`:
62-
63-
```shell
64-
$ docker run --detach \
65-
--name nginx-proxy-letsencrypt \
66-
--volumes-from nginx-proxy \
67-
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
68-
69-
jrcs/letsencrypt-nginx-proxy-companion
70-
```
71-
72-
The host docker socket has to be bound inside this container too, this time to `/var/run/docker.sock`.
73-
74-
Albeit **optional**, it is **recommended** to provide a valid default email address through the `DEFAULT_EMAIL` environment variable, so that Let's Encrypt can warn you about expiring certificates and allow you to recover your account.
75-
76-
### Step 3 - proxied container(s)
77-
78-
Once both **nginx-proxy** and **letsencrypt-nginx-proxy-companion** containers are up and running, start any container you want proxied with environment variables `VIRTUAL_HOST` and `LETSENCRYPT_HOST` both set to the domain(s) your proxied container is going to use.
79-
80-
[`VIRTUAL_HOST`](https://github.com/jwilder/nginx-proxy#usage) control proxying by **nginx-proxy** and `LETSENCRYPT_HOST` control certificate creation and SSL enabling by **letsencrypt-nginx-proxy-companion**.
81-
82-
Certificates will only be issued for containers that have both `VIRTUAL_HOST` and `LETSENCRYPT_HOST` variables set to domain(s) that correctly resolve to the host, provided the host is publicly reachable.
83-
84-
```shell
85-
$ docker run --detach \
86-
--name your-proxied-app \
87-
--env "VIRTUAL_HOST=subdomain.yourdomain.tld" \
88-
--env "LETSENCRYPT_HOST=subdomain.yourdomain.tld" \
89-
nginx
90-
```
91-
92-
The containers being proxied must expose the port to be proxied, either by using the `EXPOSE` directive in their Dockerfile or by using the `--expose` flag to `docker run` or `docker create`.
93-
94-
If the proxied container listen on and expose another port than the default `80`, you can force **nginx-proxy** to use this port with the [`VIRTUAL_PORT`](https://github.com/jwilder/nginx-proxy#multiple-ports) environment variable.
95-
96-
Example using [Grafana](https://hub.docker.com/r/grafana/grafana/) (expose and listen on port 3000):
97-
98-
```shell
99-
$ docker run --detach \
100-
--name grafana \
101-
--env "VIRTUAL_HOST=othersubdomain.yourdomain.tld" \
102-
--env "VIRTUAL_PORT=3000" \
103-
--env "LETSENCRYPT_HOST=othersubdomain.yourdomain.tld" \
104-
105-
grafana/grafana
106-
```
107-
108-
Repeat [Step 3](#step-3---proxied-containers) for any other container you want to proxy.
109-
110-
## Additional documentation
111-
112-
Please check the [docs section](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion/tree/master/docs) or the [project's wiki](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion/wiki).
1+
[![Build Status](https://travis-ci.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion.svg?branch=master)](https://travis-ci.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion)
2+
[![GitHub release](https://img.shields.io/github/release/nginx-proxy/docker-letsencrypt-nginx-proxy-companion.svg)](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/releases)
3+
[![Image info](https://images.microbadger.com/badges/image/jrcs/letsencrypt-nginx-proxy-companion.svg)](https://hub.docker.com/r/jrcs/letsencrypt-nginx-proxy-companion "Click to view the image on Docker Hub")
4+
[![Docker stars](https://img.shields.io/docker/stars/jrcs/letsencrypt-nginx-proxy-companion.svg)](https://hub.docker.com/r/jrcs/letsencrypt-nginx-proxy-companion "Click to view the image on Docker Hub")
5+
[![Docker pulls](https://img.shields.io/docker/pulls/jrcs/letsencrypt-nginx-proxy-companion.svg)](https://hub.docker.com/r/jrcs/letsencrypt-nginx-proxy-companion "Click to view the image on Docker Hub")
6+
7+
**letsencrypt-nginx-proxy-companion** is a lightweight companion container for [**nginx-proxy**](https://github.com/nginx-proxy/nginx-proxy).
8+
9+
It handles the automated creation, renewal and use of Let's Encrypt certificates for proxied Docker containers.
10+
11+
The `v2.0.0` release of this project mark the switch of the ACME client used by the Docker image from [**simp.le**](https://github.com/zenhack/simp_le) to [**acme.sh**](https://github.com/acmesh-official/acme.sh). This switch result in some backward incompatible changes, so please read [this issue](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/issues/510) for more details before updating your image. The last tagged version that uses **simp_le** is `v1.13.1`.
12+
13+
### Features:
14+
* Automated creation/renewal of Let's Encrypt (or other ACME CAs) certificates using [**acme.sh**](https://github.com/acmesh-official/acme.sh).
15+
* Let's Encrypt / ACME domain validation through `http-01` challenge only.
16+
* Automated update and reload of nginx config on certificate creation/renewal.
17+
* Support creation of [Multi-Domain (SAN) Certificates](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/blob/master/docs/Let's-Encrypt-and-ACME.md#multi-domains-certificates).
18+
* Creation of a Strong Diffie-Hellman Group at startup.
19+
* Work with all versions of docker.
20+
21+
### Requirements:
22+
* Your host **must** be publicly reachable on **both** port `80` and `443`.
23+
* Check your firewall rules and **do not attempt to block port `80`** as that will prevent `http-01` challenges from completing.
24+
* For the same reason, you can't use nginx-proxy's [`HTTPS_METHOD=nohttp`](https://github.com/nginx-proxy/nginx-proxy#how-ssl-support-works).
25+
* The (sub)domains you want to issue certificates for must correctly resolve to the host.
26+
* Your DNS provider must [answer correctly to CAA record requests](https://letsencrypt.org/docs/caa/).
27+
* If your (sub)domains have AAAA records set, the host must be publicly reachable over IPv6 on port `80` and `443`.
28+
29+
![schema](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/blob/master/schema.png)
30+
31+
## Basic usage (with the nginx-proxy container)
32+
33+
Three writable volumes must be declared on the **nginx-proxy** container so that they can be shared with the **letsencrypt-nginx-proxy-companion** container:
34+
35+
* `/etc/nginx/certs` to store certificates and private keys (readonly for the **nginx-proxy** container).
36+
* `/etc/nginx/vhost.d` to change the configuration of vhosts (required so the CA may access `http-01` challenge files).
37+
* `/usr/share/nginx/html` to write `http-01` challenge files.
38+
39+
Additionally, a fourth volume must be declared on the **letsencrypt-nginx-proxy-companion** container to store `acme.sh` configuration and state: `/etc/acme.sh`.
40+
41+
Please also read the doc about [data persistence](./docs/persistent-data.md).
42+
43+
Example of use:
44+
45+
### Step 1 - nginx-proxy
46+
47+
Start **nginx-proxy** with the three additional volumes declared:
48+
49+
```shell
50+
$ docker run --detach \
51+
--name nginx-proxy \
52+
--publish 80:80 \
53+
--publish 443:443 \
54+
--volume /etc/nginx/certs \
55+
--volume /etc/nginx/vhost.d \
56+
--volume /usr/share/nginx/html \
57+
--volume /var/run/docker.sock:/tmp/docker.sock:ro \
58+
jwilder/nginx-proxy
59+
```
60+
61+
Binding the host docker socket (`/var/run/docker.sock`) inside the container to `/tmp/docker.sock` is a requirement of **nginx-proxy**.
62+
63+
### Step 2 - letsencrypt-nginx-proxy-companion
64+
65+
Start the **letsencrypt-nginx-proxy-companion** container, getting the volumes from **nginx-proxy** with `--volumes-from`:
66+
67+
```shell
68+
$ docker run --detach \
69+
--name nginx-proxy-letsencrypt \
70+
--volumes-from nginx-proxy \
71+
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
72+
--volume /etc/acme.sh \
73+
74+
jrcs/letsencrypt-nginx-proxy-companion
75+
```
76+
77+
The host docker socket has to be bound inside this container too, this time to `/var/run/docker.sock`.
78+
79+
Albeit **optional**, it is **recommended** to provide a valid default email address through the `DEFAULT_EMAIL` environment variable, so that Let's Encrypt can warn you about expiring certificates and allow you to recover your account.
80+
81+
### Step 3 - proxied container(s)
82+
83+
Once both **nginx-proxy** and **letsencrypt-nginx-proxy-companion** containers are up and running, start any container you want proxied with environment variables `VIRTUAL_HOST` and `LETSENCRYPT_HOST` both set to the domain(s) your proxied container is going to use.
84+
85+
[`VIRTUAL_HOST`](https://github.com/nginx-proxy/nginx-proxy#usage) control proxying by **nginx-proxy** and `LETSENCRYPT_HOST` control certificate creation and SSL enabling by **letsencrypt-nginx-proxy-companion**.
86+
87+
Certificates will only be issued for containers that have both `VIRTUAL_HOST` and `LETSENCRYPT_HOST` variables set to domain(s) that correctly resolve to the host, provided the host is publicly reachable.
88+
89+
```shell
90+
$ docker run --detach \
91+
--name your-proxied-app \
92+
--env "VIRTUAL_HOST=subdomain.yourdomain.tld" \
93+
--env "LETSENCRYPT_HOST=subdomain.yourdomain.tld" \
94+
nginx
95+
```
96+
97+
The containers being proxied must expose the port to be proxied, either by using the `EXPOSE` directive in their Dockerfile or by using the `--expose` flag to `docker run` or `docker create`.
98+
99+
If the proxied container listen on and expose another port than the default `80`, you can force **nginx-proxy** to use this port with the [`VIRTUAL_PORT`](https://github.com/nginx-proxy/nginx-proxy#multiple-ports) environment variable.
100+
101+
Example using [Grafana](https://hub.docker.com/r/grafana/grafana/) (expose and listen on port 3000):
102+
103+
```shell
104+
$ docker run --detach \
105+
--name grafana \
106+
--env "VIRTUAL_HOST=othersubdomain.yourdomain.tld" \
107+
--env "VIRTUAL_PORT=3000" \
108+
--env "LETSENCRYPT_HOST=othersubdomain.yourdomain.tld" \
109+
110+
grafana/grafana
111+
```
112+
113+
Repeat [Step 3](#step-3---proxied-containers) for any other container you want to proxy.
114+
115+
## Additional documentation
116+
117+
Please check the [docs section](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/tree/master/docs) or the [project's wiki](https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion/wiki).

app/cleanup_test_artifacts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
3+
# This script should not be run outside of a test container
4+
[[ "$TEST_MODE" == 'true' ]] || exit 1
5+
6+
while [[ $# -gt 0 ]]; do
7+
flag="$1"
8+
9+
case $flag in
10+
--default-cert)
11+
for filename in default.crt default.key; do
12+
filepath="/etc/nginx/certs/$filename"
13+
[[ -f "$filepath" ]] && rm -rf "$filepath"
14+
done
15+
shift
16+
;;
17+
18+
--location-config)
19+
for filepath in '/etc/nginx/vhost.d/le1.wtf' '/etc/nginx/vhost.d/*.example.com' '/etc/nginx/vhost.d/test.*'; do
20+
[[ -f "$filepath" ]] && rm -rf "$filepath"
21+
done
22+
shift
23+
;;
24+
25+
*) #Unknown option
26+
shift
27+
;;
28+
esac
29+
done
30+
31+
for domain in le1.wtf le2.wtf le3.wtf le4.wtf lim.it; do
32+
folder="/etc/nginx/certs/$domain"
33+
[[ -d "$folder" ]] && rm -rf "$folder"
34+
location_file="/etc/nginx/vhost.d/$domain"
35+
[[ -f "$location_file" ]] && rm -rf "$location_file" 2> /dev/null
36+
for extension in key crt chain.pem dhparam.pem; do
37+
symlink="/etc/nginx/certs/${domain}.${extension}"
38+
[[ -L "$symlink" ]] && rm -rf "$symlink"
39+
done
40+
done

0 commit comments

Comments
 (0)