aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuqian Yang <crupest@crupest.life>2025-02-21 00:36:11 +0800
committerYuqian Yang <crupest@crupest.life>2025-02-21 00:58:57 +0800
commitda756422d9734d1d704e0cbcd248c17c30cd4f90 (patch)
tree7f2674c3a03e9cdd2b9624a8bc6b0479a1072f56
parentce16f3f4f3cec88335c49ab16f636efb5d2db2d6 (diff)
downloadcrupest-da756422d9734d1d704e0cbcd248c17c30cd4f90.tar.gz
crupest-da756422d9734d1d704e0cbcd248c17c30cd4f90.tar.bz2
crupest-da756422d9734d1d704e0cbcd248c17c30cd4f90.zip
feat(nginx): move certbot to nginx.
-rw-r--r--docker/auto-certbot/Dockerfile20
-rwxr-xr-xdocker/auto-certbot/daemon.bash107
-rwxr-xr-xdocker/auto-certbot/get-cert-domains.py38
-rw-r--r--docker/nginx/Dockerfile3
-rw-r--r--docker/nginx/certbot.bash9
-rw-r--r--docker/nginx/nginx-wrapper.bash7
-rw-r--r--templates/docker-compose.yaml.template27
7 files changed, 22 insertions, 189 deletions
diff --git a/docker/auto-certbot/Dockerfile b/docker/auto-certbot/Dockerfile
deleted file mode 100644
index eeb6475..0000000
--- a/docker/auto-certbot/Dockerfile
+++ /dev/null
@@ -1,20 +0,0 @@
-FROM certbot/certbot:latest
-
-ARG CRUPEST_AUTO_CERTBOT_ADDITIONAL_PACKAGES=""
-RUN apk add --no-cache tini coreutils bash ${CRUPEST_AUTO_CERTBOT_ADDITIONAL_PACKAGES} && python -m pip install cryptography
-
-
-ARG CRUPEST_DOMAIN
-ARG CRUPEST_ADDITIONAL_DOMAIN_LIST=""
-ARG CRUPEST_EMAIL
-ARG CRUPEST_AUTO_CERTBOT_POST_HOOK=""
-# install bash
-ENV CRUPEST_DOMAIN=${CRUPEST_DOMAIN}
-ENV CRUPEST_ADDITIONAL_DOMAIN_LIST=${CRUPEST_ADDITIONAL_DOMAIN_LIST}
-ENV CRUPEST_EMAIL=${CRUPEST_EMAIL}
-ENV CRUPEST_AUTO_CERTBOT_POST_HOOK=${CRUPEST_AUTO_CERTBOT_POST_HOOK}
-COPY daemon.bash /daemon.bash
-COPY get-cert-domains.py /get-cert-domains.py
-VOLUME ["/var/www/certbot", "/etc/letsencrypt", "/var/lib/letsencrypt"]
-ENTRYPOINT ["tini", "--"]
-CMD [ "/daemon.bash" ]
diff --git a/docker/auto-certbot/daemon.bash b/docker/auto-certbot/daemon.bash
deleted file mode 100755
index d79387e..0000000
--- a/docker/auto-certbot/daemon.bash
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-
-# Check I'm root.
-if [[ $EUID -ne 0 ]]; then
- echo "This script must be run as root" 1>&2
- exit 1
-fi
-
-# Check certbot version.
-certbot --version
-
-# Check domain
-if [[ -z "$CRUPEST_DOMAIN" ]]; then
- echo "CRUPEST_DOMAIN can't be empty!" 1>&2
- exit 1
-fi
-
-# Check email
-if [[ -z "$CRUPEST_EMAIL" ]]; then
- echo "CRUPEST_EMAIL can't be empty!" 1>&2
- exit 2
-fi
-
-# Check CRUPEST_CERT_PATH, default to /etc/letsencrypt/live/$CRUPEST_DOMAIN/fullchain.pem
-if [ -z "$CRUPEST_CERT_PATH" ]; then
- CRUPEST_CERT_PATH="/etc/letsencrypt/live/$CRUPEST_DOMAIN/fullchain.pem"
-fi
-
-# Check CRUPEST_CERT_PATH exists.
-if [ ! -f "$CRUPEST_CERT_PATH" ]; then
- echo "Cert file does not exist. You may want to generate it manually with aio script." 1>&2
- exit 3
-fi
-
-echo "Root domain:" "$CRUPEST_DOMAIN"
-echo "Email:" "$CRUPEST_EMAIL"
-echo "Cert path: ${CRUPEST_CERT_PATH}"
-
-# Check CRUPEST_AUTO_CERTBOT_RENEW_COMMAND is defined.
-if [ -z "$CRUPEST_AUTO_CERTBOT_RENEW_COMMAND" ]; then
- echo "CRUPEST_AUTO_CERTBOT_RENEW_COMMAND is not defined or empty. Will use the default one."
-else
- printf "CRUPEST_AUTO_CERTBOT_RENEW_COMMAND is defined as:\n%s\n" "$CRUPEST_AUTO_CERTBOT_RENEW_COMMAND"
-fi
-
-domains_str="$(/get-cert-domains.py "${CRUPEST_CERT_PATH}")"
-
-printf "Domain list:\n%s\n" "$domains_str"
-
-mapfile -t domains <<< "$domains_str"
-
-for domain in "${domains[@]}"; do
- domain_options=("${domain_options[@]}" -d "$domain")
-done
-
-options=(-n --agree-tos -m "$CRUPEST_EMAIL" --webroot -w /var/www/certbot "${domain_options[@]}")
-if [ -n "$CRUPEST_AUTO_CERTBOT_POST_HOOK" ]; then
- printf "You have defined a post hook:\n%s\n" "$CRUPEST_AUTO_CERTBOT_POST_HOOK"
- options=("${options[@]}" --post-hook "$CRUPEST_AUTO_CERTBOT_POST_HOOK")
-fi
-
-# Use test server to test.
-certbot certonly --force-renewal --test-cert --dry-run "${options[@]}"
-
-function check_and_renew_cert {
- expire_info=$(openssl x509 -enddate -noout -in "$CRUPEST_CERT_PATH")
-
- # Get ssl certificate expire date.
- expire_date=$(echo "$expire_info" | cut -d= -f2)
-
- echo "SSL certificate expire date: $expire_date"
-
- # Convert expire date to UNIX timestamp.
- expire_timestamp="$(date -d "$expire_date" +%s)"
-
- # Minus expire timestamp with 30 days in UNIX timestamp.
- renew_timestamp="$((expire_timestamp - 2592000))"
- echo "Renew SSL certificate at: $(date -d @$renew_timestamp)"
-
- # Get rest time til renew.
- rest_time_in_second="$((renew_timestamp - $(date +%s)))"
- rest_time_in_day=$((rest_time_in_second / 86400))
- echo "Rest time til renew: $rest_time_in_second seconds, aka, about $rest_time_in_day days"
-
- # Do we have rest time?
- if [ $rest_time_in_second -gt 0 ]; then
- # Sleep 1 hour.
- echo "I'm going to sleep for 1 day to check again."
- sleep 1d
- else
- # No, renew now.
- echo "Renewing now..."
-
- if [ -n "$CRUPEST_AUTO_CERTBOT_RENEW_COMMAND" ]; then
- $CRUPEST_AUTO_CERTBOT_RENEW_COMMAND
- else
- certbot certonly "${options[@]}"
- fi
- fi
-}
-
-# Run check_and_renew_cert in infinate loop.
-while true; do
- check_and_renew_cert
-done
diff --git a/docker/auto-certbot/get-cert-domains.py b/docker/auto-certbot/get-cert-domains.py
deleted file mode 100755
index 9bd28c8..0000000
--- a/docker/auto-certbot/get-cert-domains.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-from os.path import *
-from cryptography.x509 import *
-from cryptography.x509.oid import ExtensionOID
-
-# Check only one argument
-if len(sys.argv) != 2:
- print("You should only specify one argument, aka, the path of cert.",
- file=sys.stderr)
- exit(1)
-
-cert_path = sys.argv[1]
-
-if not exists(cert_path):
- print("Cert file does not exist.", file=sys.stderr)
- exit(2)
-
-if not isfile(cert_path):
- print("Cert path is not a file.")
- exit(3)
-
-if not 'CRUPEST_DOMAIN' in os.environ:
- print("Please set CRUPEST_DOMAIN environment variable to root domain.", file=sys.stderr)
- exit(4)
-
-root_domain = os.environ['CRUPEST_DOMAIN']
-
-with open(cert_path, 'rb') as f:
- cert = load_pem_x509_certificate(f.read())
- ext = cert.extensions.get_extension_for_oid(
- ExtensionOID.SUBJECT_ALTERNATIVE_NAME)
- domains: list = ext.value.get_values_for_type(DNSName)
- domains.remove(root_domain)
- domains = [root_domain, *domains]
- print('\n'.join(domains))
diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile
index 86052b9..67d41d1 100644
--- a/docker/nginx/Dockerfile
+++ b/docker/nginx/Dockerfile
@@ -7,3 +7,6 @@ RUN pnpm install --frozen-lockfile && pnpm run build
FROM nginx:mainline
COPY --from=build-www /sites/www/dist /srv/www
ADD sites/www/favicon.ico /srv/www/favicon.ico
+RUN apt update && apt-get install -y tini certbot && rm -rf /var/lib/apt/lists/*
+ADD --chmod=755 certbot.bash nginx-wrapper.bash /app/
+CMD ["/usr/bin/tini", "--", "/app/nginx-wrapper.bash"]
diff --git a/docker/nginx/certbot.bash b/docker/nginx/certbot.bash
new file mode 100644
index 0000000..0b8e3b7
--- /dev/null
+++ b/docker/nginx/certbot.bash
@@ -0,0 +1,9 @@
+#!/usr/bin/bash
+
+set -e
+
+while true; do
+ certbot renew --deploy-hook "nginx -s reload"
+ echo "Sleep one day before next certbot renew."
+ sleep 1d
+done
diff --git a/docker/nginx/nginx-wrapper.bash b/docker/nginx/nginx-wrapper.bash
new file mode 100644
index 0000000..bd566aa
--- /dev/null
+++ b/docker/nginx/nginx-wrapper.bash
@@ -0,0 +1,7 @@
+#!/usr/bin/bash
+
+set -e
+
+/app/certbot.bash &
+
+nginx "-g" "daemon off;"
diff --git a/templates/docker-compose.yaml.template b/templates/docker-compose.yaml.template
index 9005d5e..ea3e425 100644
--- a/templates/docker-compose.yaml.template
+++ b/templates/docker-compose.yaml.template
@@ -23,8 +23,10 @@ services:
volumes:
- "./generated/nginx/conf.d:/etc/nginx/conf.d:ro"
- "./generated/nginx/common:/etc/nginx/common:ro"
- - "./data/certbot/certs:/etc/letsencrypt:ro"
+ - "./data/certbot/certs:/etc/letsencrypt"
- "./data/certbot/webroot:/srv/acme:ro"
+ - "./data/certbot/data:/var/lib/letsencrypt"
+ - "./data/certbot/webroot:/var/www/certbot"
- "blog-public:/srv/www/blog:ro"
restart: on-failure:3
@@ -42,29 +44,6 @@ services:
- "./generated/v2ray-config.json:/etc/v2fly/config.json:ro"
restart: on-failure:3
- auto-certbot:
- pull_policy: build
- depends_on:
- - nginx
- build:
- context: ./docker/auto-certbot
- dockerfile: Dockerfile
- pull: true
- args:
- - CRUPEST_DOMAIN=@@CRUPEST_DOMAIN@@
- - CRUPEST_EMAIL=@@CRUPEST_EMAIL@@
- - CRUPEST_AUTO_CERTBOT_ADDITIONAL_PACKAGES=docker-cli
- - CRUPEST_AUTO_CERTBOT_POST_HOOK=docker restart nginx
- tags:
- - "crupest/auto-certbot:latest"
- volumes:
- - "./data/certbot/certs:/etc/letsencrypt"
- - "./data/certbot/data:/var/lib/letsencrypt"
- - "./data/certbot/webroot:/var/www/certbot"
- # map docker socket to allow auto-certbot to restart nginx
- - "/var/run/docker.sock:/var/run/docker.sock"
- restart: on-failure:3
-
auto-backup:
pull_policy: build
build: