(含离线包) 基于Ubuntu22.04 LTS 构建企业内网Ollama + DeepSeek R1 + Open WebUI私有化部署方案
1. 为什么企业需要一套内网专属的AI助手?
最近几年,大语言模型(LLM)火得一塌糊涂,很多企业都想用上这个“智能大脑”来提升效率。但问题来了,直接把公司的文档、代码、客户信息喂给公网上的AI服务?这风险太大了,数据安全和隐私保护是第一道坎。其次,很多研发中心、金融机构的服务器压根就不连外网,完全物理隔离,想用也连不上。再者,公网服务有延迟、有使用限制,高峰期卡顿也是常事。
所以,一套部署在企业自己内网服务器上的、完全私有的AI应用栈,就成了刚需。这就好比把水厂建在自己家里,水质自己把控,用水随时都有,还不用担心停水。今天我要分享的,就是基于 Ubuntu 22.04 LTS 这个稳定基石,利用 Ollama 这个轻量模型运行引擎,搭载最新的 DeepSeek R1 推理模型,并通过 Open WebUI 提供一个媲美ChatGPT的漂亮交互界面,最终构建一套完整的企业内网私有化AI方案。
更关键的是,我理解很多内网环境是“与世隔绝”的。因此,这个方案的核心是 “离线部署” 。我会提供所有必要组件的离线包,并教你如何在内网中架设一个临时的“软件仓库”(本地Web服务器),让Ubuntu服务器能像访问内网网站一样,轻松获取所有安装文件。这样一来,即使服务器一辈子不连互联网,也能顺利完成整套系统的搭建。这个方案我亲自在多个客户的生产环境中部署过,实测下来非常稳定,接下来我就把每一步的细节、踩过的坑和优化技巧,毫无保留地分享给你。
2. 部署前的核心准备:打造内网“软件源”
在完全离线的环境里部署软件,最大的挑战就是依赖和安装包从哪里来。我们的思路很直接:找一台能上互联网的Windows电脑(比如你的办公机),把所有需要的“砖块”(安装包、Docker镜像、模型文件)先下载好,然后在这台电脑上启动一个简单的Web文件服务,让内网的Ubuntu服务器能过来“取货”。
2.1 离线资源包获取与校验
首先,你需要准备一个足够大的硬盘分区(建议至少100GB空闲空间),因为模型文件体积不小。我在网盘里已经为你整理好了所有必需的离线组件包,你可以按需下载。
注意:由于网盘链接可能随时间失效,且模型版本会更新,最稳妥的方式是参考此方法,自行从官方渠道下载最新版本的文件进行储备。这里以我提供的离线包为例讲解原理。
你需要下载的主要有四大类文件:
- Ollama安装包: 这是运行模型的引擎本体,一个Linux下的可执行文件。
- DeepSeek-R1模型文件: 这是AI的“大脑”,我们提供了从1.5B到70B多种参数规模的版本,企业可以根据自身服务器硬件(特别是GPU显存)来选择。参数越大,通常能力越强,但也需要更多资源。
- Open WebUI的Docker镜像: 这是我们将要使用的Web界面,打包成了Docker镜像,方便部署和管理。
- 工具软件: 包括用于搭建本地Web服务器的
chfs工具,以及文件校验工具。
下载完成后,校验文件完整性是必不可少的一步,可以避免因文件损坏导致后续安装过程各种诡异的失败。你可以使用校验工具(如HashCheck)对下载的文件计算SHA256值,并与我提供的校验值(通常我会放在网盘的checksum.txt文件里)比对,确保每一个文件都完好无损。
2.2 在Windows上快速搭建本地文件服务器
有了“砖块”,我们得建个“临时仓库”。这里我强烈推荐chfs(CuteHttpFileServer),它就是一个单文件的可执行程序,无需安装,功能专注就是分享文件,特别适合这种临时场景。
操作非常简单:
- 将下载好的
chfs.exe文件,复制到C:\Windows\System32\目录下。这样你可以在命令行的任何位置直接运行chfs命令。 - 假设你把所有离线组件都放在了
D:\chfs_web文件夹里。 - 打开Windows的
cmd命令行,运行以下命令启动服务:
这个命令的意思是,将chfs --path="D:\chfs_web" --port=8080D:\chfs_web目录通过HTTP协议共享出来,监听在本机的8080端口。 - 启动后,你可以在同一局域网的任意设备(包括这台Windows电脑本身)的浏览器里,访问
http://你的Windows电脑IP:8080。如果能看到chfs_web目录下的文件列表,恭喜你,内网“软件源”已经搭建成功!
记得关闭Windows的防火墙,或者放行8080端口的入站规则,确保Ubuntu服务器能访问到这个页面。这台Windows电脑在接下来的整个部署过程中需要保持开机和chfs程序运行。
3. Ubuntu服务器基础环境配置
现在,我们把目光转向今天的主角——内网的Ubuntu 22.04 LTS服务器。我假设你已经完成了系统的基础安装。为了后续过程更顺畅,我们先做几项关键的初始化配置。
3.1 系统基础优化
首先,修改软件源。即便是内网,如果你们公司有内部的Ubuntu镜像源,一定要换成内网源,速度会快很多。如果没有,在系统安装时就可以选择国内的镜像,比如阿里云、清华大学的源。这里以阿里云为例,备份并修改/etc/apt/sources.list文件:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
然后更新软件包列表:sudo apt update && sudo apt upgrade -y。
其次,设置正确的时区。这会影响日志时间,对于排查问题很重要。
sudo timedatectl set-timezone Asia/Shanghai
最后,关于图形界面。对于服务器,我强烈建议使用纯命令行界面(Server版),资源占用更少,更稳定。如果你已经安装了GUI(桌面环境),可以酌情考虑是否移除。
3.2 显卡驱动的特别说明(如果适用)
如果你的服务器配备了NVIDIA显卡并打算用GPU来加速模型推理(这能极大提升速度),那么安装正确的NVIDIA驱动和CUDA工具包就是必须的。这个过程需要一些技巧:
- 禁用系统自带的
nouveau开源驱动:这是NVIDIA驱动的“死对头”,不先禁用它,官方驱动很可能装不上或者导致系统死机。通常需要修改GRUB配置并重建initramfs。 - 安装NVIDIA官方驱动:可以通过
ubuntu-drivers工具自动安装推荐版本,也可以去NVIDIA官网下载对应你显卡型号和系统版本的最新驱动手动安装。 - 安装CUDA Toolkit:Ollama和PyTorch等框架依赖CUDA。建议通过NVIDIA提供的网络安装方式,选择与你的驱动版本兼容的CUDA版本。
因为这部分内容根据显卡型号和系统环境差异较大,且不是本方案的核心(CPU也能运行,只是慢一些),我就不展开详述了。网上有大量详细的教程,关键词是“Ubuntu 22.04 安装 NVIDIA 驱动 CUDA”。完成驱动安装后,务必运行nvidia-smi命令验证驱动和GPU识别是否正常。
4. 离线部署Ollama服务引擎
Ollama是整个方案的基石,它负责管理和运行我们下载的DeepSeek R1模型。官方的一键安装脚本非常方便,但它是从国外服务器下载安装包。我们的任务就是“偷梁换柱”,让脚本从我们刚建好的本地Web服务器下载。
4.1 修改并运行离线安装脚本
整个过程就像是一个简单的“抓包改包”操作。我们先把官方脚本下载下来,然后将其中的下载链接替换成我们内网服务器的地址。
# 创建一个临时工作目录
mkdir -p /tmp/ollama_install && cd /tmp/ollama_install
# 下载官方的安装脚本(如果服务器完全离线,此步可跳过,直接从能上网的机器下载后拷贝进来)
# 假设你已通过其他方式将 install.sh 放到了服务器上,或者直接使用我离线包中提供的脚本副本
# 这里演示从官方下载(如果网络可达):
wget https://ollama.com/install.sh
# 备份原脚本
cp install.sh install_local.sh
# 关键步骤:替换脚本中的下载源地址
# 将脚本中所有 'https://ollama.com/download/' 开头的URL,替换成你的本地Web服务器地址
# 请将 192.168.1.100:8080 替换成你实际的Windows电脑IP和端口
# 假设你的ollama安装包放在本地Web服务器的 /chfs/shared/ollama/ 路径下
sed -i 's|https://ollama.com/download/|http://192.168.1.100:8080/chfs/shared/ollama/|g' install_local.sh
# 运行修改后的脚本进行安装
sudo bash install_local.sh
脚本执行后,它会自动完成下载(从你的本地服务器)、安装、设置系统服务(systemd)和开机自启。用systemctl status ollama命令检查一下,看到active (running)就表示Ollama服务已经在后台跑起来了。
4.2 配置Ollama网络监听
默认情况下,Ollama服务只监听127.0.0.1(即本机回环地址)。这意味着只有Ubuntu服务器自己能用localhost访问它。但我们的Open WebUI是跑在Docker容器里的,从网络角度看是另一个“机器”,需要能连接到Ollama。
所以,我们需要修改配置,让Ollama监听在所有网络接口上(0.0.0.0)。
# 备份原始的service配置文件,这是个好习惯
sudo cp /etc/systemd/system/ollama.service /etc/systemd/system/ollama.service.bak
# 编辑service文件,在[Service]部分下添加一个环境变量
sudo sed -i '/\[Service\]/a Environment="OLLAMA_HOST=0.0.0.0"' /etc/systemd/system/ollama.service
# 重新加载systemd配置,并重启Ollama服务使配置生效
sudo systemctl daemon-reload
sudo systemctl restart ollama
sudo systemctl status ollama # 再次确认服务状态
现在,你可以在同一局域网内的另一台电脑的浏览器里访问 http://你的Ubuntu服务器IP:11434。如果页面上显示 “Ollama is running” ,那么恭喜,Ollama的API服务已经成功对外开放了。这个11434端口就是Ollama的默认服务端口。
5. 导入与运行DeepSeek R1大模型
模型文件是AI的“灵魂”。Ollama管理模型有一套自己的机制,通常我们使用ollama pull deepseek-r1:7b这样的命令在线拉取。在离线环境下,我们需要手动把模型文件“放置”到Ollama期望的目录结构中。
5.1 理解Ollama的模型存储结构
Ollama把模型放在一个固定的目录下,通常是/usr/share/ollama/.ollama/models/。里面有两个关键子目录:
blobs/: 这里存放的是模型最核心的权重文件和数据文件,文件名是长长的SHA256哈希值。manifests/registry.ollama.ai/library/: 这里存放的是模型的“清单”文件,它告诉Ollama某个模型(比如deepseek-r1:7b)对应了blobs目录里的哪几个文件。
我们的离线安装,就是要把从本地Web服务器下载的模型文件,精准地复制到这两个目录的对应位置。
5.2 手动部署离线模型文件
首先,为我们的DeepSeek R1模型创建清单目录,并设置一个“占位符”防止目录被误删。
# 创建模型清单目录
sudo mkdir -p /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/deepseek-r1
# 创建一个空的none文件作为占位符
sudo touch /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/deepseek-r1/none
# 修正目录所有权和权限,确保ollama服务用户有权访问
sudo chown -R ollama:ollama /usr/share/ollama/.ollama/models/manifests
sudo chmod -R 755 /usr/share/ollama/.ollama/models/manifests
接下来,以部署deepseek-r1:7b模型为例,展示如何下载文件。请务必将以下命令中的http://192.168.1.100:8080替换成你的本地Web服务器地址。
# 切换到root用户或使用sudo,以便向系统目录写入文件
sudo -i
# 下载模型清单文件 (7b)
cd /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/deepseek-r1
wget http://192.168.1.100:8080/chfs/shared/deepseek-r1/7b/7b
# 下载该模型对应的所有blob文件 (示例,实际文件名以你的离线包为准)
cd /usr/share/ollama/.ollama/models/blobs
wget http://192.168.1.100:8080/chfs/shared/deepseek-r1/7b/sha256-xxxxxxxxxxxx...
wget http://192.168.1.100:8080/chfs/shared/deepseek-r1/7b/sha256-yyyyyyyyyyyy...
# ... 继续下载该模型所需的所有blob文件
# 退出root shell
exit
# 最后,将下载的所有文件所有权改为ollama用户
sudo chown -R ollama:ollama /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/deepseek-r1/*
sudo chmod -R 644 /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library/deepseek-r1/*
sudo chown -R ollama:ollama /usr/share/ollama/.ollama/models/blobs/*
sudo chmod -R 644 /usr/share/ollama/.ollama/models/blobs/*
对于1.5B、8B、14B等其他版本的模型,操作完全一样,只是下载的清单文件(7b)和对应的blob文件不同。你可以根据服务器硬件能力选择部署一个或多个模型。
5.3 验证与运行模型
所有文件放置妥当后,重启Ollama服务以重新扫描模型库:sudo systemctl restart ollama。
然后,使用Ollama命令行工具检查模型是否已被识别:
ollama list
如果一切顺利,你应该能看到类似 deepseek-r1:7b 的模型名称及其大小出现在列表中。
现在,激动人心的时刻到了,让我们在命令行里和AI对话试试:
ollama run deepseek-r1:7b
程序会加载模型,然后出现 >>> 提示符。你可以直接输入问题,比如“用Python写一个快速排序函数”,然后按回车。模型会开始思考(你会看到“正在思考”或类似提示)并生成回答。按 Ctrl+C 可以中断它的输出,按 Ctrl+D 可以退出当前的对话会话。
6. 部署Open WebUI:打造友好的图形界面
在命令行里对话虽然酷,但对大多数用户来说并不友好。Open WebUI(原名Ollama WebUI)提供了一个非常美观、功能丰富的Web界面,几乎可以看作是ChatGPT的开源替代品,而且它能完美对接我们本地部署的Ollama。
6.1 安装与配置Docker
我们将使用Docker来运行Open WebUI,这是最干净、最易于管理的方式。首先在内网Ubuntu上安装Docker。
# 1. 更新apt包索引
sudo apt update
# 2. 安装必要的依赖包,允许apt通过HTTPS使用仓库
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
# 3. 添加Docker的官方GPG密钥(如果内网有镜像,可替换为内网源地址)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 4. 添加Docker的稳定版仓库(同样,可替换为内网镜像源,如阿里云)
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 5. 再次更新apt包索引,安装Docker引擎
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
# 6. 启动Docker服务并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
# 7. (可选但推荐)将当前用户加入docker组,这样就不用每次都加sudo了
sudo usermod -aG docker $USER
# 执行此命令后,需要注销并重新登录,或者新开一个终端才能生效。
为了加速后续可能从外网拉取其他镜像(虽然本次离线),可以配置国内镜像加速器。创建或修改/etc/docker/daemon.json文件:
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn", "http://hub-mirror.c.163.com"]
}
然后重启Docker:sudo systemctl restart docker。
6.2 加载离线Docker镜像并启动容器
现在,从我们的本地Web服务器获取Open WebUI的Docker镜像压缩包。
# 下载镜像tar包到临时目录
wget -P /tmp http://192.168.1.100:8080/chfs/shared/docker/open-webui.tar
# 将镜像加载到本地的Docker中
sudo docker load -i /tmp/open-webui.tar
# 查看镜像是否加载成功
sudo docker images
# 你应该能看到一个名为 ghcr.io/open-webui/open-webui:main 的镜像
接下来,用一行命令启动Open WebUI容器:
sudo docker run -d \
--name open-webui \
-p 3000:8080 \
-v open-webui-data:/app/backend/data \
--restart always \
ghcr.io/open-webui/open-webui:main
让我解释一下这几个参数:
-d: 后台运行容器。--name open-webui: 给容器起个名字,方便管理。-p 3000:8080: 端口映射。将容器内部的8080端口映射到宿主机的3000端口。你可以把3000改成任何你喜欢的、未被占用的端口(比如80)。-v open-webui-data:/app/backend/data: 数据卷挂载。将容器内应用的数据目录持久化到Docker管理的一个名为open-webui-data的卷中。这样即使容器被删除,你的聊天记录、用户设置等数据也不会丢失。--restart always: 设置容器总是自动重启,即使服务器重启了,这个服务也会自动跑起来。- 最后是镜像名。
如果你的服务器有NVIDIA GPU并已正确安装驱动和nvidia-container-toolkit,可以使用支持GPU的镜像来获得更好的性能:
sudo docker run -d \
--name open-webui \
-p 3000:8080 \
-v open-webui-data:/app/backend/data \
--gpus all \
--restart always \
ghcr.io/open-webui/open-webui:cuda
6.3 配置Open WebUI并连接Ollama
容器启动后,稍等一两分钟让它初始化。然后打开浏览器,访问 http://你的Ubuntu服务器IP:3000。
第一次访问,你会看到Open WebUI的注册页面。创建一个管理员账号。登录后,进入主界面。
关键的一步来了:告诉Open WebUI我们的Ollama在哪里。
- 点击页面左下角的设置图标(齿轮⚙️)。
- 在设置侧边栏中,找到 “连接设置” 或 “Ollama API 配置”。
- 在 “Ollama API 地址” 或 “Ollama Base URL” 输入框中,填写
http://你的Ubuntu服务器IP:11434。注意,这里不能填localhost或127.0.0.1,因为Open WebUI运行在Docker容器内,localhost指的是容器自己,而不是宿主机。必须填写宿主机的实际IP地址。 - 点击 “保存” 或 “测试连接”。如果配置正确,页面通常会提示连接成功,或者你可以在模型选择下拉框中看到我们之前导入的
deepseek-r1:7b等模型。
有时候,首次登录后页面可能会白屏一段时间。这通常是因为Open WebUI默认会尝试连接OpenAI的API来获取一些模型信息,而内网环境无法访问。解决方法是在管理员设置中,找到 “外部链接” 或 “集成” 选项,关闭“OpenAI API” 的开关并保存。如果页面白屏无法操作,可以按照我原始教程里的方法,通过修改其SQLite数据库来关闭这个选项。
6.4 开始你的第一次内网AI对话
现在,一切就绪!在Open WebUI的聊天界面,右上角或模型选择区域,选中 deepseek-r1:7b(或其他你部署的版本)。然后在底部的输入框里,像使用ChatGPT一样开始提问吧。
你可以问它技术问题、让它写代码、总结文档、翻译,或者进行创意写作。所有的计算和推理都发生在你的内网服务器上,数据不出门,安全又放心。Open WebUI还支持对话历史、模型切换、参数调整(如温度、最大生成长度)等高级功能,你可以慢慢探索。
7. 生产环境优化与安全加固建议
一套能跑起来的系统只是开始,要用于企业生产环境,我们还得考虑得更周全一些。这里分享几个我踩过坑后总结的优化和安全建议。
性能优化方面:
- 模型选择: 7B模型在16GB内存的服务器上运行比较流畅。如果服务器内存更大(比如32G+),可以尝试14B或32B模型以获得更强的能力。务必用
htop或nvidia-smi(如果用了GPU)监控资源使用情况。 - Ollama参数调优: 运行模型时,可以通过环境变量或Ollama的Modelfile调整参数。例如,设置
num_ctx(上下文长度)和num_gpu(GPU层数)。对于DeepSeek R1,如果GPU显存不足,可以设置OLLAMA_NUM_GPU=0强制使用CPU,或者设置一个较小的值让部分层使用GPU。 - 使用Docker Compose: 对于多容器应用,建议使用
docker-compose.yml文件来定义和管理Ollama和Open WebUI服务。这能简化启动命令,方便版本控制和一键部署。
安全加固方面:
- 防火墙配置: 服务器上应该启用防火墙(如
ufw),只开放必要的端口(如SSH的22,Open WebUI的3000)。Ollama的11434端口如果只在服务器内部被Open WebUI访问,可以不对外开放,而是在Docker内部通过自定义网络让两个容器互通。# 创建自定义Docker网络 sudo docker network create ai-network # 将Ollama和Open WebUI都连接到这个网络,并在容器内使用容器名互相访问 - Open WebUI访问控制: 务必为Open WebUI设置强密码,并定期更换。如果只有少数人使用,可以考虑在前面加一个Nginx反向代理,配置HTTP Basic认证或集成公司的单点登录(SSO)。
- 定期备份: 定期备份两个关键数据:1) Docker卷
open-webui-data(包含所有用户数据和聊天记录);2) Ollama的模型目录/usr/share/ollama/.ollama/models/。你可以写个简单的脚本用tar打包,然后传到其他存储服务器。 - 日志与监控: 使用
journalctl -u ollama查看Ollama服务日志,使用sudo docker logs open-webui查看容器日志。对于生产系统,建议将日志收集到ELK或Graylog等集中式日志平台,方便问题排查和审计。
8. 常见问题排查与故障恢复
部署过程很难一帆风顺,这里列举几个我遇到过的典型问题及其解决方法。
问题一:Ollama服务启动失败,systemctl status ollama显示错误。
- 可能原因1: 端口11434被占用。用
sudo netstat -tlnp | grep 11434检查。如果被占,可以修改Ollama的监听端口,通过修改/etc/systemd/system/ollama.service文件,在Environment="OLLAMA_HOST=0.0.0.0"下面再加一行Environment="OLLAMA_PORT=11435"(或其他端口),然后重启服务。 - 可能原因2: 模型文件权限不对。确保
/usr/share/ollama/.ollama/models/目录及其下所有文件的所有者是ollama:ollama。
问题二:Open WebUI无法连接到Ollama,提示“Connection refused”或“Failed to fetch models”。
- 检查步骤1: 在Ubuntu服务器本机上运行
curl http://localhost:11434,看Ollama服务是否正常响应。 - 检查步骤2: 如果步骤1正常,但在Open WebUI容器内连接宿主机IP失败。这很可能是Docker的网络问题。确保在启动Open WebUI容器时,使用了
--add-host=host.docker.internal:host-gateway参数(在Linux的Docker较新版本中支持),然后在Open WebUI设置中将Ollama地址设置为http://host.docker.internal:11434。或者,更推荐使用上面提到的自定义Docker网络。
问题三:模型加载非常慢,或者推理时内存/显存溢出(OOM)。
- 对于CPU运行: 确保服务器有足够的物理内存和交换空间(Swap)。对于7B模型,建议至少有16GB可用内存。可以通过
free -h查看。 - 对于GPU运行: 用
nvidia-smi监控显存使用。如果显存不够,可以在运行模型时通过Ollama的--num-gpu参数减少加载到GPU的模型层数,或者换用更小的模型(如1.5B)。
问题四:Open WebUI页面打开缓慢或白屏。
- 主要原因: 如前所述,是初始化时尝试连接外部API(如OpenAI)超时。请确保在设置中关闭了“OpenAI API”选项。如果页面白屏无法操作,需要通过修改其数据库来关闭(参考第6.3节末尾的方法)。
这套基于Ubuntu 22.04 LTS的Ollama + DeepSeek R1 + Open WebUI内网私有化部署方案,我已经在几个对数据安全要求极高的研发团队中成功落地。从最初的摸索到现在的稳定运行,最大的体会就是“规划重于操作”。尤其是在离线环境下,提前准备好所有依赖包,理清楚服务之间的网络连接关系,能避免部署过程中绝大部分的麻烦。希望这份详细的指南能帮你少走弯路,顺利在自家内网搭建起一个安全、可控、高效的AI助手平台。如果在实践中遇到新的问题,不妨多看看服务的日志,那里面通常藏着答案。
更多推荐
所有评论(0)