This tutorial is a community contribution and is not supported by the Open WebUI team. It serves only as a demonstration on how to customize Open WebUI for your specific use case. Want to contribute? Check out the contributing tutorial.
HTTPS using Nginx
Ensuring secure communication between your users and the Open WebUI is paramount. HTTPS (HyperText Transfer Protocol Secure) encrypts the data transmitted, protecting it from eavesdroppers and tampering. By configuring Nginx as a reverse proxy, you can seamlessly add HTTPS to your Open WebUI deployment, enhancing both security and trustworthiness.
This guide provides three methods to set up HTTPS:
- Self-Signed Certificates: Ideal for development and internal use, using docker.
- Let's Encrypt: Perfect for production environments requiring trusted SSL certificates, using docker.
- Windows+Self-Signed: Simplified instructions for development and internal use on windows, no docker required.
Choose the method that best fits your deployment needs.
- Nginx Proxy Manager
- Let's Encrypt
- Self-Signed
- Windows
Nginx Proxy Managerβ
Nginx Proxy Manager (NPM) allows you to easily manage reverse proxies and secure your local applications, like Open WebUI, with valid SSL certificates from Let's Encrypt. This setup enables HTTPS access, which is necessary for using voice input features on many mobile browsers due to their security requirements, without exposing the application's specific port directly to the internet.
Prerequisitesβ
- A home server running Docker and open-webui container running.
- A domain name (free options like DuckDNS or paid ones like Namecheap/GoDaddy).
- Basic knowledge of Docker and DNS configuration.
Nginx Proxy Manager Stepsβ
-
Create Directories for Nginx Files:
mkdir ~/nginx_config
cd ~/nginx_config -
Set Up Nginx Proxy Manager with Docker:
nano docker-compose.yml
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
Run the container:
docker-compose up -d
-
Configure DNS and Domain:
- Log in to your domain provider (e.g., DuckDNS) and create a domain.
- Point the domain to your proxyβs local IP (e.g., 192.168.0.6).
- If using DuckDNS, get an API token from their dashboard.
Here is a simple example how it's done in https://www.duckdns.org/domainsβ
- Set Up SSL Certificates:
-
Access Nginx Proxy Manager at http://server_ip:81. For example:
192.168.0.6:81
-
Log in with the default credentials (admin@example.com / changeme). Change them as asked.
-
Go to SSL Certificates β Add SSL Certificate β Let's Encrypt.
-
Write your email and domain name you got from DuckDNS. One domain name contains an asterisk and another does not. Example:
*.hello.duckdns.org
andhello.duckdns.org
. -
Select Use a DNS challenge, choose DuckDNS, and paste your API token. example:
dns_duckdns_token=f4e2a1b9-c78d-e593-b0d7-67f2e1c9a5b8
-
Agree to Letβs Encrypt terms and save. Change propagation time if needed (120 seconds).
- Create Proxy Hosts:
-
For each service (e.g., openwebui, nextcloud), go to Hosts β Proxy Hosts β Add Proxy Host.
-
Fill in the domain name (e.g., openwebui.hello.duckdns.org).
-
Set the scheme to HTTP (default), enable
Websockets support
and point to your Docker IP (if docker with open-webui is running on the same computer as NGINX manager, this will be the same IP as earlier (example:192.168.0.6
) -
Select the SSL certificate generated earlier, force SSL, and enable HTTP/2.
- Add your url to open-webui (otherwise getting HTTPS error):
- Go to your open-webui β Admin Panel β Settings β General
- In the Webhook URL text field, enter your URL through which you will connect to your open-webui via Nginx reverse proxy. Example:
hello.duckdns.org
(not essential with this one) oropenwebui.hello.duckdns.org
(essential with this one).
Access the WebUIβ
Access Open WebUI via HTTPS at either hello.duckdns.org
or openwebui.hello.duckdns.org
(in whatever way you set it up).
Firewall Note: Be aware that local firewall software (like Portmaster) might block internal Docker network traffic or required ports. If you experience issues, check your firewall rules to ensure necessary communication for this setup is allowed.
Let's Encryptβ
Let's Encrypt provides free SSL certificates trusted by most browsers, ideal for securing your production environment. π
This guide uses a two-phase approach:
- Phase 1: Temporarily run Nginx to prove you own the domain and get a certificate from Let's Encrypt.
- Phase 2: Reconfigure Nginx to use the new certificate for a secure HTTPS connection.
Prerequisitesβ
- A domain name (e.g.,
my-webui.com
) with a DNSA
record pointing to your server's public IP address. - Docker and Docker Compose installed on your server.
- Basic understanding of running commands in a terminal.
Heads up! Let's Encrypt cannot issue certificates for an IP address. You must use a domain name.
Step 1: Initial Setup for Certificate Validationβ
First, we'll set up the necessary files and a temporary Nginx configuration that allows Let's Encrypt's servers to verify your domain.
-
Make sure you followed the Prerequisites above.
-
Create the Directory Structure
From your project's root directory, run this command to create folders for your Nginx configuration and Let's Encrypt certificates:
mkdir -p nginx/conf.d ssl/certbot/conf ssl/certbot/www
-
Create a Temporary Nginx Configuration
Create the file
nginx/conf.d/open-webui.conf
. This initial config only listens on port 80 and serves the validation files for Certbot.β οΈ Remember to replace
<YOUR_DOMAIN_NAME>
with your actual domain.# nginx/conf.d/open-webui.conf
server {
listen 80;
listen [::]:80;
server_name <YOUR_DOMAIN_NAME>;
# Route for Let's Encrypt validation challenges
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# All other requests will be ignored for now
location / {
return 404;
}
} -
Update Your
docker-compose.yml
Add the
nginx
service to yourdocker-compose.yml
and ensure youropen-webui
service is configured to use the shared Docker network.services:
nginx:
image: nginx:alpine
restart: always
ports:
# Expose HTTP and HTTPS ports to the host machine
- "80:80"
- "443:443"
volumes:
# Mount Nginx configs and SSL certificate data
- ./nginx/conf.d:/etc/nginx/conf.d
- ./ssl/certbot/conf:/etc/letsencrypt
- ./ssl/certbot/www:/var/www/certbot
depends_on:
- open-webui
networks:
- open-webui-network
open-webui:
# Your existing open-webui configuration...
# ...
# Ensure it's on the same network
networks:
- open-webui-network
# Expose the port internally to the Docker network.
# You do NOT need to publish it to the host (e.g., no `ports` section is needed here).
expose:
- 8080
networks:
open-webui-network:
driver: bridge
Step 2: Obtain the SSL Certificateβ
Now we'll run a script that uses Docker to fetch the certificate.
-
Create the Certificate Request Script
Create an executable script named
enable_letsencrypt.sh
in your project root.β οΈ Remember to replace
<YOUR_DOMAIN_NAME>
and<YOUR_EMAIL_ADDRESS>
with your actual information.#!/bin/bash
# enable_letsencrypt.sh
DOMAIN="<YOUR_DOMAIN_NAME>"
EMAIL="<YOUR_EMAIL_ADDRESS>"
echo "### Obtaining SSL certificate for $DOMAIN ###"
# Start Nginx to serve the challenge
docker compose up -d nginx
# Run Certbot in a container to get the certificate
docker run --rm \
-v "./ssl/certbot/conf:/etc/letsencrypt" \
-v "./ssl/certbot/www:/var/www/certbot" \
certbot/certbot certonly \
--webroot \
--webroot-path=/var/www/certbot \
--email "$EMAIL" \
--agree-tos \
--no-eff-email \
--force-renewal \
-d "$DOMAIN"
if [[ $? != 0 ]]; then
echo "Error: Failed to obtain SSL certificate."
docker compose stop nginx
exit 1
fi
# Stop Nginx before we apply the final config
docker compose stop nginx
echo "### Certificate obtained successfully! ###" -
Make the Script Executable
chmod +x enable_letsencrypt.sh
-
Run the Script
Execute the script. It will automatically start Nginx, request the certificate, and then stop Nginx.
./enable_letsencrypt.sh
Step 3: Finalize Nginx Configuration for HTTPSβ
With the certificate saved in your ssl
directory, you can now update the Nginx configuration to enable HTTPS.
-
Update the Nginx Configuration for SSL
Replace the entire contents of
nginx/conf.d/open-webui.conf
with the final configuration below.β οΈ Replace all 4 instances of
<YOUR_DOMAIN_NAME>
with your domain.# nginx/conf.d/open-webui.conf
# Redirect all HTTP traffic to HTTPS
server {
listen 80;
listen [::]:80;
server_name <YOUR_DOMAIN_NAME>;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
# Main HTTPS server block
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name <YOUR_DOMAIN_NAME>;
# SSL certificate paths
ssl_certificate /etc/letsencrypt/live/<YOUR_DOMAIN_NAME>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<YOUR_DOMAIN_NAME>/privkey.pem;
# Security enhancements
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://open-webui:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_read_timeout 10m;
proxy_buffering off;
client_max_body_size 20M;
}
} -
Launch All Services
Start both Nginx and Open WebUI with the final, secure configuration.
docker compose up -d
Step 4: Access Your Secure WebUIβ
You can now access your Open WebUI instance securely via HTTPS.
β‘οΈ https://<YOUR_DOMAIN_NAME>
(Optional) Step 5: Setting Up Automatic Renewalβ
Let's Encrypt certificates expire every 90 days. You should set up a cron
job to renew them automatically.
-
Open the crontab editor:
sudo crontab -e
-
Add the following line to run a renewal check every day at 3:30 AM. It will only renew if the certificate is close to expiring.
30 3 * * * /usr/bin/docker run --rm -v "<absolute_path>/ssl/certbot/conf:/etc/letsencrypt" -v "<absolute_path>/ssl/certbot/www:/var/www/certbot" certbot/certbot renew --quiet --webroot --webroot-path=/var/www/certbot --deploy-hook "/usr/bin/docker compose -f <absolute_path>/docker-compose.yml restart nginx"
Self-Signed Certificateβ
Using self-signed certificates is suitable for development or internal use where trust is not a critical concern.
Self-Signed Certificate Stepsβ
-
Create Directories for Nginx Files:
mkdir -p conf.d ssl
-
Create Nginx Configuration File:
conf.d/open-webui.conf
:server {
listen 443 ssl;
server_name your_domain_or_IP;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://host.docker.internal:3000;
# Add WebSocket support (Necessary for version 0.5.0 and up)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
# (Optional) Disable proxy buffering for better streaming response from models
proxy_buffering off;
# (Optional) Increase max request size for large attachments and long audio messages
client_max_body_size 20M;
proxy_read_timeout 10m;
}
} -
Generate Self-Signed SSL Certificates:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ssl/nginx.key \
-out ssl/nginx.crt \
-subj "/CN=your_domain_or_IP" -
Update Docker Compose Configuration:
Add the Nginx service to your
docker-compose.yml
:services:
nginx:
image: nginx:alpine
ports:
- "443:443"
volumes:
- ./conf.d:/etc/nginx/conf.d
- ./ssl:/etc/nginx/ssl
depends_on:
- open-webui -
Start Nginx Service:
docker compose up -d nginx
Access the WebUIβ
Access Open WebUI via HTTPS at:
Using a Self-Signed Certificate and Nginx on Windows without Dockerβ
For basic internal/development installations, you can use nginx and a self-signed certificate to proxy Open WebUI to https, allowing use of features such as microphone input over LAN. (By default, most browsers will not allow microphone input on insecure non-localhost urls)
This guide assumes you installed Open WebUI using pip and are running open-webui serve
Step 1: Installing openssl for certificate generationβ
You will first need to install openssl
You can download and install precompiled binaries from the Shining Light Productions (SLP) website.
Alternatively, if you have Chocolatey installed, you can use it to install OpenSSL quickly:
-
Open a command prompt or PowerShell.
-
Run the following command to install OpenSSL:
choco install openssl -y
Verify Installationβ
After installation, open a command prompt and type:
openssl version
If it displays the OpenSSL version (e.g., OpenSSL 3.x.x ...
), it is installed correctly.
Step 2: Installing nginxβ
Download the official Nginx for Windows from nginx.org or use a package manager like Chocolatey. Extract the downloaded ZIP file to a directory (e.g., C:\nginx).
Step 3: Generate certificateβ
Run the following command:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout nginx.key -out nginx.crt
Move the generated nginx.key and nginx.crt files to a folder of your choice, or to the C:\nginx directory
Step 4: Configure nginxβ
Open C:\nginx\conf\nginx.conf in a text editor
If you want Open WebUI to be accessible over your local LAN, be sure to note your LAN ip address using ipconfig
e.g., 192.168.1.15
Set it up as follows:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 120;
#gzip on;
# needed to properly handle websockets (streaming)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Redirect all HTTP traffic to HTTPS
server {
listen 80;
server_name 192.168.1.15;
return 301 https://$host$request_uri;
}
# Handle HTTPS traffic
server {
listen 443 ssl;
server_name 192.168.1.15;
# SSL Settings (ensure paths are correct)
ssl_certificate C:\\nginx\\nginx.crt;
ssl_certificate_key C:\\nginx\\nginx.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
# OCSP Stapling
#ssl_stapling on;
#ssl_stapling_verify on;
# Proxy settings to your local service
location / {
# proxy_pass should point to your running localhost version of open-webui
proxy_pass http://localhost:8080;
# Add WebSocket support (Necessary for version 0.5.0 and up)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
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;
# (Optional) Disable proxy buffering for better streaming response from models
proxy_buffering off;
# (Optional) Increase max request size for large attachments and long audio messages
client_max_body_size 20M;
proxy_read_timeout 10m;
}
}
}
Save the file, and check the configuration has no errors or syntax issues by running nginx -t
. You may need to cd C:\nginx
first depending on how you installed it
Run nginx by running nginx
. If an nginx service is already started, you can reload new config by running nginx -s reload
You should now be able to access Open WebUI on https://192.168.1.15 (or your own LAN ip as appropriate). Be sure to allow windows firewall access as needed.
Next Stepsβ
After setting up HTTPS, access Open WebUI securely at:
Ensure that your DNS records are correctly configured if you're using a domain name. For production environments, it's recommended to use Let's Encrypt for trusted SSL certificates.