Deploy Open WebUI on Ubuntu 24.04 with Docker and ZeroSSL
Open WebUI gives you a polished self-hosted interface for local and remote AI backends, with chat history, model selection, knowledge-base features, and a modern browser UI that is much easier to expose safely than a raw API endpoint. It is a strong fit when you want your own AI web interface on infrastructure you control.
In this guide, we restore a fresh Ubuntu 24.04.1 LTS server on Shape.Host, verify the latest stable Open WebUI release from the official project, install Docker Engine and Docker Compose from Docker’s official Ubuntu repository, deploy Open WebUI v0.8.10, place Nginx in front of it on tutorials.shape.host, secure the site with a trusted ZeroSSL certificate, and validate the finished installation from both the terminal and a browser.
| Application | Open WebUI |
|---|---|
| Application version | v0.8.10 |
| Operating system | Ubuntu 24.04.1 LTS |
| Container runtime | Docker Engine 29.3.0 with Docker Compose 5.1.0 |
| Reverse proxy | Nginx 1.24.0 |
| Public hostname | tutorials.shape.host |
| TLS issuer | ZeroSSL ECC Domain Secure Site CA |
| Validated on | Live Shape.Host Ubuntu 24.04 server |
Why Use Open WebUI on Ubuntu 24.04?
- Ubuntu 24.04.1 LTS gives you a current long-term support base for containerized AI tooling.
- Open WebUI has an official Docker and Docker Compose path that is easy to reproduce on a clean server.
- Nginx lets you keep the application on localhost while exposing a clean public HTTPS endpoint.
- ZeroSSL gives you a trusted certificate for the web interface on your own hostname.
Before You Begin
Make sure you have the following in place before you start:
- A fresh Ubuntu 24.04 server
- Root or sudo access
- A DNS record pointing
tutorials.shape.hostto your server IP - Ports
80and443open to the public internet - Your ZeroSSL EAB key ID and EAB HMAC key for ACME account registration
1. Verify the Ubuntu 24.04 Release
Start by confirming that the rebuilt server is actually running Ubuntu 24.04.1 LTS.
cat /etc/os-release

2. Install Docker, Docker Compose, Nginx, and Base Dependencies
Open WebUI officially supports Docker and Docker Compose. On Ubuntu 24.04, the clean path is to add Docker’s official Ubuntu repository instead of relying on older distro-packaged Docker builds.
apt update
apt install -y ca-certificates curl git nginx openssl socat
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
cat > /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker nginx
docker --version
docker compose version
nginx -v
git --version
On the validated Ubuntu 24.04.1 deployment, this installed Docker Engine 29.3.0, Docker Compose 5.1.0, Nginx 1.24.0, and Git 2.43.0.

3. Create the Open WebUI Docker Compose Configuration
Open WebUI’s quick-start docs show the rolling main image in their examples, but for a stable production-style deployment it is better to pin the current release tag. For a reverse-proxied setup, set CORS_ALLOW_ORIGIN to your final HTTPS URL.
mkdir -p /opt/open-webui
cd /opt/open-webui
cat > compose.yaml <<'EOF'
services:
openwebui:
image: ghcr.io/open-webui/open-webui:v0.8.10
container_name: open-webui
restart: unless-stopped
ports:
- 127.0.0.1:3000:8080
environment:
- CORS_ALLOW_ORIGIN=https://tutorials.shape.host
volumes:
- open-webui:/app/backend/data
volumes:
open-webui:
EOF
grep '^ image:' compose.yaml
grep '^ environment:' -A 1 compose.yaml
cat compose.yaml
docker compose config --services
The localhost-only port mapping keeps Open WebUI off the public interface so Nginx can proxy it securely, while CORS_ALLOW_ORIGIN matches the final browser origin recommended by the official reverse-proxy guide.

4. Start Open WebUI
With the compose file in place, start the container and confirm that the application answers locally before you expose it through Nginx.
4.1 Launch the Container
cd /opt/open-webui
docker compose up -d
sleep 30
On the live server, Docker pulled the official Open WebUI image, created the local volume for application data, and started the container successfully.

4.2 Validate the Running Container and Local HTTP Response
docker compose ps
docker compose images
curl -I http://127.0.0.1:3000
On the validated deployment, the container came up healthy on image tag v0.8.10 and the local endpoint returned HTTP/1.1 200 OK.

5. Configure Nginx and Issue a ZeroSSL Certificate
Create the initial HTTP site first so ZeroSSL can complete the ACME webroot validation. Then switch the site to a permanent HTTPS redirect and a TLS-enabled proxy block with the WebSocket-friendly headers Open WebUI expects.
mkdir -p /var/www/_letsencrypt /etc/nginx/ssl/tutorials.shape.host
cat > /etc/nginx/sites-available/tutorials.shape.host <<'EOF'
server {
listen 80;
server_name tutorials.shape.host;
location /.well-known/acme-challenge/ {
root /var/www/_letsencrypt;
default_type "text/plain";
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
proxy_read_timeout 86400;
}
}
EOF
ln -sfn /etc/nginx/sites-available/tutorials.shape.host /etc/nginx/sites-enabled/tutorials.shape.host
rm -f /etc/nginx/sites-enabled/default
nginx -t
systemctl reload nginx
curl -fsSL https://get.acme.sh | sh -s email=contact@shape.host
/root/.acme.sh/acme.sh --set-default-ca --server zerossl
/root/.acme.sh/acme.sh --register-account --server zerossl --eab-kid YOUR_ZEROSSL_EAB_KID --eab-hmac-key YOUR_ZEROSSL_EAB_HMAC_KEY
/root/.acme.sh/acme.sh --issue --server zerossl --webroot /var/www/_letsencrypt -d tutorials.shape.host --keylength ec-256
/root/.acme.sh/acme.sh --install-cert -d tutorials.shape.host --ecc \
--fullchain-file /etc/nginx/ssl/tutorials.shape.host/fullchain.cer \
--key-file /etc/nginx/ssl/tutorials.shape.host/tutorials.shape.host.key \
--reloadcmd "systemctl reload nginx"
cat > /etc/nginx/sites-available/tutorials.shape.host <<'EOF'
server {
listen 80;
server_name tutorials.shape.host;
location /.well-known/acme-challenge/ {
root /var/www/_letsencrypt;
default_type "text/plain";
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name tutorials.shape.host;
ssl_certificate /etc/nginx/ssl/tutorials.shape.host/fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/tutorials.shape.host/tutorials.shape.host.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
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 https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
proxy_read_timeout 86400;
}
}
EOF
nginx -t
systemctl reload nginx
# Run this from another machine so you test the real public route:
curl -I --resolve tutorials.shape.host:443:YOUR_SERVER_IP https://tutorials.shape.host
On this validated Ubuntu 24.04.1 deployment, the public HTTPS route returned HTTP/2 200 after the ZeroSSL certificate was installed and the final Nginx proxy block was reloaded.

6. Validate the Public HTTPS Route and Certificate
After the proxy is live, confirm the final container state, public HTTP status, and certificate issuer. In this environment, validating the public route from an external client with --resolve is more reliable than trying to hairpin back into the same public IP from inside the VM.
# On the server
cd /opt/open-webui
docker compose ps
docker compose images
nginx -v
# From another machine on the internet
curl -I --resolve tutorials.shape.host:443:YOUR_SERVER_IP https://tutorials.shape.host
openssl s_client -connect YOUR_SERVER_IP:443 -servername tutorials.shape.host < /dev/null 2>/dev/null | openssl x509 -noout -issuer -subject
In the validated Shape.Host deployment, the public HTTPS route returned HTTP/2 200 and the certificate issuer reported ZeroSSL ECC Domain Secure Site CA.

7. Open the Public Open WebUI Page
Once HTTPS is working, load the public site and confirm that Open WebUI’s welcome screen appears correctly in the browser.

Troubleshooting Tips
- If Docker packages do not appear after
apt update, verify that the Docker repository entry uses the correct Ubuntu 24.04 codename,noble. - If Open WebUI loads locally but the public browser session behaves oddly behind the proxy, confirm that
CORS_ALLOW_ORIGIN=https://tutorials.shape.hostis present in the compose file and that the Nginx proxy block includes the WebSocket headers. - If the site is healthy from outside the server but a curl test from inside the VM fails against the public IP, use
curl --resolvefrom another machine instead of relying on hairpin routing.
Conclusion
You now have a working Open WebUI deployment on Ubuntu 24.04 with Docker Compose, Nginx reverse proxying, and a trusted ZeroSSL certificate on tutorials.shape.host. On this verified Shape.Host deployment, the final validated stack was Open WebUI v0.8.10, Docker Engine 29.3.0, Docker Compose 5.1.0, and Nginx 1.24.0.