1.8GB 内存也能跑大模型!Ollama Docker 部署完整指南
想在服务器上部署私有 AI 模型,但内存不够用?本文教你用 Docker + Swap 优化,让低配服务器也能流畅运行 Ollama 大模型。
背景
为什么选择 Docker 部署?
因为直接使用命令会报错,无法运行ollama。
![]()
1. 简介
1.1 为什么使用 Docker 部署?
| 优势 | 说明 |
|---|---|
| 环境隔离 | 不污染宿主机环境,依赖问题少 |
| 一键部署 | 容器化部署,跨平台一致性好 |
| 易于管理 | 重启、更新、迁移方便 |
| 资源控制 | 可限制内存、CPU 使用 |
| 适合生产 | 稳定可靠,推荐生产环境使用 |
1.2 硬件要求
| 模型规模 | 内存要求 | 推荐配置 |
|---|---|---|
| 0.5B-3B | 2-4GB | 最低 2GB 可用内存 |
| 7B-14B | 8-16GB | 最低 8GB 可用内存 |
| 30B+ | 32GB+ | 最低 32GB 可用内存 |
1.3 低配服务器(<2GB 内存)
如果你的服务器内存不足(如 1GB-2GB),运行大模型会遇到以下错误:
Error: 500 Internal Server Error: llama runner process has terminated: signal: killed
什么是 Swap?
Swap 是 Linux 系统中的一块硬盘空间,当作"备用内存"使用。当物理内存(RAM)不够用时,系统会把暂时不用的数据从内存搬到 Swap 中,腾出物理内存给需要运行的程序。
┌─────────────────────────────────────────────────┐
│ 物理内存 (RAM) = 你的办公桌(快速但小) │
│ Swap (虚拟内存) = 旁边的储物柜(慢但大) │
│ │
│ 当办公桌放满东西时: │
│ 把不常用的文件 → 放到储物柜 (Swap) │
│ 腾出空间 → 放置正在处理的文件 │
└─────────────────────────────────────────────────┘
Swap 的作用
| 作用 | 说明 |
|---|---|
| 防止系统崩溃 | 内存不足时,用 Swap 补充,避免进程被杀死 |
| 运行大程序 | 允许运行超出物理内存的程序(如大语言模型) |
| 内存回收 | 把不活跃的内存页面移到 Swap,释放物理内存 |
为什么需要 Swap?
你的服务器配置:
- 物理内存:1.8GB
- 想运行:3b 模型(需要 ~4GB 内存)
没有 Swap:
1.8GB < 4GB → 程序被杀死 ❌
有 5GB Swap:
1.8GB + 5GB = 6.8GB > 4GB → 可以运行 ✅
注意:使用 Swap 会牺牲性能(硬盘速度约为内存的 1/100),但总比程序崩溃好。
添加 Swap 虚拟内存
# 创建 4GB swap 文件
dd if=/dev/zero of=/swapfile bs=1M count=4096
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
# 永久生效
echo '/swapfile none swap sw 0 0' >> /etc/fstab
# 验证
free -h
不同内存配置的模型推荐
| 服务器内存 | 推荐模型 | Swap 需求 |
|---|---|---|
| 1GB | qwen2.5-coder:0.5b | 建议 2GB |
| 2GB | qwen2.5-coder:0.5b / 1.5b | 建议 3GB |
| 4GB | qwen2.5-coder:3b | 不需要 |
| 8GB+ | qwen2.5-coder:7b | 不需要 |
Swap 性能判断
| Swap 使用量 | 状态 | 建议 |
|---|---|---|
| 0-500MB | 正常 | 无需处理 |
| 500MB-1GB | 一般 | 注意性能 |
| 1GB-2GB | 较慢 | 考虑换小模型 |
| >2GB | 很慢 | 必须换小模型 |
内存监控命令
# 查看当前内存和 Swap 状态
free -h
# 实时监控内存(每 1 秒刷新)
watch -n 1 free -h
# 查看 Docker 容器资源使用
docker stats ollama
# 查看容器内存限制
docker inspect ollama | grep -i memory
# 查看系统内存配置
cat /proc/sys/vm/overcommit_memory
# 0 = 启发式过度分配(默认)
# 1 = 始终允许过度分配
# 2 = 严格控制,不允许过度分配
运行模型时实时监控
开启两个终端窗口:
终端 1:运行模型
docker exec -it ollama ollama run qwen2.5-coder:0.5b
终端 2:实时监控
watch -n 1 'free -h && echo "---" && docker stats ollama --no-stream'
常见问题排查
问题:模型运行时被杀死
# 1. 检查容器内存限制
docker inspect ollama | grep -i memory
# 2. 如果有内存限制,重新创建容器
docker rm -f ollama
docker run -d \
-p 11434:11434 \
--name ollama \
--restart always \
--memory-swap=-1 \
ollama/ollama:latest
# 3. 启用内存过度分配
echo 1 | sudo tee /proc/sys/vm/overcommit_memory
echo 'vm.overcommit_memory = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# 4. 重启容器
docker restart ollama
问题:Swap 使用过高导致卡顿
# 查看当前 Swap 使用
free -h
# 如果 Swap 使用 > 1GB,建议切换到更小的模型
docker exec -it ollama ollama run qwen2.5-coder:0.5b
2. 安装 Docker
2.1 Ubuntu/Debian
# 一键安装 Docker
curl -fsSL https://get.docker.com | sh
# 将当前用户加入 docker 组(免 sudo)
sudo usermod -aG docker $USER
# 重新登录或执行以下命令使组权限生效
newgrp docker
# 验证安装
docker --version
2.2 CentOS/RHEL
# 安装 Docker
sudo yum install -y docker
# 启动 Docker 服务
sudo systemctl start docker
sudo systemctl enable docker
# 将当前用户加入 docker 组
sudo usermod -aG docker $user
# 验证安装
docker --version
2.3 验证 Docker 安装
# 运行测试容器
docker run hello-world
# 查看 Docker 版本
docker --version
docker info
3. 部署 Ollama 容器
3.1 拉取镜像
# 拉取最新版 Ollama 镜像
docker pull ollama/ollama:latest
# 或指定版本
docker pull ollama/ollama:0.5.7
3.2 启动容器
CPU 模式(默认):
docker run -d \
-p 11434:11434 \
--name ollama \
--restart always \
ollama/ollama:latest
GPU 模式(需要 NVIDIA GPU):
# 首先安装 NVIDIA Container Toolkit
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker
# 启动带 GPU 的容器
docker run -d \
--gpus all \
-p 11434:11434 \
--name ollama \
--restart always \
ollama/ollama:latest
3.3 验证容器运行
# 查看容器状态
docker ps
# 查看容器日志
docker logs -f ollama
# 测试 API
curl http://localhost:11434/api/tags
4. 模型管理
4.1 拉取模型
# 拉取 qwen2.5-coder:3b
docker exec -it ollama ollama pull qwen2.5-coder:3b
# 拉取其他模型
docker exec -it ollama ollama pull qwen2.5:7b
docker exec -it ollama ollama pull deepseek-r1:7b
4.2 查看已安装模型
docker exec -it ollama ollama list
4.3 运行模型(交互式)
docker exec -it ollama ollama run qwen2.5-coder:3b
4.4 删除模型
docker exec -it ollama ollama rm qwen2.5-coder:3b
4.5 推荐模型
| 模型 | 用途 | 内存需求 |
|---|---|---|
qwen2.5-coder:0.5b |
代码生成(轻量) | ~1GB |
qwen2.5-coder:3b |
代码生成(推荐) | ~4GB |
qwen2.5-coder:7b |
代码生成(专业) | ~8GB |
qwen2.5:3b |
通用对话 | ~4GB |
qwen2.5:7b |
通用对话(推荐) | ~8GB |
5. API 调用
5.1 基础调用格式
# 生成文本
curl http://localhost:11434/api/generate -d '{
"model": "qwen2.5-coder:3b",
"prompt": "用python写一个快速排序",
"stream": false
}'
# 对话模式
curl http://localhost:11434/api/chat -d '{
"model": "qwen2.5-coder:3b",
"messages": [
{"role": "user", "content": "你好"}
],
"stream": false
}'
5.2 参数说明
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| model | string | 模型名称 | - |
| prompt | string | 输入文本 | - |
| stream | boolean | 是否流式输出 | true |
| temperature | number | 温度(0-1),越高越随机 | 0.8 |
| num_ctx | number | 上下文长度 | 2048 |
5.3 Python 调用示例
import requests
API_URL = "http://localhost:11434/api/generate"
def call_ollama(prompt: str, model: str = "qwen2.5-coder:3b"):
response = requests.post(API_URL, json={
"model": model,
"prompt": prompt,
"stream": False
})
return response.json()["response"]
# 使用
result = call_ollama("用python写一个快速排序")
print(result)
5.4 JavaScript 调用示例
浏览器环境(原生 Fetch)
// 非流式响应
async function callOllama(prompt) {
const response = await fetch("http://localhost:11434/api/generate", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "qwen2.5-coder:3b",
prompt: prompt,
stream: false
})
});
const data = await response.json();
return data.response;
}
// 使用
callOllama("用python写一个快速排序").then(console.log);
流式响应(浏览器)
async function chatWithOllama(prompt) {
const response = await fetch("http://localhost:11434/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "qwen2.5-coder:3b",
messages: [{ role: "user", content: prompt }],
stream: true
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let result = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split("\n").filter(line => line.trim());
for (const line of lines) {
if (line.startsWith("data: ")) {
const data = line.slice(6);
if (data === "[DONE]") continue;
try {
const json = JSON.parse(data);
const content = json.choices?.[0]?.delta?.content;
if (content) {
result += content;
console.log(content); // 实时输出
}
} catch (e) {
// 忽略解析错误
}
}
}
}
return result;
}
// 使用
chatWithOllama("用python写一个快速排序");
Node.js 环境
const axios = require("axios");
async function callOllama(prompt) {
const response = await axios.post(
"http://localhost:11434/api/generate",
{
model: "qwen2.5-coder:3b",
prompt: prompt,
stream: false
}
);
return response.data.response;
}
// 使用
callOllama("用python写一个快速排序").then(console.log);
带认证的调用
// 如果设置了 API 密钥
async function callOllamaWithAuth(prompt) {
const response = await fetch("http://localhost:11434/api/generate", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer your_api_key_here"
},
body: JSON.stringify({
model: "qwen2.5-coder:3b",
prompt: prompt,
stream: false
})
});
const data = await response.json();
return data.response;
}
5.5 OpenAI 兼容格式(JavaScript)
// 使用 OpenAI SDK 调用 Ollama
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: "http://localhost:11434/v1",
apiKey: "ollama" // 不需要真实 key
});
async function chat(prompt) {
const response = await client.chat.completions.create({
model: "qwen2.5-coder:3b",
messages: [{ role: "user", content: prompt }]
});
return response.choices[0].message.content;
}
// 使用
chat("用python写一个快速排序").then(console.log);
5.6 外网调用示例
// 如果配置了外网访问(需要 HTTPS + API Key)
async function callOllamaRemote(prompt) {
const response = await fetch("https://your-domain.com/api/generate", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer your_secure_password"
},
body: JSON.stringify({
model: "qwen2.5-coder:3b",
prompt: prompt,
stream: false
})
});
const data = await response.json();
return data.response;
}
6. 容器管理
6.1 查看容器状态
# 查看运行中的容器
docker ps
# 查看所有容器(包括停止的)
docker ps -a
# 查看容器详细信息
docker inspect ollama
6.2 日志管理
# 查看实时日志
docker logs -f ollama
# 查看最近 100 行日志
docker logs --tail 100 ollama
# 查看带时间戳的日志
docker logs -t ollama
6.3 启停重启
# 停止容器
docker stop ollama
# 启动容器
docker start ollama
# 重启容器
docker restart ollama
# 删除容器(需先停止)
docker rm -f ollama
6.4 进入容器
# 进入容器 shell
docker exec -it ollama bash
# 在容器中执行命令
docker exec -it ollama ollama list
7. 进阶配置
7.1 持久化模型存储
默认情况下,模型存储在容器内部,删除容器后模型会丢失。使用挂载卷持久化:
# 删除旧容器
docker rm -f ollama
# 重新创建,挂载本地目录
docker run -d \
-p 11434:11434 \
-v ollama_data:/root/.ollama \
--name ollama \
--restart always \
ollama/ollama:latest
7.2 资源限制
# 限制内存使用为 4GB
docker run -d \
-p 11434:11434 \
--memory=4g \
--name ollama \
--restart always \
ollama/ollama:latest
# 限制 CPU 使用
docker run -d \
-p 11434:11434 \
--cpus=2.0 \
--name ollama \
--restart always \
ollama/ollama:latest
7.3 环境变量配置
docker run -d \
-p 11434:11434 \
-e OLLAMA_HOST=0.0.0.0:11434 \
-e OLLAMA_NUM_PARALLEL=4 \
-e OLLAMA_DEBUG=0 \
-v ollama_data:/root/.ollama \
--name ollama \
--restart always \
ollama/ollama:latest
7.4 使用 Docker Compose
创建 docker-compose.yml:
version: '3.8'
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
environment:
- OLLAMA_HOST=0.0.0.0:11434
- OLLAMA_NUM_PARALLEL=4
restart: always
# GPU 配置(需要 nvidia-docker)
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: all
# capabilities: [gpu]
volumes:
ollama_data:
启动:
docker-compose up -d
7.5 国内镜像加速
# 使用国内镜像源
docker pull registry.cn-hangzhou.aliyuncs.com/ollama/ollama:latest
# 或使用代理
docker pull ollama/ollama:latest
8. 故障排查
8.1 容器启动失败
# 查看容器日志
docker logs ollama
# 常见错误:GPU 配置问题
# 解决方案:删除容器,使用 CPU 模式重新创建
docker rm -f ollama
docker run -d -p 11434:11434 --name ollama --restart always ollama/ollama:latest
8.2 无法访问 API
# 检查容器是否运行
docker ps
# 检查端口是否正确映射
docker port ollama
# 测试容器内部 API
docker exec ollama curl http://localhost:11434/api/tags
# 检查防火墙
sudo ufw status # Ubuntu
sudo firewall-cmd --list-all # CentOS
8.3 模型加载慢
# 查看资源使用情况
docker stats ollama
# 检查磁盘 IO
docker exec ollama df -h
8.4 内存不足
# 查看容器资源使用
docker stats --no-stream
# 使用更小的模型
docker exec -it ollama ollama pull qwen2.5-coder:0.5b
# 或限制容器内存
docker update --memory=4g ollama
9. 生产部署建议
9.1 安全配置
# 绑定到本地地址
docker run -d \
-p 127.0.0.1:11434:11434 \
--name ollama \
ollama/ollama:latest
# 使用反向代理(Nginx)配置 HTTPS
9.2 监控配置
# 使用 Prometheus + Grafana 监控
docker run -d \
--name prometheus \
-p 9090:9090 \
prom/prometheus
# 配置 cAdvisor 监控容器
docker run -d \
--name cadvisor \
-p 8080:8080 \
google/cadvisor:latest
9.3 高可用配置
# 使用负载均衡
# 部署多个 Ollama 实例,通过 Nginx 负载均衡
# 使用健康检查
docker run -d \
--name ollama \
--health-cmd="curl -f http://localhost:11434/api/tags || exit 1" \
--health-interval=30s \
--health-timeout=10s \
--health-retries=3 \
ollama/ollama:latest
10. 常用命令速查
# 拉取模型
docker exec -it ollama ollama pull qwen2.5-coder:3b
# 查看模型列表
docker exec -it ollama ollama list
# 运行模型
docker exec -it ollama ollama run qwen2.5-coder:3b
# 查看日志
docker logs -f ollama
# 重启容器
docker restart ollama
# 进入容器
docker exec -it ollama bash
# 删除容器
docker rm -f ollama
# 测试 API
curl http://localhost:11434/api/tags