Merge pull request 'feat: Add optional SearXNG deployment for web search' (#1) from searxng into master
Reviewed-on: #1
This commit is contained in:
commit
1504d66a69
2 changed files with 220 additions and 125 deletions
80
README.md
80
README.md
|
@ -1,27 +1,29 @@
|
|||
# Automated Open WebUI Installer for Debian
|
||||
# Automated Open WebUI & SearXNG Installer
|
||||
|
||||

|
||||
|
||||
A single, robust, and intelligent shell script to fully automate the deployment of [Open WebUI](https://github.com/open-webui/open-webui) on a Debian server. This script transforms a manual setup process into a production-ready, one-shot command, complete with security hardening and full life-cycle automation.
|
||||
A single, robust, and intelligent shell script to fully automate the deployment of [Open WebUI](https://github.com/open-webui/open-webui) and an optional, private [SearXNG](https://github.com/searxng/searxng) instance on a Debian server. This script transforms a manual setup process into a production-ready, one-shot command, complete with security hardening and full life-cycle automation.
|
||||
|
||||
This project was born from an iterative process of converting a manual guide into a fully automated script, adding features and fixing real-world deployment issues like Let's Encrypt rate limits, firewall pre-configurations, and fragile cron job commands.
|
||||
This project was born from an iterative process of converting a manual guide into a fully automated script, adding features and fixing real-world deployment issues like Let's Encrypt rate limits, firewall pre-configurations, fragile cron jobs, and complex multi-container networking and configuration bugs.
|
||||
|
||||
## Features
|
||||
|
||||
- **Fully Automated Deployment:** Runs non-interactively after an initial prompt for configuration details.
|
||||
- **Optional SearXNG Stack:**
|
||||
- Deploys a private SearXNG instance on a secure Docker network.
|
||||
- Exposes it publicly on a separate subdomain with Basic Auth protection.
|
||||
- Allows internal access from Open WebUI tools without authentication for fast, secure searching.
|
||||
- Supports an optional Brave Search API key for enhanced, ad-free results.
|
||||
- **Adds a custom JSON engine** to SearXNG for advanced integrations.
|
||||
- **Security First:**
|
||||
- **Firewall Aware:** Intelligently detects and manages `UFW`, ensuring web ports are open or disabling it decisively to prevent silent failures.
|
||||
- **Brute-Force Protection:** Installs and configures `Fail2Ban` with a precise filter to block IPs that repeatedly fail login attempts.
|
||||
- **Robust Service Management:** Deploys Open WebUI via Docker, the recommended method, with the application port bound securely to the local interface.
|
||||
- **Automatic HTTPS:** Uses Nginx as a reverse proxy and `Certbot` to automatically obtain and renew a free Let's Encrypt SSL certificate.
|
||||
- **Firewall Aware:** Intelligently detects and manages `UFW`.
|
||||
- **Brute-Force Protection:** Installs and configures `Fail2Ban` to protect the Open WebUI login.
|
||||
- **Robust Service Management:** Deploys services via Docker on a shared private network, the recommended method.
|
||||
- **Automatic HTTPS:** Uses Nginx as a reverse proxy and `Certbot` to automatically obtain and renew free Let's Encrypt SSL certificates.
|
||||
- **Production-Ready Automation:**
|
||||
- **System Updates:** Configures `unattended-upgrades` to automatically apply system security patches.
|
||||
- **Container Updates:** Deploys `Watchtower` to automatically update the Open WebUI container to the latest version.
|
||||
- **Scheduled Reboots:** Implements a robust weekly reboot via a cron job for system health and to apply kernel updates.
|
||||
- **Intelligent & Flexible:**
|
||||
- Handles both root domains (with/without `www`) and subdomains correctly.
|
||||
- Includes a **Let's Encrypt Staging Mode** to prevent rate-limiting during testing.
|
||||
- Uses a reliable `cron.d` file for scheduling, avoiding common scripting pitfalls.
|
||||
- **System Updates:** Configures `unattended-upgrades`.
|
||||
- **Container Updates:** Deploys `Watchtower` for automatic container updates.
|
||||
- **Scheduled Reboots:** Implements a robust weekly reboot via a `cron.d` file.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
@ -29,27 +31,24 @@ Before running the script, you will need:
|
|||
|
||||
1. A server running **Debian 11 or 12**.
|
||||
2. `sudo` or `root` access.
|
||||
3. A domain or subdomain with a DNS **A record** pointing to your server's public IP address.
|
||||
3. A domain for Open WebUI (e.g., `ai.example.com`) with a DNS **A record** pointing to your server's IP.
|
||||
4. **If deploying SearXNG**, a second domain (e.g., `search.example.com`) also pointing to your server's IP. *(The script uses `search.example.com` by default but the variable can be changed)*.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Clone this repository to your Debian server:
|
||||
1. Download the script to your Debian server:
|
||||
```bash
|
||||
curl -fsSL -o onepush.sh https://git.r21.io/primemover/onepush/raw/branch/master/onepush.sh
|
||||
```
|
||||
|
||||
2. Make the script executable:
|
||||
```bash
|
||||
chmod +x onepush.sh
|
||||
```
|
||||
|
||||
3. Run the script with `sudo`:
|
||||
```bash
|
||||
sudo ./onepush.sh
|
||||
```
|
||||
|
||||
The script will then prompt you for the necessary configuration details before proceeding with the automated installation.
|
||||
|
||||
### The Interactive Prompts
|
||||
|
||||
The script will ask you a few questions to configure your environment:
|
||||
|
@ -67,11 +66,14 @@ The script will ask you a few questions to configure your environment:
|
|||
- Answer `Y` (the default) to have the script automatically add the `allow 'Nginx Full'` rule.
|
||||
- Answer `n` if you want to manage the firewall yourself. **If you choose 'n' and UFW is active, the script will disable UFW entirely** to guarantee the script can complete.
|
||||
|
||||
The script will then prompt you for the necessary configuration details before proceeding with the automated installation.
|
||||
|
||||
## Post-Installation
|
||||
|
||||
Once the script finishes, you will have a fully functional and secure Open WebUI instance.
|
||||
|
||||
- **Access Your Instance:** `https://your.domain.com`
|
||||
- **Access Your Instance:** `https://ai.example.com`
|
||||
- **Access SearXNG:** `https://search.example.com` (user: `admin`, with the password you set during installation).
|
||||
- **Admin Account:** The first user to register on the site will automatically be granted administrator privileges.
|
||||
- **Automations:** All automated services (system updates, container updates, reboots) are running in the background. No further action is needed.
|
||||
|
||||
|
@ -83,9 +85,43 @@ The most common reason to re-run the script is to get a production SSL certifica
|
|||
|
||||
## Security Considerations
|
||||
|
||||
- **Fail2Ban:** The jail `[open-webui]` is configured in `/etc/fail2ban/jail.d/open-webui.local`. It monitors the Nginx log file (`/var/log/nginx/your.domain.com.access.log`) for failed sign-in attempts (`POST /api/v1/auths/signin` with a `400` status code). After 5 failures, the offending IP is banned for 24 hours.
|
||||
- **Fail2Ban:** The jail `[open-webui]` is configured in `/etc/fail2ban/jail.d/open-webui.local`. It monitors the Nginx log file (`/var/log/nginx/ai.example.com.access.log`) for failed sign-in attempts (`POST /api/v1/auths/signin` with a `400` status code). After 5 failures, the offending IP is banned for 24 hours.
|
||||
- **Firewall:** The script binds the Open WebUI Docker container to the localhost interface (`127.0.0.1:3000`), meaning it is not directly exposed to the internet. Only Nginx can access it. If you opt-out of UFW management, you are responsible for ensuring a firewall (either on the host or at the network level) is configured to allow traffic on ports 80 and 443.
|
||||
|
||||
### Using Your Private SearXNG Instance
|
||||
|
||||
If you deployed SearXNG, you now have two powerful ways to enable web search for your models.
|
||||
|
||||
#### Option A: Native Web Search (Recommended)
|
||||
|
||||
This is the simplest and most integrated method.
|
||||
|
||||
1. Log in to Open WebUI as an admin.
|
||||
2. Go to the **Admin Panel** -> **Settings** -> **Web Search**.
|
||||
3. Enable the **Web Search** toggle.
|
||||
4. In the **SearXNG URL** field, enter: `http://searxng:8080`
|
||||
*(This special URL works because the containers can talk to each other directly over their private Docker network).*
|
||||
5. Click **Save**.
|
||||
|
||||
You can now enable the "Web Search" capability for any model in the "Models" section of your settings.
|
||||
|
||||
#### Option B: Advanced Python Research Tool
|
||||
|
||||
This method provides more granular control and is useful for complex workflows.
|
||||
|
||||
1. Go to **Settings** -> **Tools** and click **Add Tool**.
|
||||
2. In the **Load from URL** field, paste the following link and click the load button:
|
||||
```
|
||||
https://raw.githubusercontent.com/iamarcel/open-webui-utils/main/research_tool.py
|
||||
```
|
||||
3. Click the **Settings** tab in the tool editor (the gear icon).
|
||||
4. In the **Environment Variables** section, add the following key-value pair:
|
||||
- **Key:** `SEARXNG_BASE_URL`
|
||||
- **Value:** `http://searxng:8080`
|
||||
5. Click **Save**.
|
||||
|
||||
The tool is now installed and can be called in any chat using `@research`.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
265
onepush.sh
265
onepush.sh
|
@ -1,42 +1,29 @@
|
|||
#!/bin/bash
|
||||
|
||||
# ==============================================================================
|
||||
# Automated Open WebUI Installer for Debian (v8 - Robust Cron Job)
|
||||
# Automated Open WebUI & SearXNG Installer (v27 - The Final)
|
||||
#
|
||||
# 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).
|
||||
# 1. Deploy a complete, secure, and automated stack for Open WebUI.
|
||||
# 2. Optionally deploy SearXNG and add a user-defined JSON engine override.
|
||||
# 3. All previous bug fixes and best practices are retained.
|
||||
# ==============================================================================
|
||||
|
||||
# --- 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
|
||||
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 Automated Open WebUI Installer."
|
||||
echo "Please provide the following information:"
|
||||
echo "Welcome to the Full Stack Open WebUI & SearXNG Installer."
|
||||
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 domain for Open WebUI (e.g., ai.example.com): " UI_DOMAIN
|
||||
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 "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."
|
||||
|
@ -44,70 +31,123 @@ if command -v ufw &> /dev/null; then
|
|||
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=""
|
||||
SEARCH_DOMAIN=""
|
||||
if [[ "${DEPLOY_SEARXNG,,}" == "y" ]]; then
|
||||
# MODIFIED: Prompt for the SearXNG domain instead of hardcoding it.
|
||||
read -p "Enter the domain for SearXNG (e.g., search.example.com): " SEARCH_DOMAIN
|
||||
if [[ -z "$SEARCH_DOMAIN" ]]; then echo "❌ SearXNG domain cannot be empty."; exit 1; 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
|
||||
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
|
||||
|
||||
# --- 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"
|
||||
# --- Main Script ---
|
||||
echo "---"; echo "✅ Thank you. Starting the setup."; sleep 3
|
||||
|
||||
# --- Step 1: System Preparation and Dependencies ---
|
||||
echo "▶️ [1/9] Updating system and installing dependencies..."
|
||||
# --- 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
|
||||
apt-get install -y ca-certificates curl gnupg nginx certbot python3-certbot-nginx fail2ban unattended-upgrades
|
||||
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: Configure Firewall (Decisive Handling) ---
|
||||
# --- Step 2: Firewall Management ---
|
||||
echo "▶️ [2/9] Managing Firewall..."
|
||||
if [[ -z "${MANAGE_UFW+x}" ]]; then MANAGE_UFW="y"; fi
|
||||
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
|
||||
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."
|
||||
echo " - ⚠️ UFW is active but not managed. Disabling to prevent setup failure."
|
||||
ufw disable
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Step 3: Install Docker ---
|
||||
echo "▶️ [3/9] Installing Docker..."
|
||||
# --- 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
|
||||
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: 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 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 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"
|
||||
# --- Step 5: Configure and Deploy SearXNG (Optional) ---
|
||||
if [[ "${DEPLOY_SEARXNG,,}" == "y" ]]; then
|
||||
echo "▶️ [5/9] Configuring and deploying SearXNG..."
|
||||
|
||||
# Create a user-defined settings override to add the JSON engine
|
||||
sudo mkdir -p $SEARXNG_CONFIG_DIR
|
||||
sudo tee "$SEARXNG_CONFIG_DIR/user.yml" >/dev/null <<'EOF'
|
||||
use_default_settings: true # <- keep everything from the upstream settings
|
||||
search:
|
||||
formats:
|
||||
- html
|
||||
- json
|
||||
EOF
|
||||
sudo chown 1000:1000 "$SEARXNG_CONFIG_DIR/user.yml"
|
||||
|
||||
# Generate a robust, shell-safe secret key
|
||||
set +o pipefail
|
||||
SECRET_KEY=$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 32)
|
||||
set -o pipefail
|
||||
|
||||
# Build the docker run command safely in an array
|
||||
docker_cmd=(
|
||||
docker run -d
|
||||
--name "$SEARXNG_CONTAINER"
|
||||
--network "$NETWORK_NAME"
|
||||
-p "127.0.0.1:8081:8080"
|
||||
-v "$SEARXNG_CONFIG_DIR:/etc/searxng"
|
||||
-e "SEARXNG_SETTINGS_PATH=/etc/searxng/user.yml"
|
||||
-e "SEARXNG_SECRET=$SECRET_KEY"
|
||||
-e "SEARXNG_BIND_ADDRESS=0.0.0.0"
|
||||
-e "SEARXNG_BASE_URL=https://$SEARCH_DOMAIN"
|
||||
--restart always
|
||||
)
|
||||
|
||||
# Add optional Brave integration
|
||||
if [[ -n "$BRAVE_API_KEY" ]]; then
|
||||
echo " - Enabling Brave engine with API key..."
|
||||
docker_cmd+=(
|
||||
-e "SEARXNG_ENGINES_BRAVE_API_KEY=$BRAVE_API_KEY"
|
||||
-e "SEARXNG_ENGINES_BRAVE_DISABLED=false"
|
||||
)
|
||||
fi
|
||||
|
||||
docker_cmd+=(searxng/searxng)
|
||||
"${docker_cmd[@]}"
|
||||
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 $NGINX_SERVER_NAME;
|
||||
access_log $NGINX_LOG_PATH; error_log /var/log/nginx/$DOMAIN.error.log;
|
||||
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;
|
||||
|
@ -116,21 +156,41 @@ server {
|
|||
}
|
||||
}
|
||||
EOF
|
||||
ln -sfn "$NGINX_CONF_PATH" "/etc/nginx/sites-enabled/$DOMAIN"
|
||||
nginx -t && systemctl reload nginx
|
||||
ln -sfn "$NGINX_UI_CONF" "/etc/nginx/sites-enabled/$UI_DOMAIN"
|
||||
|
||||
# --- 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"
|
||||
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 / {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
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
|
||||
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..."
|
||||
# --- 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
|
||||
|
@ -139,42 +199,41 @@ 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;
|
||||
logpath = $NGINX_UI_LOG; 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
|
||||
echo "0 9 * * 5 root /sbin/reboot" > /etc/cron.d/weekly-reboot
|
||||
|
||||
# --- Step 9: Finalization ---
|
||||
echo "▶️ [9/9] Finalizing and cleaning up..."
|
||||
echo "▶️ [9/9] Finalizing..."
|
||||
systemctl restart nginx
|
||||
systemctl restart fail2ban
|
||||
|
||||
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 "✅🎉 **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."
|
||||
echo "--- NEXT STEPS: USING YOUR PRIVATE SEARCH ENGINE ---"
|
||||
if [[ "${DEPLOY_SEARXNG,,}" == "y" ]]; then
|
||||
echo "You now have two ways to use your private SearXNG instance:"
|
||||
echo ""
|
||||
echo " OPTION A: Native Web Search (Recommended for most users)"
|
||||
echo " 1. Go to your Open WebUI Admin Panel -> Settings -> Web Search."
|
||||
echo " 2. Enable the 'Web Search' toggle."
|
||||
echo " 3. In the 'SearXNG URL' field, enter: http://searxng:8080"
|
||||
echo " (This works because the containers are on a private network)."
|
||||
echo " 4. Save settings. You can now enable web search for any model."
|
||||
echo ""
|
||||
echo " OPTION B: Advanced Python Research Tool (For custom logic)"
|
||||
echo " 1. Go to Settings -> Tools and click 'Add Tool'."
|
||||
echo " 2. In the 'Load from URL' field, paste:"
|
||||
echo " https://raw.githubusercontent.com/iamarcel/open-webui-utils/main/research_tool.py"
|
||||
echo " 3. Go to the tool's 'Settings' tab (gear icon)."
|
||||
echo " 4. Add Environment Variable -> Key: SEARXNG_BASE_URL, Value: http://searxng:8080"
|
||||
echo " 5. Save the tool. You can now call it with '@research' in a chat."
|
||||
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 ""
|
||||
echo "---"
|
Loading…
Add table
Add a link
Reference in a new issue