onepush/onepush.sh
2025-07-08 07:18:52 +00:00

180 lines
No EOL
7.5 KiB
Bash
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# ==============================================================================
# Automated Open WebUI Installer for Debian (v8 - Robust Cron Job)
#
# This script will:
# 1. Use a robust /etc/cron.d file for the scheduled reboot, fixing a script hang.
# 2. Detect if UFW is active and handle it decisively.
# 3. Install all dependencies and deploy the full stack.
# 4. Configure all automations (updates, reboots, security).
# ==============================================================================
# --- Safety Checks ---
set -euo pipefail
# --- Pre-flight Checks ---
if [[ "$EUID" -ne 0 ]]; then
echo "❌ This script must be run as root. Please use 'sudo ./setup-webui.sh'"
exit 1
fi
if ! grep -qi "debian" /etc/os-release; then
echo "⚠️ This script is optimized for Debian. Running on another OS may have unintended results."
fi
# --- User Input ---
echo "---"
echo "Welcome to the Automated Open WebUI Installer."
echo "Please provide the following information:"
echo "---"
read -p "Enter your domain or subdomain (e.g., webui.example.com): " DOMAIN
if [[ -z "$DOMAIN" ]]; then echo "❌ Domain name cannot be empty."; exit 1; fi
read -p "Enter your email address (for Let's Encrypt): " EMAIL
if [[ -z "$EMAIL" ]]; then echo "❌ Email address cannot be empty."; exit 1; fi
read -p "Also secure the 'www' version of this domain (www.$DOMAIN)? [y/N]: " INCLUDE_WWW
read -p "Use Let's Encrypt staging environment (for testing)? [y/N]: " USE_STAGING
echo ""
if command -v ufw &> /dev/null; then
echo " UFW firewall is detected on this system."
read -p "Allow this script to manage UFW rules (allow HTTP/HTTPS)? [Y/n]: " MANAGE_UFW
else
read -p "Install and configure UFW firewall? (Recommended) [Y/n]: " MANAGE_UFW
fi
echo "---"
echo "✅ Thank you. Starting the setup for https://$DOMAIN"
echo "This process will take several minutes. Please do not interrupt it."
sleep 3
# --- Configuration Variables ---
CONTAINER_NAME="open-webui"
DATA_VOLUME="open-webui"
NGINX_CONF_PATH="/etc/nginx/sites-available/$DOMAIN"
NGINX_LOG_PATH="/var/log/nginx/$DOMAIN.access.log"
# --- Step 1: System Preparation and Dependencies ---
echo "▶️ [1/9] Updating system and installing dependencies..."
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y ca-certificates curl gnupg nginx certbot python3-certbot-nginx fail2ban unattended-upgrades
# --- Step 2: Configure Firewall (Decisive Handling) ---
if [[ "${MANAGE_UFW,,}" != "n" ]]; then
echo "▶️ [2/9] Managing Firewall (UFW)..."
if ! command -v ufw &> /dev/null; then apt-get install -y ufw; fi
ufw allow ssh > /dev/null
ufw allow 'Nginx Full' > /dev/null
ufw --force enable
else
echo "▶️ [2/9] Skipping firewall rule management as requested."
if command -v ufw &> /dev/null && ufw status | grep -q "Status: active"; then
echo " - ⚠️ UFW is active but not managed by this script. Disabling it now to prevent cert issuance failure."
ufw disable
fi
fi
# --- Step 3: Install Docker ---
echo "▶️ [3/9] Installing Docker..."
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# --- Step 4: Run Open WebUI Container ---
echo "▶️ [4/9] Deploying Open WebUI container..."
if [ "$(docker ps -q -f name=$CONTAINER_NAME)" ]; then docker stop $CONTAINER_NAME > /dev/null; fi
if [ "$(docker ps -aq -f status=exited -f name=$CONTAINER_NAME)" ]; then docker rm $CONTAINER_NAME > /dev/null; fi
docker run -d -p 127.0.0.1:3000:8080 \
--add-host=host.docker.internal:host-gateway \
-v $DATA_VOLUME:/app/backend/data \
--name $CONTAINER_NAME \
--restart always \
ghcr.io/open-webui/open-webui:main
# --- Step 5: Configure Nginx Reverse Proxy ---
echo "▶️ [5/9] Configuring Nginx..."
if [[ "${INCLUDE_WWW,,}" == "y" ]]; then NGINX_SERVER_NAME="$DOMAIN www.$DOMAIN"; else NGINX_SERVER_NAME="$DOMAIN"; fi
cat <<EOF > "$NGINX_CONF_PATH"
server {
listen 80; listen [::]:80;
server_name $NGINX_SERVER_NAME;
access_log $NGINX_LOG_PATH; error_log /var/log/nginx/$DOMAIN.error.log;
location / {
proxy_pass http://127.0.0.1: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;
proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade";
}
}
EOF
ln -sfn "$NGINX_CONF_PATH" "/etc/nginx/sites-enabled/$DOMAIN"
nginx -t && systemctl reload nginx
# --- Step 6: Obtain SSL Certificate ---
echo "▶️ [6/9] Obtaining SSL certificate with Certbot..."
if [[ "${INCLUDE_WWW,,}" == "y" ]]; then CERTBOT_DOMAINS="-d $DOMAIN -d www.$DOMAIN"; else CERTBOT_DOMAINS="-d $DOMAIN"; fi
CERTBOT_STAGING_FLAG=""
if [[ "${USE_STAGING,,}" == "y" ]]; then
echo " - Using Let's Encrypt STAGING environment for testing."
CERTBOT_STAGING_FLAG="--staging"
fi
certbot --nginx $CERTBOT_DOMAINS $CERTBOT_STAGING_FLAG --non-interactive --agree-tos -m "$EMAIL" --redirect
# --- Step 7: Configure Security Automations ---
echo "▶️ [7/9] Configuring Fail2Ban and automatic system updates..."
cat <<EOF > /etc/fail2ban/filter.d/open-webui.conf
[Definition]
failregex = ^<HOST> .* "POST /api/v1/auths/signin.*" 400
ignoreregex =
EOF
cat <<EOF > /etc/fail2ban/jail.d/open-webui.local
[open-webui]
enabled = true; port = http,https; filter = open-webui;
logpath = $NGINX_LOG_PATH; maxretry = 5; findtime = 3600; bantime = 86400;
EOF
systemctl restart fail2ban
dpkg-reconfigure -plow unattended-upgrades
# --- Step 8: Configure Service Automations ---
echo "▶️ [8/9] Deploying Watchtower and scheduling reboots..."
if ! [ "$(docker ps -q -f name=watchtower)" ]; then
docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock --restart always containrrr/watchtower
fi
# MODIFIED: Using a robust cron drop-in file instead of piping to crontab.
echo " - Scheduling weekly reboot for Friday at 09:00 UTC..."
echo "0 9 * * 5 root /sbin/reboot # Weekly reboot for system health" > /etc/cron.d/open-webui-reboot
# --- Step 9: Finalization ---
echo "▶️ [9/9] Finalizing and cleaning up..."
systemctl restart nginx
systemctl restart fail2ban
echo ""
echo "✅🎉 **DEPLOYMENT COMPLETE!** 🎉✅"
echo ""
echo "Open WebUI is now running and accessible at: https://$DOMAIN"
echo ""
echo "IMPORTANT NOTES:"
if [[ "${MANAGE_UFW,,}" == "n" ]]; then
echo " - ⚠️ UFW was detected and has been DISABLED to allow this script to complete."
echo " Your server's firewall is currently off. You are responsible for its configuration."
fi
if [[ "${USE_STAGING,,}" == "y" ]]; then
echo " - ⚠️ You used a STAGING certificate. Your site will show a browser security warning."
echo " To fix this, re-run this script after your rate limit expires and choose 'N' for staging."
fi
echo " - The Fail2Ban rule is active and will protect your login endpoint."
echo " - The first user to sign up will become the administrator."
echo " - Your system and the WebUI container will update automatically."
echo " - The server will reboot every Friday at 09:00 UTC."
echo ""