netgescon-day0/scripts/ops/netgescon-enable-https.sh

175 lines
4.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Enable HTTPS for NetGescon with Nginx + Let's Encrypt.
#
# Example:
# scripts/ops/netgescon-enable-https.sh \
# --domain staging.netgescon.it \
# --email admin@netgescon.it \
# --app-dir /var/www/netgescon \
# --nginx-site netgescon
DOMAINS=()
EMAIL=""
APP_DIR="/var/www/netgescon"
NGINX_SITE="netgescon"
UPDATE_ENV="yes"
while [[ $# -gt 0 ]]; do
case "$1" in
--domain)
DOMAINS+=("$2")
shift 2
;;
--email)
EMAIL="$2"
shift 2
;;
--app-dir)
APP_DIR="$2"
shift 2
;;
--nginx-site)
NGINX_SITE="$2"
shift 2
;;
--no-env-update)
UPDATE_ENV="no"
shift 1
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 --domain <host> [--domain <host2>] --email <email> [--app-dir /var/www/netgescon] [--nginx-site netgescon] [--no-env-update]"
exit 1
;;
esac
done
if [[ ${#DOMAINS[@]} -eq 0 ]]; then
echo "Error: at least one --domain is required"
exit 1
fi
if [[ -z "$EMAIL" ]]; then
echo "Error: --email is required"
exit 1
fi
if [[ ! -f "$APP_DIR/artisan" ]]; then
echo "Error: '$APP_DIR' does not look like a Laravel app (artisan missing)"
exit 1
fi
if ! command -v nginx >/dev/null 2>&1; then
echo "Error: nginx not installed"
exit 1
fi
if ! command -v certbot >/dev/null 2>&1; then
echo "Installing certbot + nginx plugin..."
sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx
fi
SITE_FILE="/etc/nginx/sites-available/$NGINX_SITE"
FIRST_DOMAIN="${DOMAINS[0]}"
SERVER_NAMES="${DOMAINS[*]}"
echo "Writing nginx HTTP vhost to $SITE_FILE ..."
sudo cp "$SITE_FILE" "${SITE_FILE}.backup.$(date +%Y%m%d-%H%M%S)" 2>/dev/null || true
sudo tee "$SITE_FILE" >/dev/null <<EOF
server {
listen 80;
listen [::]:80;
server_name ${SERVER_NAMES};
root ${APP_DIR}/public;
index index.php index.html;
location /.well-known/acme-challenge/ {
allow all;
}
location / {
try_files \$uri \$uri/ /index.php?\$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_read_timeout 300;
}
location ~ /\.(?!well-known).* {
deny all;
}
access_log /var/log/nginx/netgescon_access.log;
error_log /var/log/nginx/netgescon_error.log;
}
EOF
sudo ln -sf "$SITE_FILE" "/etc/nginx/sites-enabled/$NGINX_SITE"
sudo nginx -t
sudo systemctl reload nginx
CERTBOT_ARGS=(
--nginx
--non-interactive
--agree-tos
--redirect
--email "$EMAIL"
)
for domain in "${DOMAINS[@]}"; do
CERTBOT_ARGS+=("-d" "$domain")
done
echo "Requesting/renewing certificate for: ${SERVER_NAMES}"
sudo certbot "${CERTBOT_ARGS[@]}"
if [[ "$UPDATE_ENV" == "yes" && -f "$APP_DIR/.env" ]]; then
echo "Updating Laravel env for secure sessions..."
if grep -q '^APP_URL=' "$APP_DIR/.env"; then
sed -i "s#^APP_URL=.*#APP_URL=https://${FIRST_DOMAIN}#" "$APP_DIR/.env"
else
echo "APP_URL=https://${FIRST_DOMAIN}" >> "$APP_DIR/.env"
fi
if grep -q '^SESSION_SECURE_COOKIE=' "$APP_DIR/.env"; then
sed -i 's/^SESSION_SECURE_COOKIE=.*/SESSION_SECURE_COOKIE=true/' "$APP_DIR/.env"
else
echo 'SESSION_SECURE_COOKIE=true' >> "$APP_DIR/.env"
fi
if grep -q '^SESSION_SAME_SITE=' "$APP_DIR/.env"; then
sed -i 's/^SESSION_SAME_SITE=.*/SESSION_SAME_SITE=lax/' "$APP_DIR/.env"
else
echo 'SESSION_SAME_SITE=lax' >> "$APP_DIR/.env"
fi
STATEFUL="$(IFS=, ; echo "${DOMAINS[*]}")"
if grep -q '^SANCTUM_STATEFUL_DOMAINS=' "$APP_DIR/.env"; then
sed -i "s#^SANCTUM_STATEFUL_DOMAINS=.*#SANCTUM_STATEFUL_DOMAINS=${STATEFUL}#" "$APP_DIR/.env"
else
echo "SANCTUM_STATEFUL_DOMAINS=${STATEFUL}" >> "$APP_DIR/.env"
fi
pushd "$APP_DIR" >/dev/null
php artisan optimize:clear
# route:cache can fail on duplicated route names in legacy modules; keep HTTPS activation successful.
php artisan config:cache || true
php artisan event:cache || true
php artisan view:cache || true
popd >/dev/null
fi
sudo nginx -t
sudo systemctl reload nginx
echo "HTTPS enabled successfully for: ${SERVER_NAMES}"
echo "Check: https://${FIRST_DOMAIN}"