ai_learn_node/DOCKER_ISOLATION.md
caoyuchun be1dab20e9 feat: 添加 Jenkins Docker 部署配置
- 添加 Jenkinsfile 和 Jenkinsfile.docker 支持 Docker 构建
- 添加 Docker Compose 生产环境配置
- 添加后端 Dockerfile
- 添加 Docker 部署脚本
- 添加部署文档 (JENKINS_DEPLOY.md, DOCKER_DEPLOY.md, DOCKER_ISOLATION.md)
- 更新 nginx 配置支持生产环境部署
2026-01-14 14:33:58 +08:00

296 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Docker 隔离架构说明
## 隔离层次概览
当前项目实现了**完全隔离**的架构,从构建到运行都在 Docker 容器中,与宿主机完全隔离。
```
┌─────────────────────────────────────────────────────────────┐
│ 宿主机 (Host) │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Jenkins 服务器 │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Docker 容器: node:18 (构建阶段) │ │ │
│ │ │ - 安装依赖 │ │ │
│ │ │ - 构建前端 │ │ │
│ │ │ - 构建后端 │ │ │
│ │ │ ✅ 与 Jenkins 服务器隔离 │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ 部署到远程服务器 │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 远程服务器 (180.76.180.105) │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Docker 容器: nginx:alpine │ │ │
│ │ │ - 端口: 8080:80 │ │ │
│ │ │ - 网络: ai-learning-network │ │ │
│ │ │ ✅ 与宿主机和其他容器隔离 │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ Docker 容器: backend (node:18-alpine) │ │ │
│ │ │ - 端口: 3001:3001 │ │ │
│ │ │ - 网络: ai-learning-network │ │ │
│ │ │ ✅ 与宿主机和其他容器隔离 │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ 宿主机文件系统 (仅数据持久化) │ │ │
│ │ │ - /opt/nginx/html/ai/current/ │ │ │
│ │ │ - 数据库文件 (volume 挂载) │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
## 隔离层次详解
### 1. 构建阶段隔离Jenkins 服务器)
**位置**: Jenkins 服务器
**容器**: `node:18`
**隔离内容**:
```groovy
def nodeImage = docker.image("node:18")
nodeImage.inside('-v /var/run/docker.sock:/var/run/docker.sock') {
// 所有构建操作都在容器中执行
npm install
npm run build
}
```
**隔离效果**:
-**文件系统隔离**: 构建过程不影响 Jenkins 服务器文件系统
-**依赖隔离**: 不需要在 Jenkins 服务器安装 Node.js、npm
-**版本隔离**: 使用固定版本的 Node.js不受宿主机影响
-**环境隔离**: 每次构建都是干净的环境,无历史残留
**好处**:
- Jenkins 服务器保持干净,不需要安装各种构建工具
- 多个项目可以使用不同版本的 Node.js互不干扰
- 构建失败不会影响 Jenkins 服务器
### 2. 运行阶段隔离(生产服务器)
#### 2.1 Nginx 容器隔离
```yaml
nginx:
image: nginx:alpine
container_name: ai-learning-nginx
ports:
- "8080:80"
networks:
- ai-learning-network
```
**隔离效果**:
-**进程隔离**: Nginx 进程在容器内运行,与宿主机进程隔离
-**网络隔离**: 使用独立的 Docker 网络 `ai-learning-network`
-**文件系统隔离**: 只能访问挂载的 volume
-**端口隔离**: 使用 8080 端口,不影响宿主机 80 端口
#### 2.2 Backend 容器隔离
```yaml
backend:
build:
context: /opt/nginx/html/ai/current/backend
dockerfile: Dockerfile
container_name: ai-learning-backend
ports:
- "3001:3001"
networks:
- ai-learning-network
```
**隔离效果**:
-**运行时隔离**: Node.js 应用在容器内运行
-**依赖隔离**: 不需要在宿主机安装 Node.js
-**环境变量隔离**: 容器内独立的环境变量
-**网络隔离**: 只能通过 Docker 网络与其他容器通信
### 3. 网络隔离
```yaml
networks:
ai-learning-network:
driver: bridge
```
**隔离效果**:
-**独立网络**: 容器在独立的 Docker 网络中
-**服务发现**: 容器间通过服务名通信(如 `backend:3001`
-**端口隔离**: 容器端口不直接暴露给宿主机(除非映射)
-**安全隔离**: 外部无法直接访问容器内部网络
## 完全隔离的好处
### 1. 安全性
```
宿主机 ← 完全隔离 → 应用容器
```
-**进程隔离**: 容器崩溃不影响宿主机
-**文件系统隔离**: 容器无法访问宿主机敏感文件
-**网络隔离**: 容器间通信受控
-**权限隔离**: 容器以非 root 用户运行(可配置)
### 2. 环境一致性
```
开发环境 = 构建环境 = 生产环境
```
-**版本一致**: 所有环境使用相同的 Node.js 版本
-**依赖一致**: 依赖版本锁定在 package.json
-**配置一致**: Docker 配置统一管理
### 3. 资源隔离
```
容器 A ← 资源限制 → 容器 B
```
-**CPU 限制**: 可以限制容器 CPU 使用率
-**内存限制**: 可以限制容器内存使用
-**磁盘限制**: 可以限制容器磁盘使用
### 4. 易于管理
-**独立更新**: 可以单独更新某个容器,不影响其他
-**快速回滚**: 可以快速回滚到之前的镜像版本
-**日志隔离**: 每个容器的日志独立管理
-**监控隔离**: 可以单独监控每个容器
## 数据持久化(唯一与宿主机共享的部分)
虽然容器是隔离的,但某些数据需要持久化:
```yaml
volumes:
# 数据库文件(需要持久化)
- /opt/nginx/html/ai/current/backend/prisma:/app/prisma
# 前端静态文件(只读)
- /opt/nginx/html/ai/current:/usr/share/nginx/html:ro
# 日志文件(需要持久化)
- /opt/nginx/html/ai/current/docker/logs:/var/log/nginx
```
**说明**:
- 数据库文件需要持久化,所以挂载到宿主机
- 前端文件是只读挂载,容器无法修改
- 日志文件挂载到宿主机,方便查看和管理
## 隔离验证
### 1. 检查容器隔离
```bash
# 查看运行中的容器
docker ps
# 查看容器网络
docker network inspect ai-learning-network
# 查看容器进程(在宿主机上)
ps aux | grep nginx # 看不到容器内的进程
# 进入容器查看
docker exec -it ai-learning-nginx sh
# 在容器内:无法访问宿主机其他文件(除了挂载的 volume
```
### 2. 检查网络隔离
```bash
# 在宿主机上无法直接访问容器内部网络
curl http://backend:3001 # ❌ 失败backend 只在 Docker 网络内可访问
# 在容器内可以访问
docker exec -it ai-learning-nginx sh
curl http://backend:3001 # ✅ 成功,在同一 Docker 网络内
```
### 3. 检查文件系统隔离
```bash
# 容器内的文件系统是独立的
docker exec -it ai-learning-backend ls /app
# 只能看到容器内的文件,看不到宿主机其他目录(除了挂载的 volume
```
## 安全建议
虽然已经实现了完全隔离,但还可以进一步加强:
### 1. 使用非 root 用户运行容器
```dockerfile
# 在 Dockerfile 中
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
USER nodejs
```
### 2. 限制资源使用
```yaml
services:
backend:
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
```
### 3. 只读文件系统(除了必要目录)
```yaml
services:
nginx:
read_only: true
tmpfs:
- /tmp
- /var/cache/nginx
```
### 4. 网络策略
```yaml
services:
backend:
networks:
- ai-learning-network
# 不暴露端口到宿主机,只允许 nginx 访问
# ports: [] # 注释掉端口映射
```
## 总结
**是的,当前架构实现了完全隔离**
1.**构建阶段**: 在 Docker 容器中构建,与 Jenkins 服务器隔离
2.**运行阶段**: 应用在 Docker 容器中运行,与宿主机隔离
3.**网络隔离**: 容器在独立的 Docker 网络中
4.**文件系统隔离**: 容器只能访问挂载的 volume
5.**进程隔离**: 容器进程与宿主机进程隔离
**唯一与宿主机共享的**:
- 数据文件(数据库、日志)- 通过 volume 挂载
- 端口映射8080, 3001- 用于外部访问
这种架构提供了**最大的安全性和可移植性**,同时保持了必要的数据持久化。