This article explains how to deploy a browser-accessible OpenWebUI chat interface on a Debian-based system and connect it to large language models through the OpenRouter API, creating a self-hosted ChatGPT-like web interface. We will also configure a domain using Cloudflare DNS, allowing the service to be accessed directly through
<ai.your-domain>.
OpenWebUI is an open-source web chat frontend that supports both local models, such as Ollama, and remote models, such as OpenAI and OpenRouter.
It provides a modern chat interface, user management, multi-model support, and other features, making it an ideal self-hosted AI frontend.
OpenRouter provides a unified API for accessing models from multiple providers, including OpenAI, Anthropic, Mistral, and others.
After registering, you can obtain an API key in the following format:
textsk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Configure this key in OpenWebUI to access the available models.
Cloudflare DNS is used to point your own domain name to the public IP address of your server.
It can also provide reverse proxying, security acceleration, and HTTPS support.
Make sure your system is Debian / Ubuntu and meets the following requirements:
pip and venv are availablebashsudo apt update sudo apt install python3 python3-venv python3-pip git -y
bashmkdir -p /opt/openwebui
cd /opt/openwebui
python3 -m venv venv
source venv/bin/activate
bashpip install open-webui
bashopenwebui serve
By default, OpenWebUI listens on port 8080.
You can access it directly at:
texthttp://<server-IP>:8080
The first account created will automatically become the administrator account.
Log in to the Cloudflare Dashboard:
textName: ai Content: <your server's public IP> Proxy status: optional (DNS only / Proxied)
After saving the record, you can test it with:
bashping ai.<your-domain>
If the domain resolves to the correct IP address, the DNS configuration is working.
Note that the Cloudflare proxy should be disabled.
Register at OpenRouter and copy your API key.
In the OpenWebUI interface, go to:
Admin Settings → Connections → OpenRouter
Paste your API key and save the configuration.
The architecture we want is:
text[ Internet ] ↓ ai.<your-domain> ──(443/80)──▶ [Caddy] ──▶ localhost:8080 (OpenWebUI)
bashsudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy
Edit /etc/caddy/Caddyfile and add:
textai.<your-domain> { reverse_proxy localhost:8080 }
bashsudo systemctl enable --now caddy
sudo systemctl restart caddy
By default, ordinary users may not be able to access all models configured by the administrator.
To solve this, set the following environment variable:
bashBYPASS_MODEL_ACCESS_CONTROL=True
Set it in the virtual environment:
bashsource /openwebui/venv/bin/activate
export BYPASS_MODEL_ACCESS_CONTROL=True
openwebui serve
nohupbashnohup openwebui serve > openwebui.log 2>&1 &
Create the file:
text/etc/systemd/system/openwebui.service
with the following contents:
ini[Unit]
Description=Open WebUI
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
# The current installation is under /root and runs as root
User=root
Group=root
WorkingDirectory=/root/openwebui
# Start the executable directly from the virtual environment
ExecStart=/root/openwebui/venv/bin/open-webui serve
# Automatically restart if the service exits unexpectedly
Restart=on-failure
RestartSec=3
# Logging: choose one of the following approaches
# Option A: write logs to journald
# Recommended. This is also the default behavior.
StandardOutput=journal
StandardError=journal
# Option B: continue writing logs to a file
# Requires systemd 240+ for append:
# StandardOutput=append:/root/openwebui/openwebui.log
# StandardError=append:/root/openwebui/openwebui.log
# Optional: add environment variables here if needed
# Environment="HOST=0.0.0.0"
# Environment="PORT=8080"
[Install]
WantedBy=multi-user.target
Enable and start the service:
bashsudo systemctl daemon-reload
sudo systemctl enable openwebui
sudo systemctl start openwebui
You can then check the service status with:
bashsudo systemctl status openwebui
When a new version is released, activate the virtual environment and run:
bashsource /openwebui/venv/bin/activate
pip install --upgrade open-webui
Then restart the service:
bashsudo systemctl restart openwebui
At this point, you have completed the following configuration:
| Item | Status |
|---|---|
| Cloudflare DNS configuration | ✅ |
| OpenWebUI installation | ✅ |
| OpenRouter API integration | ✅ |
| Model access enabled for all users | ✅ |
| Background service and automatic startup | ✅ |
| Update mechanism | ✅ |
You can now access your self-hosted AI platform at:
texthttps://ai.<your-domain>
You now have a fully self-hosted, modern, and secure AI chat system 🎉