OneLinersCommand workbench
Guides
AI/ML / System Administration / Security / DevOps & CI/CD

Deploy Ollama and Open WebUI securely

Run authenticated local AI behind TLS with private Ollama networking, persistent storage, controlled models, staged updates and tested backup/restore.

240 min15 stepsChanges system stateRevision 2
Save or explore
Save to collectionCreate a collection in the sidebar first.
0 of 15 steps completed
Goal

Provide a reproducible local AI service whose network, identity, model, storage, update and recovery boundaries are verified.

Supported environments
  • Ubuntu Server 24.04 LTS
  • Docker Engine current supported
  • Ollama reviewed pinned release
  • Open WebUI reviewed pinned release
Prerequisites
  • Host and recovery Supported Ubuntu host, sudo, console recovery, synchronized clock and sufficient disk/RAM/VRAM.Run baseline step.
  • DNS and TLS plan Reviewed hostname and public or internal certificate path exist.Resolve {{hostName}}.
  • Protected backup storage Separate encrypted/restricted destination meets RPO/RTO.Verify {{backupRoot}} capacity.
  • Model review License, size, digest, task quality and human-control boundary are approved.Review {{modelName}} manifest.
Operating boundary

OneLiners never runs these steps or stores secrets. Review placeholders, versions, current state, and change-control requirements before using a command.

Full guide

What you will build

System
  • A single-host local inference service with Ollama and Open WebUI on Ubuntu Server. Ollama is reachable only on a private container network, model artifacts live on a dedicated persistent volume, Open WebUI keeps its database and uploads on a separate persistent volume, and the public entry point is an HTTPS reverse proxy.
  • A controlled model lifecycle. Operators select a model that fits measured RAM or VRAM, pull it by reviewed tag, record its digest and license metadata, run a deterministic smoke, observe loaded models, stop or remove retired artifacts and preserve the exact approved manifest for rollback.
  • A production operations path with first-admin bootstrap, authentication enabled, a persistent WEBUI_SECRET_KEY, TLS and WebSocket proxying, restrictive firewall, backup verification, staged image and database updates, health and capacity monitoring, and a documented restore that never overwrites the only good backup.
Observable outcome
  • Port 11434 is not reachable from untrusted networks. Open WebUI is accessible only through the intended HTTPS hostname, WebSocket upgrades work, HTTP redirects to HTTPS and authentication protects every private conversation and administrative surface.
  • Container images, configuration and model selections are versioned. Rolling tags are not promoted without resolving and recording a reviewed digest, and development volumes never share production data.
  • Backups include Open WebUI's persistent data, Ollama model inventory and reviewed configuration. A restore drill proves chats/settings and the approved model respond before the backup is considered usable.
  • Updates follow backup, staging migration, smoke, canary access and rollback. Operators can identify image digests, Open WebUI health, Ollama version, model storage, memory pressure, queueing and recent errors without exposing prompts or secrets.

Architecture

How the parts fit together

Docker Compose runs Ollama and Open WebUI on an internal network. Ollama has no host-published port; Open WebUI reaches it at http://ollama:11434 and binds its own port only to loopback for the reverse proxy. Caddy or an equivalent reviewed proxy terminates TLS, redirects HTTP, forwards WebSocket upgrades and applies network controls. Persistent named volumes separate Ollama models from Open WebUI application data. A root-owned environment file supplies one stable WEBUI_SECRET_KEY and public URL settings. Backups are written to a separate filesystem and verified before updates. The release manifest pins Compose configuration, container image digests, model names/digests and proxy configuration.

Ollama serviceLoads reviewed local models, exposes its API only on the private application network and stores model blobs persistently.
Open WebUI serviceProvides authenticated chat and administration, connects to Ollama internally and persists database, uploads and settings.
TLS reverse proxyExposes one HTTPS hostname, handles certificates, WebSocket forwarding, redirects and optional access restrictions.
Persistent storageSeparates application data, model artifacts, configuration and backups with documented ownership and capacity.
Release manifestPins image digests, model identifiers, configuration revision, backup reference and rollback target.
Operations and monitoringChecks health, capacity, logs, authentication, model behavior, backup integrity and update status without raw prompt logging.
  1. Define users, privacy boundary, hardware capacity, hostname, recovery objective and whether the host is allowed any public exposure.
  2. Install a supported container runtime, create storage and secret files, and validate available disk, RAM/VRAM and DNS before pulling large artifacts.
  3. Deploy pinned Ollama and Open WebUI images on a private network with persistent volumes and no public Ollama port.
  4. Pull one reviewed model, record its digest and metadata, run local API inference and observe memory and queue behavior.
  5. Create the first Open WebUI administrator through the protected local or HTTPS path, keep authentication enabled and verify the stable secret key.
  6. Place the application behind TLS, test redirects, certificate, WebSocket transport and blocked direct ports from an external host.
  7. Back up and verify persistent data and release metadata; stage every image/model update against a copy before production migration.
  8. Monitor service health, storage, model residency, latency and errors; restore the previous images/data/model manifest when acceptance checks fail.

Assumptions

  • The host runs supported Ubuntu Server and Docker Engine/Compose or an equivalent reviewed container runtime. The operator has sudo and independent console access.
  • A DNS name points to the intended reverse proxy and TCP 80/443 reachability is available if public certificate issuance is used. Private-only deployments use an approved internal PKI or access network.
  • The selected model's license and use are acceptable and the host has sufficient storage and RAM/VRAM. A local model does not automatically make every workload private if plugins, web search or external providers remain enabled.
  • Open WebUI authentication remains enabled for multi-user use. The first-account bootstrap happens through a protected path and the stable WEBUI_SECRET_KEY is backed up separately from public configuration.
  • Backups are stored outside the live volume and protected according to the sensitivity of conversations, uploaded files and configuration. Restore tests may use an isolated host.
  • The organization can tolerate a maintenance window or has an upstream availability design; this guide covers a durable single-host deployment, not multi-replica HA.

Key concepts

Model manifest
Reviewed list of model name/tag, digest, size, license note, purpose, smoke result and lifecycle state used by the deployment.
Private inference network
Container or host network where Ollama is reachable by Open WebUI but not published to untrusted clients.
WEBUI_SECRET_KEY
Persistent secret used by Open WebUI for session signing and related cryptographic behavior; changing it invalidates sessions and replicas must share it.
Persistent data volume
Storage mounted at /app/backend/data so database, chats, settings and uploads survive container replacement.
Rolling tag
An image tag such as main whose digest can move. Production releases record an immutable reviewed digest for reproduction and rollback.
Restore drill
Isolated recovery that proves backup extraction, application startup, authentication, model availability and sample inference.

Before you copy

Values used in this guide

{{hostName}}

HTTPS DNS name used by operators.

Example: ai.example.net
{{openWebuiImage}}

Reviewed Open WebUI image pinned to an immutable digest.

Example: ghcr.io/open-webui/open-webui:main@sha256:REVIEWED_DIGEST
{{ollamaImage}}

Reviewed Ollama image pinned to an immutable digest.

Example: ollama/ollama:latest@sha256:REVIEWED_DIGEST
{{modelName}}

Reviewed Ollama model tag from the approved manifest.

Example: gemma3:4b
{{backupRoot}}

Separate protected filesystem for backups.

Example: /srv/backups/local-ai
{{releaseId}}

Complete deployment release identifier.

Example: local-ai/2026-07-28.1

Security and production boundaries

  • Do not publish Ollama's API directly to the Internet. It has access to model operations and may expose inference without the user controls provided by the application boundary.
  • Keep Open WebUI authentication enabled for shared or network-accessible deployments. The no-login single-user option is only appropriate for a genuinely isolated single-user environment and cannot be casually toggled after initialization.
  • Use a stable high-entropy WEBUI_SECRET_KEY stored with restrictive permissions. Never commit it to Compose, screenshots or support logs; changing it invalidates sessions.
  • Terminate TLS at a maintained reverse proxy and permit only the intended hostname and networks. Test WebSocket forwarding and direct-port blocking from outside the host.
  • Treat uploaded documents, chats, generated content and backups as sensitive. Encrypt backup transport/storage as required, restrict access and verify deletion/retention policy.
  • Local models can still generate harmful or incorrect output. Keep human review and application authorization for consequential decisions and never connect model text directly to privileged execution.

Stop before continuing if

  • Stop if console recovery, tested backup destination, sufficient disk/memory or a reviewed model license is unavailable.
  • Stop if Ollama port 11434 or Open WebUI's direct application port is reachable from an untrusted external host.
  • Stop if authentication is disabled on a shared/network service, the first administrator can be claimed through an unprotected route or WEBUI_SECRET_KEY is not persistent.
  • Stop an update when backup verification, staging migration, pinned rollback image/model or external HTTPS/WebSocket smoke fails.
  • Stop restore if the target volume or backup archive is ambiguous; never erase the live volume before preserving and verifying the current state.
01

instruction

Define users, exposure, data and recovery boundaries

read-only

Document who may use the service, whether it is private or Internet-reachable, what data is allowed, which optional integrations remain disabled, hardware capacity, DNS/TLS path, backup objective and human review for consequential output.

Why this step matters

A local stack still has network, identity, storage and model risks. Defining the boundary prevents a convenient demo from becoming an unauthenticated data repository.

What to understand

Classify chats, uploads and backups.

Decide public, VPN or loopback access.

Measure RAM/VRAM and disk before model selection.

Name RPO/RTO and console recovery owner.

System changes

  • Creates an architecture and data policy.
  • Changes no host.

Syntax explained

VPN+HTTPS
Private access network plus encrypted application transport.
RPO
Maximum acceptable data-loss interval.
RTO
Target recovery duration.
Example output / evidence
deployment=single-host
users=operations-team
access=VPN+HTTPS
ollama_public=false
openwebui_auth=true
allowed_data=internal-low-sensitivity
RPO=24h RTO=4h
console_recovery=verified
consequential_actions=human_only

Checkpoint: Approve operating boundary

Continue whenOwner can state access, data, capacity, recovery and human-control rules.

Stop whenStop if exposure, backup or data policy is undefined.

If this step fails

The team assumes local means no egress.

Likely causeIntegrations were not inventoried.

Safe checks
  • Review providers/plugins.
  • Observe outbound connections.

ResolutionDisable unapproved integrations and document the actual flow.

Security notes

  • No model output receives operational authority.
  • Restrict data to the approved classification.

Alternatives

  • Use workstation loopback only.
  • Use a hosted service under approved controls.

Stop conditions

  • Stop if exposure, backup or data policy is undefined.
02

command

Verify host, Docker, storage and clock

read-only

Record OS, container runtime, Compose, CPU, memory, disk and time before downloading images or models. Keep independent console access and enough free space for the model plus update and backup copies.

Why this step matters

Model pulls and updates are storage-heavy and TLS/auth depend on a sane clock. A baseline makes later capacity and rollback decisions evidence-based.

What to understand

Confirm supported Docker installation.

Reserve space for old/new image and backup.

Record GPU separately when used.

Verify console recovery before firewall changes.

System changes

  • Reads host state only.
  • Creates no container or download.

Syntax explained

free -h
Readable memory capacity.
df -h
Filesystem capacity.
NTPSynchronized
Clock synchronization state.
Command
uname -a && docker version --format '{{.Server.Version}}' && docker compose version && free -h && df -h /var/lib/docker && timedatectl show -p NTPSynchronized
Example output / evidence
Linux ai01 6.8.0-65-generic #68-Ubuntu SMP x86_64 GNU/Linux
27.5.1
Docker Compose version v2.38.2
Mem: 62Gi total, 55Gi available
/dev/mapper/vg-docker  900G  112G  743G  14% /var/lib/docker
NTPSynchronized=yes

Checkpoint: Approve host capacity

docker info --format '{{json .SecurityOptions}}'

Continue whenRuntime is healthy, storage/memory meet plan and clock/console recovery are available.

Stop whenStop on low disk, unsupported runtime, unsynchronized clock or missing recovery access.

If this step fails

Docker commands fail.

Likely causeDaemon or permissions are unhealthy.

Safe checks
  • systemctl status docker.
  • Inspect group/access policy.

ResolutionRepair the official Docker installation before continuing.

Security notes

  • Avoid broad Docker group membership.
  • Do not run remote daemon unauthenticated.

Alternatives

  • Use Podman only with a separately tested guide.
  • Deploy on a larger approved host.

Stop conditions

  • Stop on low disk, unsupported runtime, unsynchronized clock or missing recovery access.
03

command

Create protected configuration, secrets and backup paths

caution

Create a root-owned deployment directory and separate backup filesystem. Generate a stable Open WebUI secret into a mode-0600 environment file and record only its digest in the release manifest.

Why this step matters

A persistent secret keeps sessions stable and protected configuration prevents accidental repository exposure. A separate backup path reduces the chance that container cleanup removes recovery data.

What to understand

Store the secret outside Compose.

Back it up through the secret-management process.

Do not echo its value.

Ensure backup destination has sufficient capacity and protection.

System changes

  • Creates directories and one secret file.
  • Does not start services.

Syntax explained

umask 077
Creates owner-only secret permissions.
openssl rand -hex 32
Generates high-entropy secret text.
install -d -m 0750
Creates restricted directories.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

sudo install -d -m 0750 -o root -g root /opt/local-ai {{backupRoot}} && sudo sh -c 'umask 077; printf "WEBUI_SECRET_KEY=%s\n" "$(openssl rand -hex 32)" > /opt/local-ai/secrets.env' && sudo stat -c '%a %U:%G %n' /opt/local-ai/secrets.env
Example output / evidence
600 root:root /opt/local-ai/secrets.env

Checkpoint: Verify secret handling

sudo test -s /opt/local-ai/secrets.env && sudo test "$(stat -c %a /opt/local-ai/secrets.env)" = 600

Continue whenSecret exists, is non-empty and mode 0600 without appearing in command output or repository.

Stop whenStop if the secret was printed, committed or made group/world-readable.

If this step fails

Sessions reset after update.

Likely causeSecret file was not loaded or persisted.

Safe checks
  • Compare secret digest.
  • Inspect Compose env_file.

ResolutionRestore the protected stable secret and require reauthentication after any real rotation.

Security notes

  • Never include secret values in backups without encryption/access policy.
  • Rotate immediately if exposed.

Alternatives

  • Use a managed Docker secret mechanism.
  • Use rootless secret injection supported by your runtime.

Stop conditions

  • Stop if the secret was printed, committed or made group/world-readable.
04

config

Define pinned private-network services

caution

Create Compose services with persistent volumes, an internal Ollama endpoint and loopback-only Open WebUI publication. Use reviewed immutable image digests from the release manifest rather than trusting rolling tags.

Why this step matters

Private networking prevents accidental Ollama exposure, loopback binding reserves public access for TLS proxying and named volumes survive container replacement. Immutable image references make update and rollback reproducible.

What to understand

Resolve and review real digests before deployment.

Persist both model and application paths.

Keep auth true.

Do not mount Docker socket or host root.

System changes

  • Adds deployment configuration.
  • Does not start containers until explicitly applied.

Syntax explained

127.0.0.1:3000:8080
Direct UI listens only on host loopback.
OLLAMA_BASE_URL
Internal service URL.
restart: unless-stopped
Restarts services except when deliberately stopped.
File /opt/local-ai/compose.yaml
Configuration
Fill variables0/2 ready

Values stay on this page and are never sent or saved.

services:
  ollama:
    image: "{{ollamaImage}}"
    restart: unless-stopped
    volumes:
      - ollama-models:/root/.ollama
    networks: [local-ai]

  open-webui:
    image: "{{openWebuiImage}}"
    restart: unless-stopped
    depends_on: [ollama]
    env_file: [secrets.env]
    environment:
      OLLAMA_BASE_URL: http://ollama:11434
      WEBUI_AUTH: "True"
    ports:
      - "127.0.0.1:3000:8080"
    volumes:
      - open-webui-data:/app/backend/data
    networks: [local-ai]

networks:
  local-ai:
    driver: bridge

volumes:
  ollama-models:
  open-webui-data:
Example output / evidence
services=ollama,open-webui
ollama_host_ports=none
openwebui_bind=127.0.0.1:3000
openwebui_data=/app/backend/data
auth=true
images=immutable-digest
compose_validation=PASS

Checkpoint: Validate Compose and image pins

cd /opt/local-ai && sudo docker compose config --quiet

Continue whenConfiguration resolves, images contain reviewed digests and no Ollama host port exists.

Stop whenStop if images are mutable for production, data volumes absent or ports bind all interfaces.

If this step fails

Ollama appears on host port 11434.

Likely causeCompose publishes the port.

Safe checks
  • Inspect docker ps.
  • Inspect compose config.

ResolutionRemove the ports mapping and recreate after review.

Security notes

  • No Docker socket mount.
  • No privileged container unless separately justified.

Alternatives

  • Bind both services to loopback for host-installed proxy.
  • Use an isolated VM boundary.

Stop conditions

  • Stop if images are mutable for production, data volumes absent or ports bind all interfaces.
05

command

Start services and verify the private Ollama API

caution

Pull pinned images, start the stack and test Ollama from inside its network and Open WebUI from loopback. Confirm that port 11434 has no host listener.

Why this step matters

Starting services is the first state change. Immediate listener and health checks catch unsafe exposure before DNS or proxy publication.

What to understand

Review pulled digests against manifest.

Inspect container status and recent logs.

Test internal Ollama with docker compose exec.

Test external port blocking from another host later.

System changes

  • Downloads images and starts persistent services.
  • Creates container networks and volumes.

Syntax explained

compose pull
Fetches exact pinned images.
compose up -d
Reconciles services in background.
! ss ...11434
Asserts no host listener.
Command
cd /opt/local-ai && sudo docker compose pull && sudo docker compose up -d && sudo docker compose ps && curl -fsS http://127.0.0.1:3000/health && ! ss -lnt | grep -q ':11434 '
Example output / evidence
NAME                    IMAGE                  SERVICE      STATUS
local-ai-ollama-1       sha256:...             ollama       Up (healthy)
local-ai-open-webui-1   sha256:...             open-webui   Up (healthy)
{"status":true}
ollama_host_listener=absent

Checkpoint: Verify service and exposure state

cd /opt/local-ai && sudo docker compose exec open-webui curl -fsS http://ollama:11434/api/version

Continue whenOpen WebUI container reaches Ollama internally and host exposes no 11434 listener.

Stop whenStop if health fails, digest differs or Ollama is externally reachable.

If this step fails

Open WebUI cannot resolve ollama.

Likely causeServices are not on the same network.

Safe checks
  • Inspect compose networks.
  • Resolve ollama inside container.

ResolutionAttach both services to the private network and recreate.

Security notes

  • Review logs for accidental secrets.
  • Do not temporarily publish 11434 to troubleshoot.

Alternatives

  • Use container healthchecks and a local diagnostic container.
  • Run Ollama on host loopback with explicit firewall.

Stop conditions

  • Stop if health fails, digest differs or Ollama is externally reachable.
06

command

Pull, inspect and smoke one approved model

caution

Pull the reviewed model, list and inspect it, record its digest/size in the manifest and run a deterministic smoke. Measure memory and remove only explicitly retired models after rollback review.

Why this step matters

Model tags, artifacts and memory requirements are part of the release. A concrete smoke proves the artifact can load and respond before users depend on it.

What to understand

Review license and intended use.

Record returned ID/digest and size.

Observe pull storage and load memory.

Use ollama ps/stop for residency and ollama rm only under approved lifecycle.

System changes

  • Downloads a large model artifact and loads it for inference.
  • Consumes disk and RAM/VRAM.

Syntax explained

ollama pull
Downloads/updates the named model.
ollama show
Displays model metadata.
ollama run
Loads model and performs inference.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

cd /opt/local-ai && sudo docker compose exec ollama ollama pull {{modelName}} && sudo docker compose exec ollama ollama list && sudo docker compose exec ollama ollama show {{modelName}} && sudo docker compose exec ollama ollama run {{modelName}} 'Reply with exactly: MODEL_OK'
Example output / evidence
pulling manifest
pulling 5c3... 100% ▕████████████████▏ 3.3 GB
verifying sha256 digest
writing manifest
success
NAME        ID            SIZE      MODIFIED
gemma3:4b  a2af6cc3eb7f  3.3 GB    Less than a minute ago
MODEL_OK

Checkpoint: Record model manifest and capacity

cd /opt/local-ai && sudo docker compose exec ollama ollama ps

Continue whenApproved model ID/size are recorded and load fits capacity without swapping or errors.

Stop whenStop if license, digest, disk or memory behavior is unacceptable.

If this step fails

Model process queues or swaps heavily.

Likely causeModel exceeds practical capacity.

Safe checks
  • Run ollama ps.
  • Inspect memory/GPU.

ResolutionStop it and select a smaller reviewed model after quality evaluation.

Security notes

  • Do not pull unreviewed model artifacts in production.
  • Model output remains untrusted.

Alternatives

  • Use a smaller quantized model.
  • Use a hosted approved model for workloads exceeding capacity.

Stop conditions

  • Stop if license, digest, disk or memory behavior is unacceptable.
07

instruction

Bootstrap the first administrator through a protected path

caution

Before public exposure, access loopback through console or SSH tunnel, create the intended first administrator, verify authentication and administrative ownership, then close the bootstrap path. Never run shared service with WEBUI_AUTH disabled.

Why this step matters

Initial account creation can establish administrative control. Performing it before exposure prevents an outsider from claiming the first account.

What to understand

Use SSH tunnel to loopback.

Create a unique strong administrator account.

Test logout/login and non-admin user role.

Record admin recovery procedure without storing password in the guide.

System changes

  • Creates initial Open WebUI user/admin state.
  • Writes authentication data to persistent volume.

Syntax explained

ssh-tunnel
Protected access to loopback before proxy publication.
WEBUI_AUTH=True
Multi-user authentication remains enabled.
anonymous_access=DENIED
Acceptance check.
Example output / evidence
bootstrap_path=ssh-tunnel
first_admin=created
admin_identity=verified
WEBUI_AUTH=True
anonymous_access=DENIED
session_persistence=PASS
bootstrap_window=closed

Checkpoint: Verify authentication and ownership

Continue whenOnly intended admin exists, anonymous access fails and sessions survive container restart.

Stop whenStop if first account ownership is uncertain or anonymous access works.

If this step fails

Unexpected admin exists.

Likely causeBootstrap was exposed or reused data is compromised.

Safe checks
  • Block access.
  • Inspect users and logs.

ResolutionTreat as incident and restore/reinitialize from known clean state.

Security notes

  • Use a password manager and MFA/SSO where supported and approved.
  • Keep break-glass recovery protected.

Alternatives

  • Integrate approved SSO after local admin bootstrap.
  • Keep service workstation-local.

Stop conditions

  • Stop if first account ownership is uncertain or anonymous access works.
08

config

Terminate TLS and forward WebSockets

caution

Configure the reviewed reverse proxy for the public hostname, HTTPS, HTTP redirect and WebSocket-compatible proxying to loopback Open WebUI. Keep Caddy state persistent if using automatic certificates.

Why this step matters

TLS protects credentials and conversations in transit, while the reverse proxy is the only intended public boundary. Open WebUI requires WebSocket support for interactive behavior.

What to understand

Validate config before reload.

Persist certificate state and monitor renewal.

Set headers according to application compatibility.

Test from outside the host, not only localhost.

System changes

  • Publishes HTTPS service and certificate handling.
  • Does not expose Ollama.

Syntax explained

reverse_proxy
Forwards HTTP and WebSocket traffic to loopback.
HSTS
Instructs browsers to prefer HTTPS after careful domain review.
encode
Enables supported response compression.
File /etc/caddy/Caddyfile
Configuration
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

{{hostName}} {
  encode zstd gzip
  reverse_proxy 127.0.0.1:3000
  header {
    Strict-Transport-Security "max-age=31536000; includeSubDomains"
    X-Content-Type-Options "nosniff"
    Referrer-Policy "same-origin"
  }
}
Example output / evidence
hostname={{hostName}}
http_status=308
https_status=200
certificate_subject={{hostName}}
certificate_expiry_days=89
websocket_upgrade=101
direct_3000_external=BLOCKED

Checkpoint: Run external TLS and WebSocket smoke

curl -I https://{{hostName}} && openssl s_client -connect {{hostName}}:443 -servername {{hostName}} </dev/null

Continue whenValid hostname certificate, HTTPS response, redirect and WebSocket chat; direct ports remain blocked.

Stop whenStop if certificate, WebSocket or direct-port checks fail.

If this step fails

Chat disconnects while page loads.

Likely causeWebSocket forwarding is broken.

Safe checks
  • Inspect browser 101 upgrade.
  • Inspect proxy logs.

ResolutionApply official proxy guidance and retest streamed chat.

Security notes

  • Restrict proxy administration.
  • Do not publish origin ports externally.

Alternatives

  • Use Nginx with official Open WebUI proxy guidance.
  • Use VPN-only access with internal certificates.

Stop conditions

  • Stop if certificate, WebSocket or direct-port checks fail.
09

verification

Verify listeners, firewall and application access

caution

Allow only SSH from administrative networks and HTTP/HTTPS as required for certificate and users. Confirm Ollama and the direct Open WebUI port are unreachable externally, while HTTPS authentication works.

Why this step matters

Compose intent is not proof of exposure. Listener, firewall and external tests verify the actual attack surface.

What to understand

Preserve console before firewall.

Test from a distinct host/network.

Restrict SSH.

Review IPv4 and IPv6.

System changes

  • May update host firewall under approved policy.
  • No application data change.

Syntax explained

22/tcp
Administrative SSH restricted to approved network.
443/tcp
Primary HTTPS service.
11434
Ollama port that must remain private.
Command
sudo ss -lntp && sudo ufw status verbose
Example output / evidence
22/tcp   ALLOW IN  10.20.0.0/16
80/tcp   ALLOW IN  Anywhere
443/tcp  ALLOW IN  Anywhere
3000/tcp DENY/NO LISTENER external
11434/tcp DENY/NO LISTENER external
https_auth=PASS

Checkpoint: Perform external port scan

nmap -Pn -p 22,80,443,3000,11434 {{hostName}}

Continue whenOnly approved ports are open and authentication protects HTTPS.

Stop whenStop if lockout risk exists or direct model/application ports are open.

If this step fails

11434 is reachable externally.

Likely causeHost bind or port publication widened.

Safe checks
  • Inspect ss.
  • Inspect docker port.

ResolutionRemove publication, restore private network and review logs.

Security notes

  • Check IPv6 separately.
  • Avoid management access from all networks.

Alternatives

  • Restrict HTTPS to VPN ranges.
  • Place host behind an access proxy/firewall appliance.

Stop conditions

  • Stop if lockout risk exists or direct model/application ports are open.
10

command

Back up volumes and release metadata

caution

Quiesce Open WebUI for a consistent single-host archive, back up its named volume to the separate destination, export Compose/proxy/model manifest and checksum the archive. Decide separately whether to back up large model blobs or redownload them by recorded digest.

Why this step matters

The data volume contains database, chats, settings and uploads. A quiesced archive and checksum create a recoverable point before updates.

What to understand

Store configuration and manifest beside backup.

Protect archive as sensitive.

Use explicit volume name verified from Compose.

Restart and health-check promptly.

System changes

  • Briefly stops Open WebUI and writes a backup archive.
  • Ollama may remain available internally.

Syntax explained

:ro
Mounts live data read-only in backup helper.
tar czf
Creates compressed archive.
sha256sum
Integrity check, not authenticity or encryption.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

cd /opt/local-ai && sudo docker compose stop open-webui && sudo docker run --rm -v local-ai_open-webui-data:/data:ro -v {{backupRoot}}:/backup alpine tar czf /backup/openwebui-$(date +%Y%m%d-%H%M%S).tar.gz /data && sudo docker compose start open-webui && sudo sha256sum {{backupRoot}}/openwebui-*.tar.gz
Example output / evidence
Container local-ai-open-webui-1 Stopped
backup=/srv/backups/local-ai/openwebui-20260728-153000.tar.gz
size=184M
Container local-ai-open-webui-1 Started
sha256=7d9a...  openwebui-20260728-153000.tar.gz
service_health=PASS

Checkpoint: List and verify backup

sudo tar tzf {{backupRoot}}/openwebui-20260728-153000.tar.gz | head && sudo test -s {{backupRoot}}/openwebui-20260728-153000.tar.gz

Continue whenArchive contains /data paths, checksum recorded and application health restored.

Stop whenStop if volume name, destination, permissions or service recovery is uncertain.

If this step fails

Archive is tiny or lacks database.

Likely causeWrong volume was mounted.

Safe checks
  • List archive.
  • Inspect docker volume mounts.

ResolutionIdentify actual /app/backend/data volume and repeat before updates.

Security notes

  • Encrypt and restrict backup storage.
  • Never upload archives to unapproved services.

Alternatives

  • Use storage snapshots after application quiescence.
  • Use database-specific backup for scaled external databases.

Stop conditions

  • Stop if volume name, destination, permissions or service recovery is uncertain.
11

verification

Restore into an isolated drill volume

caution

Create a new isolated volume and Compose project, extract the selected archive without touching production, start the pinned rollback image on loopback-only alternate ports and verify users/settings, a sample chat and model connection.

Why this step matters

An archive is not a backup until restoration proves application behavior. Isolated recovery prevents a drill from destroying live data.

What to understand

Use a different project name, network and loopback port.

Load the matched image/secret/config.

Verify actual records and inference.

Delete drill data according to policy afterward.

System changes

  • Creates an isolated restore-test volume and temporary service.
  • Does not overwrite production.

Syntax explained

volume create
Creates empty isolated target.
:ro
Prevents test from modifying backup archive.
-C /
Restores archive paths as created.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

sudo docker volume create open-webui-restore-test && sudo docker run --rm -v open-webui-restore-test:/data -v {{backupRoot}}:/backup:ro alpine sh -c 'tar xzf /backup/openwebui-20260728-153000.tar.gz -C /' && echo restore_volume_ready
Example output / evidence
open-webui-restore-test
restore_volume_ready
files=1248
database_present=true
isolated_start=PASS
admin_login=PASS
ollama_connection=PASS
sample_chat=PASS

Checkpoint: Approve recovery evidence

Continue whenMatched image starts, login/settings/data/model smoke pass and elapsed recovery meets RTO.

Stop whenStop if any command targets production volume or archive identity is ambiguous.

If this step fails

Old image cannot read restored data.

Likely causeBackup was taken after incompatible migration.

Safe checks
  • Inspect update timestamps.
  • Select matched backup/image.

ResolutionRestore the pre-update pair and improve manifest linkage.

Security notes

  • Keep drill isolated and access-restricted.
  • Remove test copies after evidence retention.

Alternatives

  • Restore on a disposable VM.
  • Use storage snapshot clone.

Stop conditions

  • Stop if any command targets production volume or archive identity is ambiguous.
12

decision

Stage image and model updates before production

caution

Resolve new immutable image digests, review release notes, back up production and run the candidate against a restored data copy and model smoke. Never share production volume with dev or candidate containers.

Why this step matters

Open WebUI rolling images and migrations can change. Staging on a copied volume discovers incompatibility while preserving production and makes image/data rollback explicit.

What to understand

Read official update guidance.

Resolve digest after review.

Never share dev volume.

Test auth, proxy, WebSocket, data and model.

System changes

  • Downloads candidate images and migrates only staging copy.
  • Does not alter production when followed correctly.

Syntax explained

candidate_images=immutable
Reproducible reviewed artifacts.
staging_volume=isolated
No candidate migration touches production.
rollback_pair
Prior image plus pre-update data.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

node local-ai/release-check.mjs --from {{releaseId}} --candidate local-ai/2026-08-10.1
Example output / evidence
backup_verified=true
candidate_images=immutable
staging_volume=isolated
database_migration=PASS
admin_login=PASS
websocket=PASS
model_smoke=PASS
security_checks=PASS
rollback_pair=available
promotion=APPROVED

Checkpoint: Sign update evidence

node local-ai/release-check.mjs --report local-ai/2026-08-10.1

Continue whenAll functional/security smokes pass and matched rollback data/image exist.

Stop whenStop if staging shares production data or rollback pair is missing.

If this step fails

Candidate migrates production unexpectedly.

Likely causeWrong volume/project name used.

Safe checks
  • Stop candidate.
  • Inspect mounts.

ResolutionPreserve state, restore pre-update backup and strengthen project isolation checks.

Security notes

  • Review image provenance and digest.
  • Do not automate blind rolling-tag updates.

Alternatives

  • Schedule manual update window.
  • Remain on current supported version until staging passes.

Stop conditions

  • Stop if staging shares production data or rollback pair is missing.
13

command

Promote a pinned update with a maintenance checkpoint

danger

Announce maintenance, create a fresh verified backup, update manifest to candidate digests, recreate services and run health, login, TLS, WebSocket, data and model checks before reopening access.

Why this step matters

Promotion changes application and potentially database state. A checkpointed maintenance flow prevents half-updated service and keeps rollback decision timely.

What to understand

Use exact reviewed manifest.

Watch migration logs.

Run external tests before reopening.

Keep pre-update backup immutable.

System changes

  • Replaces production containers and may migrate Open WebUI data.
  • Keeps persistent volumes.

Syntax explained

pull
Fetches pinned candidate images.
up -d
Recreates services to manifest.
--remove-orphans
Removes obsolete services after review.
Command
cd /opt/local-ai && sudo docker compose pull && sudo docker compose up -d --remove-orphans && sudo docker compose ps
Example output / evidence
release=local-ai/2026-08-10.1
images=pinned
services=healthy
database_migration=completed
admin_login=PASS
https=PASS
websocket=PASS
sample_chat=PASS
ollama_external=BLOCKED

Checkpoint: Run production acceptance

node local-ai/acceptance.mjs --release local-ai/2026-08-10.1 --host {{hostName}}

Continue whenAuth/data/model/TLS/WebSocket/security checks pass with intended digests.

Stop whenStop and roll back on migration, login, data, model, TLS or exposure failure.

If this step fails

Services healthy but users cannot login.

Likely causeSecret or database migration mismatch.

Safe checks
  • Compare secret digest.
  • Inspect app logs.

ResolutionRestore matched prior image, secret and pre-update data.

Security notes

  • Do not bypass auth to complete update.
  • Review new environment defaults.

Alternatives

  • Blue/green host cutover.
  • Restore current release when maintenance window closes.

Stop conditions

  • Stop and roll back on migration, login, data, model, TLS or exposure failure.
14

verification

Monitor health, capacity, storage and model lifecycle

read-only

Collect service health, restart count, storage, Ollama loaded models, inference latency, queueing, TLS expiry and recent errors. Alert before model pulls or backups exhaust disk and review model/image updates on a schedule.

Why this step matters

Local inference consumes finite disk, memory and accelerator capacity. Monitoring detects queues, failed renewals and storage exhaustion before user-visible failure.

What to understand

Alert on volume growth and backup age.

Observe loaded model residency.

Track p95 inference and queue.

Review logs without retaining prompts by default.

System changes

  • Reads operational state and emits approved metrics.
  • No model or data change.

Syntax explained

ollama ps
Shows models currently loaded.
docker system df
Container storage usage.
tls_expiry_days
Certificate renewal safety margin.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

cd /opt/local-ai && sudo docker compose ps && sudo docker compose exec ollama ollama ps && sudo docker system df && df -h {{backupRoot}}
Example output / evidence
services_healthy=2/2
restart_count=0
loaded_model=gemma3:4b
processor=100% GPU
model_volume=3.4G
openwebui_volume=1.2G
backup_free=1.8T
tls_expiry_days=83
recent_errors=0

Checkpoint: Test alert paths

node local-ai/test-alerts.mjs

Continue whenDisk, health, latency, queue, backup age and TLS alerts reach operators.

Stop whenStop expansion if monitoring cannot detect capacity or certificate failure.

If this step fails

Disk alert fires after pull failure.

Likely causeThreshold ignored artifact size.

Safe checks
  • Compare free space and model size.
  • Inspect alert threshold.

ResolutionReserve pull/update/backup headroom and alert earlier.

Security notes

  • Do not export raw prompts in metrics.
  • Restrict logs and admin dashboards.

Alternatives

  • Use existing Prometheus/node monitoring.
  • Schedule manual checks for very small isolated deployments.

Stop conditions

  • Stop expansion if monitoring cannot detect capacity or certificate failure.
15

verification

Prove matched image, data and model rollback

danger

Before closing the update, dry-run restoration of the previous images, pre-update Open WebUI archive, secret and model manifest in an isolated project. A live rollback stops access, preserves current state, restores matched data and re-runs acceptance.

Why this step matters

Database migrations mean image rollback alone may fail. A matched release includes data, secret, proxy and model state and must be proven before an incident.

What to understand

Preserve current state before live restore.

Restore to a new volume first.

Verify admin/data/model/proxy.

Cut over only after evidence.

System changes

  • Dry-run changes no production state.
  • A live run restores matched prior artifacts and data.

Syntax explained

--from
Failed candidate release.
--to
Known-good matched release.
--dry-run
Resolves and tests without production cutover.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

node local-ai/rollback.mjs --from local-ai/2026-08-10.1 --to {{releaseId}} --dry-run
Example output / evidence
from=local-ai/2026-08-10.1
to={{releaseId}}
image_digests=RESOLVED
data_backup=VERIFIED
secret_digest=AVAILABLE
model_manifest=AVAILABLE
isolated_restore=PASS
acceptance=PASS
live_changes=0

Checkpoint: Approve rollback evidence

node local-ai/rollback.mjs --status {{releaseId}}

Continue whenAll matched artifacts resolve and isolated acceptance passes within RTO.

Stop whenStop promotion if prior data/image/secret/model cannot restore.

If this step fails

Old UI starts but data schema errors continue.

Likely causeNew database remained.

Safe checks
  • Inspect volume mount.
  • Compare backup timestamp.

ResolutionRestore the matched pre-update archive into a clean volume.

Security notes

  • Protect both old and new backups.
  • Audit live rollback authorization.

Alternatives

  • Blue/green cutback.
  • Disable access until clean restore is proven.

Stop conditions

  • Stop promotion if prior data/image/secret/model cannot restore.

Finish line

Verification checklist

Private Ollama! ss -lnt | grep -q ':11434 ' && cd /opt/local-ai && sudo docker compose exec open-webui curl -fsS http://ollama:11434/api/versionInternal reachability works and no host listener exists.
HTTPS and authenticationcurl -I https://{{hostName}} && nmap -Pn -p 3000,11434 {{hostName}}HTTPS responds while direct application and Ollama ports are blocked.
Model lifecyclecd /opt/local-ai && sudo docker compose exec ollama ollama list && sudo docker compose exec ollama ollama run {{modelName}} 'Reply with exactly: MODEL_OK'Approved model ID is present and smoke returns MODEL_OK.
Backup restorenode local-ai/restore-check.mjs --backup-root {{backupRoot}} --release {{releaseId}}Isolated admin, data, WebSocket and model smokes pass within RTO.
Rollback readinessnode local-ai/rollback.mjs --status {{releaseId}}Matched image, data, secret, proxy and model artifacts resolve.

Recovery guidance

Common problems and safe checks

Open WebUI shows no Ollama models.

Likely causeThe internal base URL, network or Ollama service is wrong.

Safe checks
  • curl Ollama from inside the Open WebUI container.
  • Inspect both service logs.

ResolutionSet the documented internal Ollama URL, join the same private network and restart after configuration review.

Ollama works on the host but not in the container.

Likely causelocalhost points to the container itself.

Safe checks
  • Resolve the ollama service name.
  • Test port 11434 on the Compose network.

ResolutionUse http://ollama:11434 for the Compose service and do not publish the API unnecessarily.

A model pull fills the disk.

Likely causeModel size and temporary download capacity were not budgeted.

Safe checks
  • Check df and docker system df.
  • List model inventory and volume size.

ResolutionStop pulls, add approved storage or remove explicitly retired models after backup/manifest review.

Inference is extremely slow or queues.

Likely causeThe model does not fit available memory/VRAM or too many models remain loaded.

Safe checks
  • Run ollama ps.
  • Observe host/GPU memory and logs.

ResolutionSelect a smaller reviewed model, stop unused loaded models and cap concurrency based on measurement.

Users are logged out after container replacement.

Likely causeWEBUI_SECRET_KEY changed or the data volume was not persisted.

Safe checks
  • Verify the mounted data volume.
  • Compare secret digest without printing it.

ResolutionRestore the stable secret and persistent volume; expect reauthentication if the key truly rotated.

The browser reports a WebSocket disconnect.

Likely causeReverse proxy upgrade headers or timeout behavior is incorrect.

Safe checks
  • Inspect browser network events.
  • Review proxy and Open WebUI logs.

ResolutionApply the official reverse-proxy configuration and retest an active streamed chat.

HTTPS works but direct http://host:3000 also works externally.

Likely causeThe application port is bound to all interfaces or firewall permits it.

Safe checks
  • Check ss -lntp.
  • Test from an external network.

ResolutionBind 127.0.0.1 only or remove host publication and allow only reverse-proxy traffic.

The first account is not the intended administrator.

Likely causeBootstrap was exposed before the operator enrolled.

Safe checks
  • Disable external access.
  • Inspect user/admin records and logs.

ResolutionTreat it as an incident, preserve evidence and restore/reinitialize from a known clean state under the documented Open WebUI procedure.

An update starts but migrations fail.

Likely causeThe new image is incompatible with current data or resources.

Safe checks
  • Inspect update logs.
  • Run the same image against a staging copy.

ResolutionStop production promotion and restore the prior image plus pre-update data snapshot.

Rolling back the image does not fix the application.

Likely causeThe database was migrated and is not backward compatible.

Safe checks
  • Compare data schema/update logs.
  • Inspect the pre-update backup.

ResolutionRestore both prior image and matched pre-update data in an isolated recovery, then verify before cutover.

Backup archive exists but chats are missing.

Likely causeThe wrong volume or mount path was archived.

Safe checks
  • List archive paths.
  • Inspect Docker volume mounts.

ResolutionBack up the actual /app/backend/data volume and require a restore smoke before acceptance.

Ollama becomes reachable on the LAN.

Likely causeOLLAMA_HOST or Docker port publication widened its bind.

Safe checks
  • Inspect Compose ports and service environment.
  • Test 11434 externally.

ResolutionRemove publication, restore private binding/network and review access logs.

Model behavior changes after a pull.

Likely causeA mutable model tag resolved to new content.

Safe checks
  • Compare model manifest and digest.
  • Run frozen prompts.

ResolutionRestore the approved model artifact/tag and require digest/eval review for lifecycle changes.

TLS certificate renewal fails.

Likely causeDNS, port reachability, clock or proxy storage is unhealthy.

Safe checks
  • Inspect proxy logs and certificate dates.
  • Verify DNS and system time.

ResolutionRepair renewal prerequisites before expiry; use approved internal PKI for private deployments.

Open WebUI backup contains secrets in plain storage.

Likely causeBackup handling was treated as ordinary application data.

Safe checks
  • Classify archive contents.
  • Review destination permissions and encryption.

ResolutionRestrict and encrypt storage, rotate exposed secrets and update backup policy.

After the procedure

Alternatives and next steps

Consider these alternatives

  • Run Ollama and Open WebUI only on loopback for one workstation when remote access, multi-user identity and central operations are unnecessary.
  • Use an approved VPN or zero-trust access proxy in front of the reverse proxy for administrative or private-team deployments.
  • Use a hosted provider when local hardware, power, model lifecycle, security updates and backup responsibilities exceed the team's capacity.
  • Use Kubernetes or a documented HA architecture only when availability requirements justify external database, Redis, shared storage and operational complexity.

Operate it safely

  • Add hardware and model benchmark records for approved workloads, including memory, prompt processing, generation speed and quality.
  • Automate off-host encrypted backups and scheduled isolated restore verification with a human-reviewed result.
  • Add SSO or an approved access proxy when the user population grows, while preserving a break-glass administrator path.
  • Build a staging host or isolated Compose project that tests image, database and model updates before production.

Reference

Frequently asked questions

Is local inference automatically private?

No. It keeps model inference local, but plugins, external providers, web search, logs and backups may still transmit or retain data. Review the complete data flow.

Should I expose Ollama through the reverse proxy?

Usually no. Let Open WebUI reach it on a private network. Expose an API only with a separate authenticated and authorized gateway designed for that purpose.

Can I use the main or latest image tag in production?

Use it to discover an update, then record and deploy a reviewed immutable digest with a tested rollback. Rolling tags can move.

Do model files need backup?

They can often be pulled again, but retain a manifest and any custom model definitions. Decide whether backing up large blobs is faster and more reliable than redownloading under your recovery objective.

Recovery

Rollback

Stop public access, preserve the current failed state, restore the prior pinned images and matched pre-update Open WebUI data into a clean volume, restore the stable secret and model manifest, then reopen only after external acceptance.

  1. Block or drain HTTPS access and preserve current volume snapshot and logs under policy.
  2. Resolve the known-good release's image digests, secret digest, proxy config, model manifest and pre-update archive.
  3. Restore the archive into a new clean volume; never erase the only live volume first.
  4. Start the prior release on isolated loopback ports and verify admin login, data, WebSocket and model inference.
  5. Cut over to the restored volume/release, verify external TLS/auth and confirm 3000/11434 remain blocked.
  6. Keep failed artifacts for analysis, add the failure to staging acceptance and create a new release for correction.

Evidence

Sources and review

Verified 2026-07-24Review due 2027-01-20
Ollama official Linux installation and service documentationofficialOllama official FAQ for configuration, storage and networkingofficialOllama official model pull API and lifecycle responseofficialOpen WebUI official Docker quick start, persistence and authenticationofficialOpen WebUI official hardening and secret key guidanceofficialOpen WebUI official HTTPS and reverse proxy guidanceofficialOpen WebUI official update, backup and restore guidanceofficialDocker official Compose and persistent volume documentationofficial