feat(nginx): add nginx + functionality to toggle between letsencrypt, custom-ssl and http-only modes in .env file

This commit is contained in:
2026-04-14 21:10:43 +08:00
parent b5e7422754
commit 2d00e454c9
5 changed files with 365 additions and 138 deletions

View File

@@ -1,47 +1,147 @@
#!/usr/bin/env bash
set -e
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'
if [ ! -f ".env" ]; then
echo "[ERROR] .env file not found. Skipping SSL setup."
echo -e "${RED}[ERROR] .env file not found. Skipping SSL setup.${NC}"
exit 1
fi
source .env
if [[ ! "$GITEA_EXTERNAL_URL" == https://* ]]; then
echo "[INFO] HTTPS not enabled in GITEA_EXTERNAL_URL. Skipping SSL setup."
exit 0
fi
SSL_MODE="${SSL_MODE:-none}"
NGINX_CONF_DIR="./nginx/conf.d"
NGINX_SSL_DIR="./nginx/ssl"
if [[ -z "$SSL_CERT_PATH" || -z "$SSL_KEY_PATH" ]]; then
echo "[INFO] SSL_CERT_PATH or SSL_KEY_PATH not set. Skipping SSL copy."
exit 0
fi
mkdir -p "$NGINX_CONF_DIR" "$NGINX_SSL_DIR"
if [ ! -f "$SSL_CERT_PATH" ]; then
echo "[ERROR] Certificate file not found: $SSL_CERT_PATH"
# ── Helper: write HTTP-only config ──
write_http_conf() {
cat > "$NGINX_CONF_DIR/gitea.conf" <<'NGINX'
server {
listen 80;
server_name _;
location / {
proxy_pass http://gitea:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 512M;
}
}
NGINX
}
# ── Helper: write HTTPS config (works for both letsencrypt & custom) ──
write_https_conf() {
local cert_path="$1"
local key_path="$2"
cat > "$NGINX_CONF_DIR/gitea.conf" <<NGINX
server {
listen 80;
server_name ${GITEA_DOMAIN};
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://\$host\$request_uri;
}
}
server {
listen 443 ssl http2;
server_name ${GITEA_DOMAIN};
ssl_certificate ${cert_path};
ssl_certificate_key ${key_path};
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://gitea:3000;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
client_max_body_size 512M;
}
}
NGINX
}
# ── Main logic ──
case "$SSL_MODE" in
none)
echo -e "${YELLOW}[SSL] Mode: none — HTTP only${NC}"
write_http_conf
;;
letsencrypt)
echo -e "${GREEN}[SSL] Mode: letsencrypt${NC}"
if [[ -z "$LETSENCRYPT_EMAIL" ]]; then
echo -e "${RED}[ERROR] LETSENCRYPT_EMAIL is required for letsencrypt mode.${NC}"
exit 1
fi
if [[ -z "$GITEA_DOMAIN" ]]; then
echo -e "${RED}[ERROR] GITEA_DOMAIN is required for letsencrypt mode.${NC}"
exit 1
fi
CERT="/etc/letsencrypt/live/${GITEA_DOMAIN}/fullchain.pem"
KEY="/etc/letsencrypt/live/${GITEA_DOMAIN}/privkey.pem"
# If certs don't exist yet, start with HTTP-only so Nginx can boot
# for the ACME challenge. After certbot runs we'll switch to HTTPS.
if docker volume inspect gitea-deployment_certbot_certs >/dev/null 2>&1 && \
docker run --rm -v gitea-deployment_certbot_certs:/etc/letsencrypt alpine \
test -f "/etc/letsencrypt/live/${GITEA_DOMAIN}/fullchain.pem" 2>/dev/null; then
echo "[SSL] Existing Let's Encrypt certs found. Writing HTTPS config."
write_https_conf "$CERT" "$KEY"
else
echo "[SSL] No certs yet. Writing temporary HTTP config for ACME challenge."
write_http_conf
fi
;;
custom)
echo -e "${GREEN}[SSL] Mode: custom${NC}"
if [[ -z "$SSL_CERT_PATH" || -z "$SSL_KEY_PATH" ]]; then
echo -e "${RED}[ERROR] SSL_CERT_PATH and SSL_KEY_PATH are required for custom mode.${NC}"
exit 1
fi
if [[ ! -f "$SSL_CERT_PATH" ]]; then
echo -e "${RED}[ERROR] Certificate not found: $SSL_CERT_PATH${NC}"
exit 1
fi
if [[ ! -f "$SSL_KEY_PATH" ]]; then
echo -e "${RED}[ERROR] Key not found: $SSL_KEY_PATH${NC}"
exit 1
fi
cp "$SSL_CERT_PATH" "$NGINX_SSL_DIR/cert.pem"
cp "$SSL_KEY_PATH" "$NGINX_SSL_DIR/key.pem"
chmod 600 "$NGINX_SSL_DIR/key.pem"
write_https_conf "/etc/nginx/ssl/cert.pem" "/etc/nginx/ssl/key.pem"
echo -e "${GREEN}[SSL] Custom certificates copied to $NGINX_SSL_DIR${NC}"
;;
*)
echo -e "${RED}[ERROR] Unknown SSL_MODE: $SSL_MODE (expected: none, letsencrypt, custom)${NC}"
exit 1
fi
;;
esac
if [ ! -f "$SSL_KEY_PATH" ]; then
echo "[ERROR] Key file not found: $SSL_KEY_PATH"
exit 1
fi
echo "[INFO] Preparing Gitea SSL directory..."
mkdir -p ${GITEA_DATA_PATH}/gitea/https
echo "[INFO] Copying SSL certificates..."
cp "$SSL_CERT_PATH" ${GITEA_DATA_PATH}/gitea/https/cert.pem
cp "$SSL_KEY_PATH" ${GITEA_DATA_PATH}/gitea/https/key.pem
chmod 600 ${GITEA_DATA_PATH}/gitea/https/key.pem
echo "[SUCCESS] SSL certificates copied."
echo "Gitea will load them from:"
echo " /data/https/cert.pem"
echo " /data/https/key.pem"
echo -e "${GREEN}[SSL] Nginx config written to $NGINX_CONF_DIR/gitea.conf${NC}"