#!/usr/bin/env bash # scripts/provision-production-tls.sh # Issue/renew Let's Encrypt certificate via DNS-01 (Cloudflare), then install # cert/key into nginx/ssl paths used by the existing Nginx config. set -euo pipefail REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" DOMAIN="${DOMAIN:-nxt.bhatfamily.in}" SSL_DIR="${REPO_DIR}/nginx/ssl" LE_DIR="${SSL_DIR}/letsencrypt" PROPAGATION_SECONDS="${CF_DNS_PROPAGATION_SECONDS:-60}" if ! command -v docker >/dev/null 2>&1; then echo "ERROR: docker is required but not found." exit 1 fi if [ -z "${CF_DNS_API_TOKEN:-}" ]; then echo "ERROR: CF_DNS_API_TOKEN is not set." echo "Export it first, then rerun this script." exit 1 fi if [ -z "${LETSENCRYPT_EMAIL:-}" ]; then echo "ERROR: LETSENCRYPT_EMAIL is not set." echo "Export it first, then rerun this script." exit 1 fi mkdir -p "${LE_DIR}" "${SSL_DIR}" CF_CREDS_FILE="$(mktemp)" cleanup() { rm -f "${CF_CREDS_FILE}" } trap cleanup EXIT chmod 600 "${CF_CREDS_FILE}" printf 'dns_cloudflare_api_token = %s\n' "${CF_DNS_API_TOKEN}" > "${CF_CREDS_FILE}" echo "==> Requesting/renewing Let's Encrypt cert for ${DOMAIN} via Cloudflare DNS-01..." docker run --rm \ -v "${LE_DIR}:/etc/letsencrypt" \ -v "${CF_CREDS_FILE}:/run/secrets/cloudflare.ini:ro" \ certbot/dns-cloudflare:latest certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /run/secrets/cloudflare.ini \ --dns-cloudflare-propagation-seconds "${PROPAGATION_SECONDS}" \ --non-interactive \ --agree-tos \ --email "${LETSENCRYPT_EMAIL}" \ --keep-until-expiring \ --preferred-challenges dns-01 \ --rsa-key-size 4096 \ -d "${DOMAIN}" echo "==> Installing production certificate into nginx/ssl..." docker run --rm \ -v "${LE_DIR}:/etc/letsencrypt:ro" \ -v "${SSL_DIR}:/work" \ alpine:3.20 sh -lc " test -f /etc/letsencrypt/live/${DOMAIN}/fullchain.pem && \ test -f /etc/letsencrypt/live/${DOMAIN}/privkey.pem && \ cp /etc/letsencrypt/live/${DOMAIN}/fullchain.pem /work/${DOMAIN}.crt && \ cp /etc/letsencrypt/live/${DOMAIN}/privkey.pem /work/${DOMAIN}.key && \ chmod 0644 /work/${DOMAIN}.crt && \ chmod 0600 /work/${DOMAIN}.key " echo "==> Production TLS material installed:" echo " ${SSL_DIR}/${DOMAIN}.crt" echo " ${SSL_DIR}/${DOMAIN}.key" echo "" echo "Next step: restart web service (or full stack) to pick up the new certificate."