Skip to content

Docker Compose 部署 Vue 项目

Docker Compose 是部署 Vue 项目的理想工具,它可以通过一个简单的 YAML 文件定义和运行多容器应用。下面我将详细介绍如何使用 Docker Compose 部署 Vue 项目,包括基本配置、优化技巧和常见问题的解决方案。

1. 项目准备与基础配置

1.1 创建 Vue 项目

首先确保你已经创建了一个 Vue 项目。如果没有,可以使用 Vue CLI 创建:

bash
npm install -g @vue/cli
vue create my-vue-app
cd my-vue-app

1.2 创建 Dockerfile

在项目根目录下创建Dockerfile,内容如下:

dockerfile
# 构建阶段使用Node镜像
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 生产阶段使用Nginx镜像
FROM nginx:alpine
# 设置时区
ENV TZ=Asia/Shanghai
# 复制Nginx配置文件
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 从构建阶段复制构建好的文件
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

这个 Dockerfile 使用了多阶段构建,第一阶段用 Node 环境构建 Vue 项目,第二阶段用轻量级的 Nginx 镜像运行构建好的静态文件。

1.3 创建 Nginx 配置文件

在项目根目录创建nginx.conf文件:

nginx
server {
    listen 80;
    server_name localhost;

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

这个配置确保 Vue 的路由能正常工作,特别是处理 history 模式的路由。

2. Docker Compose 配置

2.1 基础 docker-compose.yml

在项目根目录创建docker-compose.yml文件:

yaml
version: "3.8"
services:
  vue-app:
    build: .
    container_name: my-vue-app
    ports:
      - "8080:80"
    environment:
      - TZ=Asia/Shanghai
    networks:
      - vue-network
    restart: unless-stopped

networks:
  vue-network:
    driver: bridge

这个配置定义了一个服务vue-app,它会构建当前目录下的 Dockerfile,将容器的 80 端口映射到主机的 8080 端口,并设置了一些基本参数。

2.2 启动项目

运行以下命令构建并启动容器:

bash
docker-compose up --build -d

--build参数确保每次都会重新构建镜像,-d参数让容器在后台运行。

3. 高级配置选项

3.1 添加后端服务

如果你的 Vue 项目需要连接后端 API,可以在 docker-compose.yml 中添加后端服务:

yaml
version: "3.8"
services:
  vue-app:
    build: .
    ports:
      - "8080:80"
    depends_on:
      - api-service
    networks:
      - vue-network

  api-service:
    image: my-api-image
    ports:
      - "3000:3000"
    networks:
      - vue-network

networks:
  vue-network:
    driver: bridge

这样 Vue 应用可以通过服务名api-service访问后端 API。

3.2 开发环境配置

对于开发环境,可以使用挂载卷实现代码热更新:

yaml
version: "3.8"
services:
  vue-app:
    build: .
    ports:
      - "8080:8080"
    volumes:
      - .:/app
      - /app/node_modules
    command: npm run serve
    environment:
      - NODE_ENV=development

这样修改代码后会自动重新编译,无需手动重建容器。

3.3 添加数据库服务

如果需要数据库,可以添加 PostgreSQL 或 MySQL 服务:

yaml
services:
  db:
    image: postgres
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - vue-network

volumes:
  db-data:

记得在 Vue 应用的环境变量中配置数据库连接信息。

4. 常见问题与解决方案

4.1 构建速度慢

  • 问题:每次构建都要重新安装 node_modules
  • 解决方案:在 Dockerfile 中先复制 package.json,安装依赖,再复制其他文件:
dockerfile
COPY package*.json ./
RUN npm install
COPY . .

这样可以更好地利用 Docker 的缓存机制。

4.2 路由问题

  • 问题:刷新页面出现 404
  • 解决方案:确保 Nginx 配置中包含try_files $uri $uri/ /index.html,这是 Vue 路由 history 模式必需的。

4.3 跨域问题

  • 问题:开发时访问 API 出现跨域
  • 解决方案:在 vue.config.js 中配置代理:
javascript
module.exports = {
  devServer: {
    proxy: {
      "/api": {
        target: "http://api-service:3000",
        changeOrigin: true,
      },
    },
  },
};

或者在 Nginx 配置中添加 CORS 头。

5. 生产环境优化

5.1 使用轻量级基础镜像

dockerfile
FROM node:14-alpine AS builder
# ...
FROM nginx:alpine

Alpine 镜像比常规镜像小很多,可以显著减少镜像大小。

5.2 启用 Gzip 压缩

在 nginx.conf 中添加:

nginx
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

这可以减少传输文件大小,提高加载速度。

5.3 设置资源缓存

在 Nginx 配置中添加缓存头:

nginx
location / {
  # ...其他配置
  expires 1y;
  add_header Cache-Control "public";
}

location /index.html {
  add_header Cache-Control "no-cache, no-store, must-revalidate";
}

这样静态资源会被浏览器缓存,而 index.html 不会被缓存。

6. 完整示例

以下是一个完整的生产环境配置示例:

Dockerfile:

dockerfile
FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

nginx.conf:

nginx
server {
    listen 80;
    server_name localhost;
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
        index index.html index.htm;
        expires 1y;
        add_header Cache-Control "public";
    }

    location /index.html {
        add_header Cache-Control "no-cache, no-store, must-revalidate";
    }
}

docker-compose.yml:

yaml
version: "3.8"
services:
  vue-app:
    build: .
    container_name: my-vue-app
    ports:
      - "80:80"
    environment:
      - TZ=Asia/Shanghai
    networks:
      - vue-network
    restart: unless-stopped

networks:
  vue-network:
    driver: bridge

通过以上配置,你可以轻松地使用 Docker Compose 部署 Vue 项目到生产环境。根据你的具体需求,可以调整配置中的参数和选项。