静看光阴荏苒
不管不顾不问不说也不念

Docker部署的Open WebUI连接非Docker部署的Ollama

之前网上已经有很多文章提到过Ollama API未经授权访问的事情。。其实大概就是很多人把Ollama直接监听到0.0.0.0了。。我估计大多数人也不是错误配置,基本上可以说都只是为了将Ollama与其他的程序进行对接时才这样配置的。因为解决Ollama与其他程序对接问题最简单的办法就是监听0.0.0.0。

但是这就暴露出来一个安全问题,由于Ollama官方一直不愿意(#1053 #8536 #9131)搞个API鉴权的功能出来,这就导致如果把Ollama部署在有公网的机器上,监听0.0.0.0就等于是自杀。。

其实早在这些文章发布前我自己就经历过一次,当时是拿来测试用的,测试完了忘记改回来了,没过几天就被别人拿来白嫖了= =

然后我最近又部署了一个Ollama,没有用Docker,但是对接的Open WebUI是用Docker部署的,又遇到这个问题了,有过上次的教训这次就想彻底解决掉这问题。。

首先在Open WebUI的compose内肯定是要配置host.docker.internal:host-gateway的,这个功能其实就是在容器系统内的hosts文件里添加一行如下配置:

172.17.0.1 host.docker.internal

其中172.17.0.1是宿主机在Docker默认桥接网络中的网关地址。有了这个配置后,容器内部的应用只需请求http://host.docker.internal,就能访问宿主机的服务了。

但是如果宿主机的服务只监听127.0.0.1(环回接口),host.docker.internal能访问到宿主机的这个服务吗?很明显不行啊,因为容器系统内部的127.0.0.1是容器自己,不是宿主机。所以这个时候直接将服务监听到0.0.0.0,那host.docker.internal就能访问到了,但问题就如之前说的Ollama没鉴权,直接暴露在公网会有安全问题。

监听0.0.0.0对于有公网的环境来说不适用,那还有一个办法就是配置Docker容器使用主机网络(Host Network)但是我也不想用这种方案,我还是想用默认的桥接网络。我想到一个办法就是用Socat弄一个端口转发,把172.17.0.1:11434的流量转发到127.0.0.1:11434,可不可行?我也不知道,但是我试了一下确实能用。。。

这里记录下完整的部署过程。安装Docker和需要用到的软件包:

apt -y update
apt -y install socat curl nginx python3-certbot-nginx
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

创建目录和compose文件:

mkdir -p /opt/openwebui && cd /opt/openwebui && nano docker-compose.yml

写入如下内容:

services:
  openwebui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: openwebui
    extra_hosts:
      - "host.docker.internal:host-gateway"
    ports:
      - "50000:8080"
    volumes:
      - open-webui:/app/backend/data
volumes:
  open-webui:

启动Open WebUI:

docker compose up -d

配置NGINX反向代理:

nano /etc/nginx/sites-available/openwebui

写入如下内容:

server {
    listen 80;
    server_name openwebui.example.com;

    location / {
        proxy_pass http://127.0.0.1:50000;
        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_buffering off;
        client_max_body_size 0;
        proxy_read_timeout 10m;
    }
}

启用站点:

ln -s /etc/nginx/sites-available/openwebui /etc/nginx/sites-enabled/openwebui

签发SSL证书:

certbot --nginx

访问Open WebUI创建管理员账号:

接下来安装Ollama:

curl -L https://ollama.com/download/ollama-linux-amd64.tgz -o ollama-linux-amd64.tgz
tar -C /usr -xzf ollama-linux-amd64.tgz

添加一个用户,后续用这个用户来运行Ollama:

useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama
usermod -a -G ollama $(whoami)

新建systemd配置文件:

nano /etc/systemd/system/ollama.service

写入如下内容:

[Unit]
Description=Ollama Service
After=network-online.target

[Service]
ExecStart=/usr/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="PATH=$PATH"

[Install]
WantedBy=multi-user.target

启动并设置Ollama开机自启:

systemctl enable --now ollama

最后用Socat配置一个端口转发,新建systemd配置文件:

nano /etc/systemd/system/socat-ollama.service

写入如下内容:

[Unit]
Description=Socat port forward 11434 on 172.17.0.1 to 127.0.0.1:11434
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/socat TCP4-LISTEN:11434,bind=172.17.0.1,fork,reuseaddr TCP4:127.0.0.1:11434
Restart=always
RestartSec=2
LimitNOFILE=4096

[Install]
WantedBy=multi-user.target

启动并设置开机自启:

systemctl enable --now socat-ollama

Open WebUI的配置:

测试:

总结:

方案1:Ollama直接监听0.0.0.0,不适用公网环境。
方案2:配置Docker容器使用主机网络,比较简单的解决方案,但降低了Docker网络的隔离性。
方案3:配置一个端口转发,既可以用在公网环境,也不需要使用主机网络,保障了Docker网络的隔离性。
方案4(未实践):搭建One API,然后用One API中转。
方案5(未实践):不确定这种能不能与Open WebUI兼容,https://github.com/ParisNeo/ollama_proxy_server

赞(0)
未经允许不得转载:荒岛 » Docker部署的Open WebUI连接非Docker部署的Ollama
分享到: 更多 (0)

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    还有一个方案就是监听在 0.0.0.0 但是端口设置白名单 IP 才能访问,可以用 iptables 或者 nftables 来设置

    另外容器里的 hosts 文件不建议直接修改,可以在 compose 文件里添加两行即可

    extra_hosts:
    – “域名:IP地址”

    Showfom12小时前 Firefox 139.0 Firefox 139.0 Windows 10 x64 Edition Windows 10 x64 Edition回复

分享创造快乐

广告合作资源投稿