# acme.sh Docker 自動化管理 SSL 証書完整指南

# ACME 協議和 acme.sh 簡介

# 什麼是 ACME 協議?

ACME(Automated Certificate Management Environment)是 IETF 標準協議,用於自動化 SSL/TLS 証書的申請、驗證、安裝和續期。

核心優勢:

  • 零成本:利用 Let's Encrypt 和 ZeroSSL 等免費簽發機構
  • 自動化:無需手動操作,定時自動續期
  • 安全:支持多種驗證方式(HTTP、DNS、TLSALPN)
  • 標準化:符合行業標準,多工具支持

# acme.sh 是什麼?

acme.sh 是用 Bash 編寫的 ACME 客戶端,特點:

  • 輕量級:純 Bash,占用資源少
  • 無依賴:不依賴 Python、NodeJS 等重型運行時
  • 功能全:支持 80+ 種 DNS API
  • 容器友好:易于 Docker 化和自動化
  • 活躍開發:社區維護,定期更新

# 簽證機構對比

機構免費驗證方式証書有效期續期難度
Let's EncryptHTTP/DNS/TLSALPN90 天簡單
ZeroSSLHTTP/DNS/ACME90 天簡單
CloudflareDNS無限期極簡

本教程重點:ZeroSSL(證書可視化管理,初學者友好)

# 環境準備

# 前置要求

# 系統:任何 Linux 或 Docker
# 網絡:需要訪問 ACME 伺服器(80/443 端口)
# DNS:使用 DNS 驗證時需要 DNS API 密鑰
# 檢查 Bash 版本
bash --version  # 需要 >= 4.0

# 依賴項

ACME.sh 最小依賴:

curl       # HTTP 客戶端(幾乎所有系統都有)
wget       # 備選 HTTP 客戶端
openssl    # 密碼學運算
socat      # 用於 HTTP 驗證的 TCP 中繼

# 核心概念詳解

# ACME 驗證流程

ACME 協議使用以下驗證方式:

# 1. HTTP 驗證(最簡單)

1. acme.sh 生成驗證文件 → /.well-known/acme-challenge/xxxxx
2. ACME 伺服器訪問 http://example.com/.well-known/acme-challenge/xxxxx
3. 驗證成功 → 簽發証書

優點:無需 DNS 權限
缺點:必須開放 80 端口,需要 Web 伺服器配置

# 2. DNS 驗證(推薦用於自動化)

1. acme.sh 行使 DNS API → 向 DNS 記錄添加 TXT 驗證值
2. ACME 伺服器查詢 DNS 記錄,驗證所有權
3. acme.sh 刪除 TXT 記錄 → 簽發証書

優點:支持泛域名 (*.example.com)、無需暴露 80 端口、完全自動化
缺點:需要 DNS 服務商的 API 密鑰

# 3. TLSALPN 驗證(實驗性)

直接使用 TLS 443 端口驗證,適合只開放 HTTPS 的環境。


# 運行模式對比

模式使用場景優缺點
系統服務VPS 長期運行全局 crontab;無容器開銷
Docker 容器多租戶、隔離環境可複用;版本一致;易于管理
K8s Job雲原生部署自動微服務集成;複雜度高

本教程重點:Docker 容器方案


# Docker 化 acme.sh 完整方案

# 目錄結構

acme-sh-docker/
├── Dockerfile              # 容器定義
├── docker-compose.yml      # 容器編排
├── .env                    # 環境變量
├── scripts/
│   ├── entry.sh            # 容器入口
│   ├── init.sh             # 證書初始化
│   └── renew.sh            # 手動續期腳本
└── volumes/
    ├── cert/               # 證書輸出目錄
    └── acme-home/          # acme.sh 主目錄

# Step 1: Dockerfile

FROM ubuntu:22.04
# 安裝依賴項
RUN apt-get update && apt-get install -y \
    curl wget tar gzip cron socat jq ca-certificates && \
    rm -rf /var/lib/apt/lists/*
# 設置時區
ENV TZ=Asia/Taipei
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
    echo $TZ > /etc/timezone
# 工作目錄
WORKDIR /app
# 複製腳本
COPY scripts/entry.sh .
COPY scripts/init.sh .
RUN chmod +x ./*.sh
# 暴露日誌卷
VOLUME /root/.acme.sh
VOLUME /cert
# 健康檢查
HEALTHCHECK --interval=60s --timeout=10s --start-period=30s --retries=3 \
    CMD curl -f http://localhost/health || exit 1
# 入口點
ENTRYPOINT ["/bin/bash", "-c", "/app/entry.sh"]

# Step 2: entry.sh (容器啟動入口)

#!/bin/bash
set -e
# 日誌函數
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
# 1. 安裝 acme.sh(首次運行)
if [[ ! -f /root/.acme.sh/acme.sh ]]; then
    log "Installing acme.sh..."
    curl -sSL https://get.acme.sh | sh -s email="${ACME_EMAIL}"
    ln -s /root/.acme.sh/acme.sh /usr/bin/acme.sh
fi
# 2. 設置默認 CA 和通知
log "Configuring acme.sh..."
acme.sh --set-default-ca --server "${ACME_SERVER:-zerossl}"
acme.sh --set-default-notify-hook telegram 2>/dev/null || true
# 3. 設置 cron 自動續期
log "Setting up cron for automatic renewal..."
(crontab -l 2>/dev/null || true; \
 echo "0 0 * * * /root/.acme.sh/acme.sh --cron --home /root/.acme.sh > /proc/1/fd/1 2>&1") | crontab -
# 4. 啟動 cron 服務
service cron start
# 5. 初始化日誌文件
touch /root/.acme.sh/acme.sh.log
log "acme.sh is ready!"
# 6. 监控日誌(保持容器運行)
tail -f /root/.acme.sh/acme.sh.log

# Step 3: init.sh (證書初始化腳本)

#!/bin/bash
# 使用方法:./init.sh/cert/example.com dns_cf example.com www.example.com
set -e
CERT_LOCATION="${1%/}"
DNS_API="$2"
shift 2
DOMAINS=("$@")
if [[ -z "$CERT_LOCATION" ]] || [[ -z "$DNS_API" ]] || [[ $
更新於

請我喝咖啡~( ̄▽ ̄)~*