onepush/onepush.sh
2025-07-11 06:53:44 +00:00

206 lines
No EOL
9 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 & SearXNG Installer (v19 - The Definitive)
#
# This script will:
# 1. Use the user's superior method of `curl` to fetch the default SearXNG config.
# 2. Surgically inject the Brave API key into the downloaded config.
# 3. Deploy a complete, secure, and automated stack for Open WebUI and SearXNG.
# ==============================================================================
# --- Safety Checks ---
set -euo pipefail
# --- Pre-flight Checks ---
if [[ "$EUID" -ne 0 ]]; then echo "❌ This script must be run as root."; exit 1; fi
if ! grep -qi "debian" /etc/os-release; then echo "⚠️ This script is optimized for Debian."; fi
# --- User Input ---
echo "---"
echo "Welcome to the Full Stack Open WebUI & SearXNG Installer."
echo "---"
read -p "Enter your domain for Open WebUI (e.g., ai.example.com): " UI_DOMAIN
read -p "Enter your email address (for Let's Encrypt): " EMAIL
read -p "Also secure the 'www' version of this domain (www.$UI_DOMAIN)? [y/N]: " UI_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 ""
read -p "Deploy a private SearXNG instance for the research tool? [y/N]: " DEPLOY_SEARXNG
BRAVE_API_KEY=""
if [[ "${DEPLOY_SEARXNG,,}" == "y" ]]; then
SEARCH_DOMAIN="search.r21.io"
echo " SearXNG will be deployed to https://$SEARCH_DOMAIN"
read -p "Enter your Brave Search API key (highly recommended, or press Enter): " BRAVE_API_KEY
fi
# --- Main Script ---
echo "---"; echo "✅ Thank you. Starting the setup."; sleep 3
# --- Configuration ---
UI_CONTAINER="open-webui"
SEARXNG_CONTAINER="searxng"
NETWORK_NAME="open-webui-net"
SEARXNG_CONFIG_DIR="/srv/searxng"
# --- Step 1: Dependencies ---
echo "▶️ [1/9] Installing dependencies..."
export DEBIAN_FRONTEND=noninteractive
apt-get update
BASE_PACKAGES="ca-certificates curl gnupg nginx certbot python3-certbot-nginx fail2ban unattended-upgrades"
if [[ "${DEPLOY_SEARXNG,,}" == "y" ]]; then apt-get install -y $BASE_PACKAGES apache2-utils; else apt-get install -y $BASE_PACKAGES; fi
# --- Step 2: Firewall Management ---
echo "▶️ [2/9] Managing Firewall..."
if [[ "${MANAGE_UFW,,}" != "n" ]]; then
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
if command -v ufw &> /dev/null && ufw status | grep -q "Status: active"; then
echo " - ⚠️ UFW is active but not managed. Disabling to prevent setup failure."
ufw disable
fi
fi
# --- Step 3: Docker & Network ---
echo "▶️ [3/9] Installing Docker and setting up network..."
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
if ! docker network ls | grep -q "$NETWORK_NAME"; then docker network create $NETWORK_NAME; fi
# --- Step 4: Stop Old Containers ---
echo "▶️ [4/9] Stopping and removing any old containers..."
docker stop $UI_CONTAINER $SEARXNG_CONTAINER 2>/dev/null || true
docker rm $UI_CONTAINER $SEARXNG_CONTAINER 2>/dev/null || true
# --- Step 5: Configure and Deploy SearXNG (Optional) ---
if [[ "${DEPLOY_SEARXNG,,}" == "y" ]]; then
echo "▶️ [5/9] Configuring and deploying SearXNG..."
# 1. Fetch the default settings.yml directly from GitHub
echo " - Fetching default SearXNG configuration from GitHub..."
sudo mkdir -p $SEARXNG_CONFIG_DIR
sudo curl -sL "https://raw.githubusercontent.com/searxng/searxng/master/searx/settings.yml" -o "$SEARXNG_CONFIG_DIR/settings.yml"
# 2. Surgically inject the Brave API key if provided
if [[ -n "$BRAVE_API_KEY" ]]; then
echo " - Injecting Brave API key..."
sudo sed -i "/^- name: brave/a \ api_key: \"$BRAVE_API_KEY\"" "$SEARXNG_CONFIG_DIR/settings.yml"
else
echo " - No Brave API key provided, using default settings."
fi
# 3. Add a mandatory secret_key
SECRET_KEY=$(gpg --gen-random --armor 1 24)
sudo sed -i "s/ultrasecretkey/\"$SECRET_KEY\"/" "$SEARXNG_CONFIG_DIR/settings.yml"
# 4. Set correct permissions
sudo chown -R 1000:1000 $SEARXNG_CONFIG_DIR
# 5. Launch the final container
echo " - Starting SearXNG container..."
docker run -d --name $SEARXNG_CONTAINER --network $NETWORK_NAME -v $SEARXNG_CONFIG_DIR:/etc/searxng --restart always searxng/searxng
else
echo "▶️ [5/9] Skipping SearXNG deployment."
fi
# --- Step 6: Deploy Open WebUI ---
echo "▶️ [6/9] Deploying Open WebUI..."
docker run -d -p 127.0.0.1:3000:8080 -v open-webui:/app/backend/data --name $UI_CONTAINER --network $NETWORK_NAME --restart always ghcr.io/open-webui/open-webui:main
# --- Step 7: Configure Nginx ---
echo "▶️ [7/9] Configuring Nginx sites..."
NGINX_UI_CONF="/etc/nginx/sites-available/$UI_DOMAIN"
if [[ "${UI_INCLUDE_WWW,,}" == "y" ]]; then UI_SERVER_NAME="$UI_DOMAIN www.$UI_DOMAIN"; else UI_SERVER_NAME="$UI_DOMAIN"; fi
cat <<EOF > "$NGINX_UI_CONF"
server {
listen 80; listen [::]:80; server_name $UI_SERVER_NAME;
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_UI_CONF" "/etc/nginx/sites-enabled/$UI_DOMAIN"
if [[ "${DEPLOY_SEARXNG,,}" == "y" ]]; then
NGINX_SEARCH_CONF="/etc/nginx/sites-available/$SEARCH_DOMAIN"
echo "Please set a password for the public SearXNG instance."
sudo htpasswd -c /etc/nginx/.htpasswd admin
cat <<EOF > "$NGINX_SEARCH_CONF"
server {
listen 80; listen [::]:80; server_name $SEARCH_DOMAIN;
location / {
resolver 127.0.0.11;
set \$searxng_upstream http://searxng:8080;
proxy_pass \$searxng_upstream;
auth_basic "Private Search Instance";
auth_basic_user_file /etc/nginx/.htpasswd;
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_set_header X-Forwarded-Host \$server_name;
}
}
EOF
ln -sfn "$NGINX_SEARCH_CONF" "/etc/nginx/sites-enabled/$SEARCH_DOMAIN"
fi
# --- Step 8: SSL Certificates & Automations ---
echo "▶️ [8/9] Obtaining SSL certificates and configuring automations..."
nginx -t
CERTBOT_STAGING_FLAG=""
if [[ "${USE_STAGING,,}" == "y" ]]; then CERTBOT_STAGING_FLAG="--staging"; fi
certbot --nginx -d $UI_SERVER_NAME $CERTBOT_STAGING_FLAG --non-interactive --agree-tos -m "$EMAIL" --redirect
if [[ "${DEPLOY_SEARXNG,,}" == "y" ]]; then
certbot --nginx -d $SEARCH_DOMAIN $CERTBOT_STAGING_FLAG --non-interactive --agree-tos -m "$EMAIL" --redirect
fi
NGINX_UI_LOG="/var/log/nginx/$UI_DOMAIN.access.log"
touch $NGINX_UI_LOG && chown www-data:adm $NGINX_UI_LOG
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_UI_LOG; maxretry = 5; findtime = 3600; bantime = 86400;
EOF
systemctl restart fail2ban
dpkg-reconfigure -plow unattended-upgrades
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
echo "0 9 * * 5 root /sbin/reboot" > /etc/cron.d/weekly-reboot
# --- Step 9: Finalization ---
echo "▶️ [9/9] Finalizing..."
systemctl restart nginx
echo "---"; echo "✅🎉 **DEPLOYMENT COMPLETE!** 🎉✅"; echo ""
echo "--- ACCESS ---"
echo " - Open WebUI: https://$UI_DOMAIN"
if [[ "${DEPLOY_SEARXNG,,}" == "y" ]]; then echo " - SearXNG: https://$SEARCH_DOMAIN (user: admin)"; fi
echo ""
echo "--- NEXT STEPS: ADDING THE RESEARCH TOOL ---"
if [[ "${DEPLOY_SEARXNG,,}" == "y" ]]; then
echo "1. Go to Open WebUI -> Settings -> Tools."
echo "2. Paste the Python code from https://github.com/iamarcel/open-webui-utils/blob/main/research_tool.py"
echo "3. Go to the Settings tab in the tool editor."
echo "4. Add Environment Variable: Key: SEARXNG_BASE_URL, Value: http://searxng:8080"
echo "5. Click 'Save'."
fi
echo "---"