# 使用 acme.sh 加上 Docker 獲得 ZeroSSL 免費憑證
# 簡介
通過 acme.sh 工具,加上 DNS API 與免費憑證簽發機構 ZeroSSL,包裝成 Docker 容器排程執行,實現自動更新的 SSL 憑證的服務。
# 教程
# 建立 Dockerfile
| FROM ubuntu:20.04 |
| RUN apt update && \ |
| apt-get install -y wget curl tar cron socat jq && \ |
| DEBIAN_FRONTEND=noninteractive TZ=Asia/Taipei apt-get -y install tzdata |
| RUN TZ=Asia/Taipei \ |
| && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ |
| && echo $TZ > /etc/timezone \ |
| && dpkg-reconfigure -f noninteractive tzdata |
| WORKDIR /app |
| COPY ./*.sh . |
| RUN chmod +x ./*.sh |
| RUN service cron start && \ |
| echo "0 0 * * *" "/usr/bin/acme.sh --cron" >> mycron && \ |
| crontab mycron && \ |
| rm mycron |
| ENTRYPOINT ["/bin/bash","-c","/app/entry.sh"] |
# 建立 entry.sh
| #!/bin/bash |
| |
| |
| if [[ ! -f /root/.acme.sh/acme.sh ]] |
| then |
| curl -sSL https://get.acme.sh | sh -s email=$ACME_EMAIL |
| fi |
| if [[ ! -f /usr/bin/acme.sh ]] |
| then |
| ln -s /root/.acme.sh/acme.sh /usr/bin/acme.sh |
| echo [$(date)] acme.sh has been installed |
| acme.sh --set-default-ca --server zerossl |
| fi |
| service cron start |
| |
| |
| acme.sh --set-notify --notify-level 3 |
| acme.sh --set-notify --notify-mode 0 |
| acme.sh --set-notify --notify-hook telegram |
| |
| |
| if [[ ! -f /root/.acme.sh/acme.sh.log ]]; then |
| touch /root/.acme.sh/acme.sh.log |
| fi |
| tail -f /root/.acme.sh/acme.sh.log |
# 建立 env
| |
| ACME_EMAIL=email@example.com |
| |
| CF_Token=1111111111111111111111111111 |
| CF_Account_ID=1111111111111111111111111111 |
| DPI_Id=123 |
| DPI_Key=1111111111111111111111111111 |
| |
| TELEGRAM_BOT_APITOKEN="1111111:aaaaaaaaaaaaaaaaaaaaaaa" |
| TELEGRAM_BOT_CHATID="1111111" |
# 建立 init.sh
| #!/bin/bash |
| ISSUE="/usr/bin/acme.sh --server zerossl --register-account -m ${ACME_EMAIL} --issue --force --log" |
| CERT_LOCATION="" |
| if [ $# -ne 0 ]; then |
| CERT_LOCATION="${1%/}" |
| INSTALL="/usr/bin/acme.sh --install-cert --key-file $CERT_LOCATION/cert.key --fullchain-file $CERT_LOCATION/cert.pem --log" |
| shift |
| ISSUE=$(echo "$ISSUE --dns $1") |
| shift |
| |
| while [ $# != 0 ] |
| do |
| ISSUE=$(echo $ISSUE -d "$1") |
| INSTALL=$(echo $INSTALL -d "$1") |
| shift |
| done |
| else |
| echo "Usage: \"./init.sh cert_location dns_api domain1 domain2...\""; |
| exit |
| fi |
| echo $ISSUE |
| echo $INSTALL |
# 建立 docker-compose.yml
| version: "3.9" |
| services: |
| acme-sh: |
| build: . |
| image: acme-sh |
| tty: true |
| stdin_open: true |
| container_name: acme-sh |
| restart: always |
| env_file: |
| - .env |
| volumes: |
| - /volumes/acme/cert:/cert |
| - /volumes/acme/home:/root/.acme.sh |
| network_mode: host |
# 啟動服務
| docker-compose up -d --build |
# 新增要安裝的憑證
用法: docker exec -it acme-sh ./init.sh 憑證存放位置 dns_api 域名1 域名2...
例如:使用 Cloudflare 託管的域名 example.com
,憑證存放在 example.com
目錄下
- 執行下面指令
| docker exec -it acme-sh ./init.sh /cert/example.com dns_cf example.com |
- 就會印出下面兩行指令
| /usr/bin/acme.sh --server zerossl --register-account -m email@example.com --issue --force --log --dns dns_cf -d example.com |
| |
| /usr/bin/acme.sh --install-cert --key-file /cert/example.com/cert.key --fullchain-file /cert/example.com/cert.pem --log -d example.com |
- 將其前方加入
docker exec -it acme-sh
,改為下方指令並執行
| docker exec -it acme-sh /usr/bin/acme.sh --server zerossl --register-account -m email@example.com --issue --force --log --dns dns_cf -d example.com |
| |
| docker exec -it acme-sh /usr/bin/acme.sh --install-cert --key-file /cert/example.com/cert.key --fullchain-file /cert/example.com/cert.pem --log -d example.com |
- 完成