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

11 KiB
Raw Blame History

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
隔离内容:

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 容器隔离

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 容器隔离

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. 网络隔离

networks:
  ai-learning-network:
    driver: bridge

隔离效果:

  • 独立网络: 容器在独立的 Docker 网络中
  • 服务发现: 容器间通过服务名通信(如 backend:3001
  • 端口隔离: 容器端口不直接暴露给宿主机(除非映射)
  • 安全隔离: 外部无法直接访问容器内部网络

完全隔离的好处

1. 安全性

宿主机 ← 完全隔离 → 应用容器
  • 进程隔离: 容器崩溃不影响宿主机
  • 文件系统隔离: 容器无法访问宿主机敏感文件
  • 网络隔离: 容器间通信受控
  • 权限隔离: 容器以非 root 用户运行(可配置)

2. 环境一致性

开发环境 = 构建环境 = 生产环境
  • 版本一致: 所有环境使用相同的 Node.js 版本
  • 依赖一致: 依赖版本锁定在 package.json
  • 配置一致: Docker 配置统一管理

3. 资源隔离

容器 A ← 资源限制 → 容器 B
  • CPU 限制: 可以限制容器 CPU 使用率
  • 内存限制: 可以限制容器内存使用
  • 磁盘限制: 可以限制容器磁盘使用

4. 易于管理

  • 独立更新: 可以单独更新某个容器,不影响其他
  • 快速回滚: 可以快速回滚到之前的镜像版本
  • 日志隔离: 每个容器的日志独立管理
  • 监控隔离: 可以单独监控每个容器

数据持久化(唯一与宿主机共享的部分)

虽然容器是隔离的,但某些数据需要持久化:

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. 检查容器隔离

# 查看运行中的容器
docker ps

# 查看容器网络
docker network inspect ai-learning-network

# 查看容器进程(在宿主机上)
ps aux | grep nginx  # 看不到容器内的进程

# 进入容器查看
docker exec -it ai-learning-nginx sh
# 在容器内:无法访问宿主机其他文件(除了挂载的 volume

2. 检查网络隔离

# 在宿主机上无法直接访问容器内部网络
curl http://backend:3001  # ❌ 失败backend 只在 Docker 网络内可访问

# 在容器内可以访问
docker exec -it ai-learning-nginx sh
curl http://backend:3001  # ✅ 成功,在同一 Docker 网络内

3. 检查文件系统隔离

# 容器内的文件系统是独立的
docker exec -it ai-learning-backend ls /app
# 只能看到容器内的文件,看不到宿主机其他目录(除了挂载的 volume

安全建议

虽然已经实现了完全隔离,但还可以进一步加强:

1. 使用非 root 用户运行容器

# 在 Dockerfile 中
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001
USER nodejs

2. 限制资源使用

services:
  backend:
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M

3. 只读文件系统(除了必要目录)

services:
  nginx:
    read_only: true
    tmpfs:
      - /tmp
      - /var/cache/nginx

4. 网络策略

services:
  backend:
    networks:
      - ai-learning-network
    # 不暴露端口到宿主机,只允许 nginx 访问
    # ports: []  # 注释掉端口映射

总结

是的,当前架构实现了完全隔离

  1. 构建阶段: 在 Docker 容器中构建,与 Jenkins 服务器隔离
  2. 运行阶段: 应用在 Docker 容器中运行,与宿主机隔离
  3. 网络隔离: 容器在独立的 Docker 网络中
  4. 文件系统隔离: 容器只能访问挂载的 volume
  5. 进程隔离: 容器进程与宿主机进程隔离

唯一与宿主机共享的:

  • 数据文件(数据库、日志)- 通过 volume 挂载
  • 端口映射8080, 3001- 用于外部访问

这种架构提供了最大的安全性和可移植性,同时保持了必要的数据持久化。