Vue 3 与 Docker 集成

概述

Docker 是一个开源的容器化平台,允许开发者将应用及其依赖打包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以在 Windows 和 macOS 上运行。在 Vue 3 项目中,使用 Docker 可以确保开发、测试和生产环境的一致性,简化部署流程,提高开发效率。

核心知识点

1. Docker 基础

核心概念

  • 镜像 (Image) - 一个只读的模板,用于创建容器
  • 容器 (Container) - 镜像的可运行实例
  • 仓库 (Repository) - 存储镜像的地方
  • Dockerfile - 用于构建镜像的文本文件
  • Docker Compose - 用于定义和运行多容器 Docker 应用的工具
  • Docker Hub - Docker 官方的镜像仓库

Dockerfile 基本结构

# 基础镜像
FROM node:16-alpine

# 设置工作目录
WORKDIR /app

# 复制 package.json 和 package-lock.json
COPY package*.json ./

# 安装依赖
RUN npm ci

# 复制应用代码
COPY . .

# 构建应用
RUN npm run build

# 暴露端口
EXPOSE 8080

# 启动命令
CMD ["npm", "run", "serve"]

2. Vue 3 项目的 Docker 配置

基本 Dockerfile

创建 Dockerfile 文件:

# 阶段 1:构建应用
FROM node:16-alpine as builder

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# 阶段 2:运行应用
FROM nginx:alpine

# 复制构建产物到 Nginx 静态文件目录
COPY --from=builder /app/dist /usr/share/nginx/html

# 复制 Nginx 配置文件
COPY nginx.conf /etc/nginx/conf.d/default.conf

# 暴露端口
EXPOSE 80

# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]

Nginx 配置

创建 nginx.conf 文件:

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    #tcp_nopush on;

    keepalive_timeout 65;

    #gzip on;

    server {
        listen 80;
        server_name localhost;

        location / {
            root /usr/share/nginx/html;
            index index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /usr/share/nginx/html;
        }
    }
}

.dockerignore 文件

创建 .dockerignore 文件,排除不需要复制到镜像中的文件:

node_modules/
dist/
.DS_Store
.env
.env.local
.env.*.local
.git
.gitignore
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
*.log

3. 构建和运行 Docker 镜像

构建镜像

# 构建镜像
docker build -t vue3-docker-app .

# 查看镜像
docker images

运行容器

# 运行容器
docker run -d -p 8080:80 --name vue3-app vue3-docker-app

# 查看运行中的容器
docker ps

# 查看容器日志
docker logs vue3-app

# 进入容器
docker exec -it vue3-app sh

# 停止容器
docker stop vue3-app

# 删除容器
docker rm vue3-app

4. Docker Compose 配置

Docker Compose 用于定义和运行多容器 Docker 应用,适合包含前端、后端、数据库等多个服务的应用。

创建 docker-compose.yml 文件:

version: '3.8'

services:
  frontend:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:80"
    depends_on:
      - backend
    environment:
      - VITE_API_URL=http://backend:3000/api
    restart: unless-stopped
  
  backend:
    build:
      context: ../backend
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:
      - DB_HOST=db
      - DB_PORT=5432
      - DB_USER=postgres
      - DB_PASSWORD=password
      - DB_NAME=vue3_app
    restart: unless-stopped
  
  db:
    image: postgres:14-alpine
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=vue3_app
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  postgres_data:
    driver: local

使用 Docker Compose 运行应用:

# 启动所有服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看服务日志
docker-compose logs -f frontend

# 停止所有服务
docker-compose down

# 重建并启动服务
docker-compose up -d --build

5. 多阶段构建优化

使用多阶段构建可以减小镜像大小:

# 阶段 1:依赖安装
FROM node:16-alpine as deps

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# 阶段 2:构建应用
FROM node:16-alpine as builder

WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# 阶段 3:运行应用
FROM nginx:alpine as runner

COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

6. 环境变量配置

在 Docker 中使用环境变量:

# 在 Dockerfile 中使用 ARG 和 ENV
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

# 构建时传递 ARG
docker build --build-arg NODE_ENV=development -t vue3-app .

# 运行时传递 ENV
docker run -d -e VITE_API_URL=http://api.example.com -p 8080:80 vue3-app

docker-compose.yml 中配置环境变量:

services:
  frontend:
    environment:
      - VITE_API_URL=http://backend:3000/api
      - VITE_APP_NAME=Vue 3 App
      - NODE_ENV=production
    env_file:
      - .env.production

7. 开发环境配置

为开发环境创建专门的 Dockerfile:

# Dockerfile.dev
FROM node:16-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 5173

CMD ["npm", "run", "dev"]

开发环境的 docker-compose.yml

version: '3.8'

services:
  frontend:
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "5173:5173"
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      - VITE_API_URL=http://localhost:3000/api
    restart: unless-stopped

8. Docker 网络配置

Docker 网络允许容器之间通信:

# 创建网络
docker network create vue3-network

# 运行容器时指定网络
docker run -d --network vue3-network --name backend backend-image
docker run -d --network vue3-network -p 8080:80 --name frontend frontend-image

在 Docker Compose 中配置网络:

version: '3.8'

services:
  # ...

networks:
  default:
    name: vue3-network
    driver: bridge

9. Docker 卷配置

Docker 卷用于持久化数据:

# 创建卷
docker volume create vue3-data

# 运行容器时挂载卷
docker run -d -v vue3-data:/app/data app-image

在 Docker Compose 中配置卷:

version: '3.8'

services:
  db:
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
    driver: local

10. 部署到生产环境

标签和版本管理

# 为镜像打标签
docker tag vue3-docker-app your-docker-hub-username/vue3-app:1.0.0
docker tag vue3-docker-app your-docker-hub-username/vue3-app:latest

# 推送镜像到 Docker Hub
docker push your-docker-hub-username/vue3-app:1.0.0
docker push your-docker-hub-username/vue3-app:latest

生产环境最佳实践

  • 使用官方基础镜像
  • 定期更新镜像
  • 使用多阶段构建减小镜像大小
  • 避免在容器中运行 root 用户
  • 配置适当的健康检查
  • 使用 Docker Compose 管理多个服务
  • 配置日志管理
  • 实现自动部署

最佳实践

1. 镜像优化

  • 使用 Alpine 等轻量级基础镜像
  • 使用多阶段构建
  • 最小化镜像层数
  • 清理不必要的依赖和文件
  • 使用 npm ci 替代 npm install
  • 配置适当的 .dockerignore 文件

2. 容器设计

  • 每个容器只运行一个进程
  • 避免在容器中存储数据
  • 使用环境变量配置应用
  • 配置适当的重启策略
  • 实现健康检查
  • 限制容器资源使用

3. 开发工作流

  • 使用 Docker Compose 管理开发环境
  • 挂载代码目录实现热更新
  • 配置开发专用的 Dockerfile
  • 与 CI/CD 集成
  • 自动化测试容器

4. 安全实践

  • 使用官方镜像
  • 定期扫描镜像漏洞
  • 避免在镜像中存储敏感信息
  • 使用 Secrets 管理敏感数据
  • 限制容器权限
  • 配置网络隔离

5. 监控和日志

  • 配置集中式日志管理
  • 实现容器监控
  • 配置告警机制
  • 定期备份数据

常见问题与解决方案

1. 镜像构建失败

问题:Docker 镜像构建失败,出现依赖安装错误。

解决方案

  • 检查 package.jsonpackage-lock.json 是否一致
  • 尝试使用 npm install 替代 npm ci
  • 检查网络连接
  • 清理 Docker 缓存
  • 升级基础镜像版本

2. 容器运行失败

问题:容器运行后立即退出,或者无法访问应用。

解决方案

  • 查看容器日志 docker logs container-name
  • 检查端口映射是否正确
  • 检查应用启动命令
  • 检查环境变量配置
  • 检查依赖服务是否正常运行

3. 开发环境热更新不工作

问题:修改代码后,容器中的应用没有自动更新。

解决方案

  • 确保正确挂载了代码目录
  • 检查开发服务器配置是否支持热更新
  • 检查容器内的文件权限
  • 尝试重启容器

4. 镜像体积过大

问题:构建的 Docker 镜像体积过大。

解决方案

  • 使用多阶段构建
  • 使用轻量级基础镜像
  • 清理不必要的依赖和文件
  • 配置 .dockerignore 文件
  • 避免在镜像中安装开发依赖

5. 容器间通信问题

问题:多个容器之间无法通信。

解决方案

  • 确保容器在同一个网络中
  • 检查服务名称和端口配置
  • 检查防火墙设置
  • 使用容器名称作为 hostname

进阶学习资源

  1. 官方文档

  2. 书籍

    • 《Docker 实战》
    • 《Docker 从入门到实践》
    • 《Vue 3 实战》
  3. 视频教程

  4. 示例项目

  5. 社区资源

实践练习

练习1:配置基本的 Docker 环境

要求

  • 创建一个 Vue 3 项目
  • 配置 Dockerfile
  • 构建镜像并运行容器
  • 访问应用验证

练习2:实现多阶段构建

要求

  • 配置多阶段构建 Dockerfile
  • 比较构建前后的镜像大小
  • 优化镜像体积
  • 测试优化后的镜像

练习3:使用 Docker Compose

要求

  • 配置包含前端和后端的 Docker Compose 项目
  • 实现服务间通信
  • 配置环境变量
  • 测试多服务应用

练习4:开发环境配置

要求

  • 配置开发环境 Dockerfile
  • 实现代码热更新
  • 配置开发专用的环境变量
  • 测试开发工作流

练习5:部署到生产环境

要求

  • 配置生产环境 Dockerfile
  • 推送镜像到 Docker Hub
  • 部署到生产服务器
  • 配置监控和日志

总结

Docker 是 Vue 3 项目中强大的容器化工具,能够帮助开发者确保环境一致性,简化部署流程,提高开发效率。通过本集的学习,你应该掌握了 Docker 的基本概念、Vue 3 项目的 Docker 配置、Docker Compose 的使用以及最佳实践等。

在下一集中,我们将探讨 Vue 3 与 Kubernetes 的集成,敬请期待!

« 上一篇 Vue 3 与 GitHub Actions 集成:实现自动化 CI/CD 流程 下一篇 » 186-vue3-kubernetes-integration