Self-hosted • Privacy-first • No tracking
Home / Self-Hosted AI / Self-Hosted AI Privacy Benefits: A Technical Deep Dive with Docker Compose
Self-Hosted AI #privacy#docker-compose#ollama#self-hosted-ai#open-webui ⏱ 12 min • 👁 1 • Sep 01, 2026

Self-Hosted AI Privacy Benefits: A Technical Deep Dive with Docker Compose

Explore the technical privacy advantages of self-hosted AI, with a full Docker Compose deployment guide for Ollama and Open WebUI, covering data control, network isolation, and security hardening.

AdSense — Top (970x90) • Responsive
Self-Hosted AI Privacy Benefits: A Technical Deep Dive with Docker Compose

1. Introduction

The rise of cloud-based AI services has brought unprecedented capabilities, but it has also created a significant privacy gap. When you send a prompt to a cloud API, your data — including proprietary code, personal documents, and confidential communications — traverses your network, enters a third-party data center, and is often stored for model training or compliance purposes. For homelab enthusiasts and privacy-conscious professionals, this is a fundamental loss of data sovereignty. Self-hosted AI is not just a hobbyist's toy; it is a technical strategy for reclaiming control over your digital footprint.

This guide provides a deep technical exploration of why self-hosted AI is a superior choice for privacy. We will move beyond abstract concepts and build a production-ready AI stack using Ollama for local model inference and Open WebUI as a privacy-respecting frontend. You will learn how to architect a system that ensures data never leaves your hardware, how to isolate it on your network, and how to apply security hardening techniques that go beyond default configurations.

By the end of this article, you will have a fully functional, private AI assistant running on your own infrastructure. You will understand the network topology, the data flow, and the security mechanisms that make self-hosting the gold standard for AI privacy. We will cover everything from prerequisite hardware specifications to advanced reverse proxy setup and backup strategies. This is not a high-level overview; it is an operational manual.

We will adhere strictly to verified facts. Where specific versions are not pinned, you will see placeholders like ${OLLAMA_VERSION:-latest}. You must check the official GitHub releases page before pinning a version — the version above may be outdated by now. Performance figures are provided as typical ranges, not benchmarks, because real-world results depend heavily on your specific CPU, GPU, and model size.

2. Prerequisites / Requirements

Before we begin, you need to ensure your hardware and software environment can support a local AI inference engine. Ollama is optimized for Apple Silicon (M-series) and NVIDIA GPUs via CUDA, but it can also run on CPU-only systems with reduced performance. Below is a detailed breakdown of the requirements.

Component Minimum Requirement Recommended Requirement Notes
CPU x86_64 or ARM64, 4 cores 8+ cores (AMD Ryzen 7 / Intel Core i7 / Apple M2 Pro) CPU handles model scheduling and non-GPU inference.
RAM 16 GB 32 GB+ RAM is critical for loading models. A 7B parameter model typically requires ~8 GB, while a 13B model may need ~16 GB.
Storage 20 GB free space 1 TB NVMe SSD Model files are large (4-8 GB each). NVMe reduces model load time.
GPU (Optional) NVIDIA GPU with 8 GB VRAM (e.g., RTX 3060) NVIDIA RTX 4090 24 GB or Apple M1 Max/Ultra CUDA support is mandatory for NVIDIA. Without a GPU, inference speed will be significantly slower (CPU-only).
OS Linux (Ubuntu 22.04+), macOS 13+, Windows 11 via WSL2 Ubuntu Server 24.04 LTS Docker Desktop is required on Windows/macOS.
Software Docker Engine 24+ & Docker Compose v2 Docker Engine 26+ You must have docker compose (v2) command available, not the legacy docker-compose.
Network Local network with DHCP VLAN capable router For isolating your AI stack from your main LAN.

Software Installation: This guide assumes you have Docker and Docker Compose installed. If not, run the following commands on a fresh Ubuntu server.

sudo apt update && sudo apt install -y ca-certificates curl gnupg lsb-release && sudo install -m 0755 -d /etc/apt/keyrings && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg && sudo 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/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null && sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable docker && sudo systemctl start docker && sudo usermod -aG docker $USER

Log out and back in for the group change to take effect.

3. Installation & Configuration Steps

We will deploy two services: ollama (inference engine) and open-webui (web interface). The critical privacy feature here is that all communication stays within a private Docker network. We will not expose the Ollama API port to the host's public interface; only the web UI will be accessible via a reverse proxy.

Step 1: Create Project Structure and .env File

First, create the directory structure and a .env file to hold secrets and version variables. Never commit this file to Git.

mkdir -p ~/ai-stack && cd ~/ai-stack && mkdir -p data/ollama data/open-webui

Now, create the .env file using nano or vim.

nano .env

Paste the following content. Replace the passwords with strong, unique values.

# AI Stack Environment Variables
# WARNING: Never commit this file to version control.
# WARNING: Never commit this file to version control.

# Version pins - CHECK OFFICIAL GITHUB RELEASES BEFORE PINNING
OLLAMA_VERSION=latest
OPEN_WEBUI_VERSION=latest

# Database Credentials (for Open WebUI's internal DB)
POSTGRES_PASSWORD=change_this_strong_password_123

# Web UI Secret (used for session signing)
WEBUI_SECRET_KEY=change_this_another_strong_secret_456

# Host Ports
WEBUI_PORT=3000
OLLAMA_HOST_PORT=11434

Step 2: Create Docker Compose File

Create the docker-compose.yml file. This file defines the services, the network, and the volumes.

nano docker-compose.yml

Paste the following complete configuration.

version: "3.8"

services:
  ollama:
    image: ollama/ollama:${OLLAMA_VERSION:-latest}
    container_name: ollama
    restart: unless-stopped
    volumes:
      - ./data/ollama:/root/.ollama
    networks:
      - ai_net
    # No ports exposed to host. Only accessible via the internal network.
    # For GPU support, uncomment the following lines and comment out the 'cpu' deploy section.
    # deploy:
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           count: all
    #           capabilities: [gpu]

  open-webui:
    image: ghcr.io/open-webui/open-webui:${OPEN_WEBUI_VERSION:-latest}
    container_name: open-webui
    restart: unless-stopped
    depends_on:
      - ollama
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
      - WEBUI_SECRET_KEY=${WEBUI_SECRET_KEY}
      - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@db:5432/openwebui
    volumes:
      - ./data/open-webui:/app/backend/data
    networks:
      - ai_net
    ports:
      - "${WEBUI_PORT:-3000}:8080" # Expose only the UI.

  db:
    image: postgres:16-alpine
    container_name: ai-db
    restart: unless-stopped
    environment:
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=openwebui
      - POSTGRES_USER=postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    networks:
      - ai_net
    # No ports exposed to host. Internal only.

networks:
  ai_net:
    driver: bridge
    internal: false # Set to 'true' for stricter isolation, but then you need a proxy on the same network.

Note on internal: false: The network is not marked internal because we need the open-webui container to bind to a host port. However, the ollama and db containers have no host port mappings, making them inaccessible from outside the Docker network.

Step 3: Pull and Start the Stack

Pull the images and start the stack in detached mode.

docker compose up -d --pull always

Step 4: Verify the Containers are Running

Check the status of all containers.

docker compose ps

You should see three containers: ollama, open-webui, and ai-db. If any container exited with an error, check the logs with docker compose logs <service_name>.

Step 5: Pull an AI Model into Ollama

Now that Ollama is running, you need to pull a model. We will use llama3.2:3b which is a small, efficient model suitable for testing. Execute this command inside the running ollama container.

docker exec -it ollama ollama pull llama3.2:3b

Step 6: Access the Web UI

Open your browser and navigate to http://<your-server-ip>:3000. You will be prompted to create an admin account. This is the first user who will have full administrative rights.

Step 7: Configure the Web UI to Use the Local Model

In the Open WebUI interface, go to Settings -> Models. You should see llama3.2:3b listed. If not, click the refresh button. Select it as the default model.

Step 8: Test the Privacy Boundary

To prove the privacy benefits, we will verify that the Ollama API is not exposed to the host. Run the following command from your host machine.

curl http://localhost:11434/api/tags

This command should fail with a connection refused error. This confirms that the Ollama service is only accessible within the Docker network. Your data is processed locally and is not reachable by external network interfaces.

4. Advanced Configuration & Optimization

4.1 Reverse Proxy with SSL (Nginx Proxy Manager)

To access your AI stack securely from the internet (or your LAN with proper DNS), you should place it behind a reverse proxy. This adds TLS encryption and proper HTTP routing. Add the following service to your docker-compose.yml.

  nginx-proxy:
    image: jc21/nginx-proxy-manager:latest
    container_name: nginx-proxy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "81:81" # Admin UI
    volumes:
      - ./data/nginx/data:/data
      - ./data/nginx/letsencrypt:/etc/letsencrypt
    networks:
      - ai_net

After adding this, run docker compose up -d. Access the admin UI on port 81 (default credentials: admin@example.com / changeme). Set up a proxy host for open-webui pointing to open-webui:8080 and enable SSL via Let's Encrypt.

4.2 Backup Strategy

Your data is in the ./data directory. To back up, you can use rsync or a tool like restic. The critical data is the ./data/open-webui and ./data/db directories. Here is a simple backup command to a local drive.

rsync -avz --delete ~/ai-stack/data/ /mnt/backup-drive/ai-stack-data/

For automated backups, consider a cron job. Warning: Do not back up the .env file to an insecure location.

4.3 Optional Hardening

The following settings are optional and require adaptation for your specific environment. Copying them verbatim may break container functionality. They are provided for advanced users who understand the trade-offs.

services:
  ollama:
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - SETGID
      - SETUID

Warning: Setting read_only: true might prevent Ollama from writing to its model cache if the volume mount is not properly configured. The cap_drop might break GPU access if not properly configured with --device mappings. Test thoroughly in a staging environment.

5. Troubleshooting

Common Error Likely Cause Solution
connection refused on curl localhost:11434 Ollama port is not mapped to host. This is expected. The service is internal. Use docker exec -it ollama curl localhost:11434 to test internally.
Error: pull access denied for llama3.2:3b Model name is incorrect or not available for your architecture. Check the official Ollama library for the correct model tag. Try llama3.2 or tinyllama.
Open WebUI shows Ollama not reachable The OLLAMA_BASE_URL environment variable is incorrect. Verify the URL is http://ollama:11434 (service name, not IP). Check if the ollama container is running.
Permission denied when writing to volumes Host directory ownership mismatch. Run id -u && id -g on your host and verify against the image's documentation (default user in this image is root for Ollama, but for Open WebUI it might be 1000). Adjust permissions with chown or chmod accordingly.
Docker Compose syntax error YAML indentation or missing version key. Validate the YAML file with docker compose config.
GPU not detected in Ollama CUDA drivers not installed on host or deploy section not uncommented. Install NVIDIA drivers and nvidia-container-toolkit. Uncomment the deploy section in the compose file.

6. Conclusion & FAQ

Self-hosting AI is the definitive answer to the privacy concerns of cloud-based services. By following this guide, you have built a stack where your prompts, your documents, and your interactions are processed entirely on your own hardware. The network isolation between the inference engine and the web interface ensures that your data does not leak through unintended ports. This is not just about convenience; it is about establishing a sovereign digital boundary.

The technical benefits are clear: complete data ownership, no third-party retention policies, and the ability to audit the entire software stack. While the initial setup requires some effort, the long-term payoff in privacy and customization is immeasurable. You are no longer a user of a service; you are the operator of your own infrastructure.

As you continue, explore different models, fine-tune parameters, and integrate this stack with other self-hosted services. The skills you have learned here — containerization, network isolation, and secure deployment — are transferable to any other privacy-respecting application. The era of blindly trusting cloud providers is over; the era of self-sovereign AI has begun.

FAQ

Q1: Is self-hosted AI truly private if I use a reverse proxy?

Yes, the privacy boundary is at the application layer. The reverse proxy only handles encrypted HTTP traffic (TLS). The AI model inference and data storage happen inside your Docker network. The proxy does not have access to the raw model weights or the database. It only forwards requests to the web UI. Your data is still processed locally.

Q2: Can I run this on a Raspberry Pi?

Technically yes, but performance will be severely limited. A Raspberry Pi 5 with 8 GB RAM can run very small models like tinyllama (1.1B parameters) with slow inference speeds (typically > 1 minute per response). It is not recommended for a production experience. A dedicated x86 server or a Mac Mini is a better investment.

Q3: How do I update Ollama and Open WebUI?

To update, pull the new images and recreate the containers. First, check the official GitHub releases for breaking changes. Then, run docker compose pull followed by docker compose up -d. Always back up your ./data directory before major version updates.

Q4: What happens if I lose my .env file?

You will not be able to start the stack if the environment variables are missing. The WEBUI_SECRET_KEY invalidates all user sessions, and the POSTGRES_PASSWORD will prevent the database from starting. This is why it is critical to store a backup of the .env file in a secure location, such as a password manager.

Q5: Can I expose the Ollama API directly to the internet for remote access?

You can, but it is highly discouraged. The Ollama API has no built-in authentication. If you expose it, anyone can use your GPU resources and potentially access your models. If you must have remote access, use a VPN like WireGuard or Tailscale to access your internal network, and keep the API on the private Docker network.

AdSense — In-article (responsive)

Related Guides