docker一键部署前后端项目

好的,没问题!我们可以使用 Docker Compose 来一键部署你的 Spring Boot 后端、React 前端和 MySQL 数据库。下面是详细的步骤和项目结构。

这个方案假设:

  • 你的 Spring Boot 项目可以打包成一个可执行的 JAR 文件。
  • 你的 React 项目可以通过 npm run build (或类似命令) 构建成静态文件。

🚀 项目结构

首先,我们来规划一下整个项目的目录结构。建议将你的后端项目、前端项目和 Docker 相关配置文件放在一个统一的父目录下,例如 my-fullstack-app

复制代码
my-fullstack-app/
├── backend/                  # 你的 Spring Boot 后端项目
│   ├── src/
│   │   └── main/
│   │       └── resources/
│   │           └── db.sql    # 你的数据库初始化脚本
│   ├── pom.xml
│   └── Dockerfile            # 后端项目的 Dockerfile
│
├── frontend/                 # 你的 React 前端项目
│   ├── public/
│   ├── src/
│   ├── package.json
│   ├── vite.config.js        # (或其他 Vite 配置文件)
│   └── Dockerfile            # 前端项目的 Dockerfile (用于构建和准备 Nginx)
│
├── mysql/
│   └── init.sql              #  (可选,另一种初始化方式,这里我们会用后端的方式)
│
└── docker-compose.yml        # Docker Compose 配置文件

说明:

  • backend/frontend/ 目录分别存放你已有的 GitHub 项目代码。
  • backend/src/main/resources/db.sql 是你提供的数据库初始化脚本。
  • 我们会在 backend/frontend/ 目录下分别创建一个 Dockerfile
  • docker-compose.yml 是核心的编排文件。

🐳 Dockerfile 配置

接下来,我们为前端和后端应用创建 Dockerfile。

1. 后端 Spring Boot 应用 ( backend/Dockerfile )

这个 Dockerfile 会将你的 Spring Boot 应用打包成一个可执行的 JAR 文件,并运行它。

Dockerfile

复制代码
# 使用一个包含 JDK 的基础镜像
FROM openjdk:17-jdk-slim as builder

# 设置工作目录
WORKDIR /app

# 复制 Maven Wrapper 相关文件 (如果你的项目使用 Maven Wrapper)
COPY .mvn/ .mvn
COPY mvnw .
COPY pom.xml .

# 下载依赖 (利用 Docker 缓存机制)
RUN ./mvnw dependency:go-offline -B

# 复制源代码
COPY src ./src

# 打包应用
RUN ./mvnw package -DskipTests

# ---- 第二阶段:运行阶段 ----
# 使用一个更小的 JRE 镜像来运行应用
FROM openjdk:17-jre-slim

WORKDIR /app

# 从构建阶段复制 JAR 文件
COPY --from=builder /app/target/*.jar app.jar

# 暴露 Spring Boot 应用的端口 (默认为 8080)
EXPOSE 8080

# 运行应用
ENTRYPOINT ["java", "-jar", "app.jar"]

注意:

  • 请确保你的 Spring Boot 项目根目录下有 mvnw (Maven Wrapper)。如果没有,你需要先在你的项目中设置 Maven Wrapper,或者修改 Dockerfile 以使用全局安装的 Maven。
  • openjdk:17-jdk-slimopenjdk:17-jre-slim 是示例,你可以根据你的项目选择合适的 Java 版本。
  • -DskipTests 在构建 Docker 镜像时跳过测试,可以加快构建速度。

2. 前端 React 应用 ( frontend/Dockerfile )

这个 Dockerfile 会分两个阶段:

  1. 构建阶段: 使用 Node.js 环境构建你的 React 应用,生成静态文件。
  2. 运行阶段: 使用 Nginx 镜像来托管这些静态文件。

Dockerfile

复制代码
# ---- 构建阶段 ----
FROM node:18-alpine as builder

# 设置工作目录
WORKDIR /app

# 复制 package.json 和 package-lock.json (或 yarn.lock)
COPY package*.json ./
# 如果使用 yarn
# COPY yarn.lock ./

# 安装依赖
RUN npm install
# 如果使用 yarn
# RUN yarn install

# 复制所有项目文件
COPY . .

# 构建应用
RUN npm run build
# 如果使用 yarn
# RUN yarn build

# ---- 运行阶段 ----
FROM nginx:stable-alpine

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

# 从构建阶段复制构建好的静态文件到 Nginx 的 www 目录
COPY --from=builder /app/dist /usr/share/nginx/html
# 注意: /app/dist 路径可能需要根据你的 Vite build outputDir 配置进行调整

# 暴露 Nginx 端口 (默认为 80)
EXPOSE 80

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

创建 Nginx 配置文件 ( frontend/nginx.conf ):

在你的 frontend 目录下创建一个名为 nginx.conf 的文件,用于配置 Nginx。

Nginx

复制代码
server {
    listen 80;
    server_name localhost;

    root /usr/share/nginx/html;
    index index.html index.htm;

    # 处理 React Router 的路由
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 可以添加其他 Nginx 配置,例如反向代理到后端 API
    # location /api/ {
    #     proxy_pass http://backend:8080/; # "backend" 是 docker-compose.yml 中定义的服务名
    #     proxy_set_header Host $host;
    #     proxy_set_header X-Real-IP $remote_addr;
    #     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    #     proxy_set_header X-Forwarded-Proto $scheme;
    # }
}

注意:

  • node:18-alpine 是一个示例 Node.js 版本,请选择适合你项目的版本。
  • npm run build 是 Vite 项目通常的构建命令,如果你的命令不同,请相应修改。
  • frontend/dist 是 Vite 默认的构建输出目录。如果你的 vite.config.jsbuild.outDir 配置不同,请修改 Dockerfile 中的 COPY --from=builder /app/dist ... 路径。
  • nginx.conf 中的 try_files $uri $uri/ /index.html; 对于单页应用(SPA)很重要,它确保了所有未匹配到静态文件的请求都会 fallback 到 index.html,让 React Router 能够处理路由。
  • nginx.conf 中注释掉的 location /api/ 部分是一个示例,如果你希望通过 Nginx 代理后端的 API 请求 (例如,避免 CORS 问题),可以取消注释并根据需要修改。

🐳 Docker Compose 配置 ( docker-compose.yml )

这是将所有服务(后端、前端、数据库)串联起来的核心文件。

YAML

复制代码
version: '3.8'

services:
  # 后端 Spring Boot 应用
  backend:
    build:
      context: ./backend  # Dockerfile 所在的目录
      dockerfile: Dockerfile
    container_name: my-springboot-app
    ports:
      - "8080:8080"       # 将主机的 8080 端口映射到容器的 8080 端口
    environment:
      # Spring Boot 连接 MySQL 的环境变量
      - SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/mydatabase?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
      - SPRING_DATASOURCE_USERNAME=myuser
      - SPRING_DATASOURCE_PASSWORD=mypassword
      - SPRING_JPA_HIBERNATE_DDL_AUTO=update # 或者 validate, none (如果完全依赖 db.sql)
      # 如果你的 db.sql 包含了创建数据库的语句,并且希望 Spring Boot 等待数据库初始化完成
      # 可以考虑使用 depends_on 的 condition,或者在应用启动脚本中加入等待逻辑
    depends_on:
      db:
        condition: service_healthy # 等待 MySQL 服务健康后再启动后端
    networks:
      - my-app-network

  # 前端 React 应用 (Nginx)
  frontend:
    build:
      context: ./frontend # Dockerfile 所在的目录
      dockerfile: Dockerfile
    container_name: my-react-app
    ports:
      - "80:80"           # 将主机的 80 端口映射到容器的 80 端口 (Nginx)
    depends_on:
      - backend           # 前端可能需要调用后端 API
    networks:
      - my-app-network

  # MySQL 数据库
  db:
    image: mysql:8.0       # 使用官方 MySQL 8.0 镜像
    container_name: my-mysql-db
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: mydatabase
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypassword
      MYSQL_ROOT_PASSWORD: rootpassword # MySQL root 用户密码
    volumes:
      - mysql_data:/var/lib/mysql                     # 数据持久化
      - ./backend/src/main/resources/db.sql:/docker-entrypoint-initdb.d/init.sql # 挂载初始化脚本
    ports:
      - "3306:3306"       # (可选) 将主机的 3306 端口映射到容器的 3306,方便外部工具连接调试
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u$$MYSQL_USER", "-p$$MYSQL_PASSWORD"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s # 给 MySQL 足够的时间启动
    networks:
      - my-app-network

# Docker 网络
networks:
  my-app-network:
    driver: bridge

# Docker 数据卷 (用于持久化 MySQL 数据)
volumes:
  mysql_data:

关键点解释:

  • version: '3.8':指定 Docker Compose 文件格式版本。
  • services: 定义了三个服务:backendfrontenddb
  • backend 服务:
    • build: 指向 backend 目录,并使用该目录下的 Dockerfile 进行构建。
    • ports: 将你本机的 8080 端口映射到容器的 8080 端口。
    • environment: 设置 Spring Boot 连接数据库所需的环境变量。
      • SPRING_DATASOURCE_URL: JDBC 连接字符串。注意 db:3306 中的 db 是下面定义的 MySQL 服务的名称,Docker Compose 会在内部网络中解析它。mydatabase 是你希望创建的数据库名。
      • SPRING_DATASOURCE_USERNAMESPRING_DATASOURCE_PASSWORD: 与 MySQL 服务中设置的用户名和密码一致。
      • SPRING_JPA_HIBERNATE_DDL_AUTO: 控制 Hibernate 如何处理数据库 schema。update 会在启动时根据实体类更新表结构,如果你的 db.sql 已经完整定义了表结构,可以考虑设置为 validate (只验证) 或 none (不做任何操作)。
    • depends_on.db.condition: service_healthy: 确保后端服务在 MySQL 服务完全启动并健康后才启动。这对于依赖数据库初始化的应用很重要。
  • frontend 服务:
    • build: 指向 frontend 目录,并使用该目录下的 Dockerfile 进行构建。
    • ports: 将你本机的 80 端口映射到容器的 80 端口(Nginx 默认端口)。
    • depends_on: - backend: 表示前端服务依赖后端服务。这不是强制的,但如果你在 Nginx 配置中设置了反向代理到后端,这样写更清晰。
  • db 服务:
    • image: mysql:8.0: 使用官方的 MySQL 8.0 镜像。
    • restart: unless-stopped: 除非手动停止,否则容器总会自动重启。
    • environment:
      • MYSQL_DATABASE: 当容器第一次启动时,会自动创建名为 mydatabase 的数据库。
      • MYSQL_USERMYSQL_PASSWORD: 创建一个具有指定用户名和密码的用户,并授予其对 mydatabase 的所有权限。
      • MYSQL_ROOT_PASSWORD: 设置 MySQL 的 root 用户密码。
    • volumes:
      • mysql_data:/var/lib/mysql: 将 MySQL 的数据存储目录挂载到宿主机的 Docker volume mysql_data 上,这样即使容器被删除,数据也不会丢失。
      • ./backend/src/main/resources/db.sql:/docker-entrypoint-initdb.d/init.sql: 这是关键的一步 。MySQL 镜像在第一次启动时,会自动执行 /docker-entrypoint-initdb.d/ 目录下的所有 .sh, .sql, .sql.gz 文件。我们将你的 db.sql 挂载到这个目录,MySQL 就会用它来初始化表结构和数据。
    • ports: (可选) 将主机的 3306 端口映射到容器的 3306,方便你使用本地的数据库客户端 (如 DBeaver, DataGrip, MySQL Workbench) 连接到 Docker 中的 MySQL 进行调试。生产环境中不建议直接暴露数据库端口到公网。
    • healthcheck: 定义了如何检查 MySQL 服务是否健康。这与 backend 服务的 depends_on.condition 配合使用。
  • networks:
    • my-app-network: 创建一个自定义的桥接网络,让所有服务都在同一个网络中,可以通过服务名相互通信(例如,后端可以通过 db:3306 连接 MySQL)。
  • volumes:
    • mysql_data: 定义一个命名的 volume,用于持久化 MySQL 数据。

🛠️ 部署步骤

  1. 准备代码:

    • 将你的后端 Spring Boot 项目代码放到 my-fullstack-app/backend/ 目录下。
    • 确保后端项目的 src/main/resources/ 目录下有 db.sql 文件。
    • 将你的前端 React 项目代码放到 my-fullstack-app/frontend/ 目录下。
  2. 创建 Dockerfile:

    • my-fullstack-app/backend/ 目录下创建上面提供的 Dockerfile
    • my-fullstack-app/frontend/ 目录下创建上面提供的 Dockerfilenginx.conf 文件。
  3. 创建 docker-compose.yml:

    • my-fullstack-app/ (项目根目录) 下创建上面提供的 docker-compose.yml 文件。
  4. 修改配置 (重要):

    • 后端 Dockerfile: 检查 Java 版本,Maven Wrapper 是否正确。
    • 前端 Dockerfile : 检查 Node.js 版本,构建命令 (npm run build),以及 Vite 的输出目录 (dist)是否与你的项目一致。
    • docker-compose.yml :
      • 数据库凭证 : 修改 db 服务和 backend 服务中的 MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD, MYSQL_ROOT_PASSWORD 以及 SPRING_DATASOURCE_USERNAME, SPRING_DATASOURCE_PASSWORD请务必使用强密码!
      • 后端数据库连接 URL : 确保 SPRING_DATASOURCE_URL 中的数据库名 (mydatabase) 与 db 服务中 MYSQL_DATABASE 的值一致。
      • 端口映射 : 如果你本机的 808080 端口已被占用,可以修改 ports 部分的左侧端口号 (例如 8081:80)。
  5. 构建并启动服务:

    • 打开终端 (命令行工具)。

    • 进入到 my-fullstack-app/ 目录。

    • 执行以下命令:

      Bash

      复制代码
      docker-compose up --build
      • --build: 这个参数会强制 Docker Compose 在启动服务前重新构建镜像。第一次运行时是必需的,之后如果你的代码或 Dockerfile 没有改变,可以省略 --build 直接使用 docker-compose up
      • Docker Compose 会按照依赖顺序依次构建和启动 dbbackendfrontend 服务。
      • 你会看到很多日志输出,包括数据库的初始化、Spring Boot 应用的启动、Nginx 的启动等。
  6. 访问应用:

    • 前端 : 打开浏览器,访问 http://localhost (或者你在 docker-compose.yml 中为 frontend 服务映射的主机端口,例如 http://localhost:8081 如果你改了端口)。
    • 后端 API : 如果你直接暴露了后端端口,可以访问 http://localhost:8080 (或者你映射的后端端口)。通常前端会通过 Nginx 代理或者直接请求这个地址。
    • 数据库 : 如果你映射了数据库的 3306 端口,可以使用数据库客户端连接到 localhost:3306,用户名为 myuser,密码为 mypassword (或你设置的值),数据库为 mydatabase
  7. 查看日志:

    • 如果你想看特定服务的日志,可以打开新的终端窗口,执行: Bash

      复制代码
      docker-compose logs -f backend  # 查看后端日志
      docker-compose logs -f frontend # 查看前端 (Nginx) 日志
      docker-compose logs -f db       # 查看数据库日志

      -f 参数表示持续跟踪日志输出。

  8. 停止服务:

    • 在运行 docker-compose up 的终端中,按 Ctrl + C

    • 或者,在项目目录下打开新的终端,执行: Bash

      复制代码
      docker-compose down

      这个命令会停止并移除容器。如果希望移除数据卷 (删除 MySQL 数据),可以执行 docker-compose down -v


💡 一些额外的提示

  • 环境变量管理 : 对于敏感信息(如数据库密码),在生产环境中更好的做法是使用 .env 文件或 Docker Secrets 来管理,而不是直接写在 docker-compose.yml 文件中。

    • my-fullstack-app/ 目录下创建一个 .env 文件,例如: 代码段

      复制代码
      MYSQL_USER_ENV=myuser
      MYSQL_PASSWORD_ENV=mypassword
      MYSQL_DATABASE_ENV=mydatabase
      MYSQL_ROOT_PASSWORD_ENV=rootpassword
    • 然后在 docker-compose.yml 中引用这些变量: YAML

      复制代码
      # ...
      environment:
        MYSQL_DATABASE: ${MYSQL_DATABASE_ENV}
        MYSQL_USER: ${MYSQL_USER_ENV}
        MYSQL_PASSWORD: ${MYSQL_PASSWORD_ENV}
        MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD_ENV}
      # ...
      environment:
        - SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/${MYSQL_DATABASE_ENV}?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
        - SPRING_DATASOURCE_USERNAME=${MYSQL_USER_ENV}
        - SPRING_DATASOURCE_PASSWORD=${MYSQL_PASSWORD_ENV}
      # ...
  • Spring Boot application.properties / application.yml : 确保你的 Spring Boot 应用的配置文件 (application.propertiesapplication.yml) 使用了环境变量来配置数据库连接信息,例如: application.properties:

    Properties

    复制代码
    spring.datasource.url=${SPRING_DATASOURCE_URL}
    spring.datasource.username=${SPRING_DATASOURCE_USERNAME}
    spring.datasource.password=${SPRING_DATASOURCE_PASSWORD}
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.jpa.hibernate.ddl-auto=${SPRING_JPA_HIBERNATE_DDL_AUTO:update}

    application.yml:
    YAML

    复制代码
    spring:
      datasource:
        url: ${SPRING_DATASOURCE_URL}
        username: ${SPRING_DATASOURCE_USERNAME}
        password: ${SPRING_DATASOURCE_PASSWORD}
        driver-class-name: com.mysql.cj.jdbc.Driver
      jpa:
        hibernate:
          ddl-auto: ${SPRING_JPA_HIBERNATE_DDL_AUTO:update}

    这样 docker-compose.yml 中设置的环境变量才能被 Spring Boot 应用正确读取。

  • 开发与生产:

    • 这里的配置是一个基础的部署方案。对于生产环境,你可能还需要考虑更复杂的 Nginx 配置 (HTTPS, 缓存, 限流等)、日志收集、监控、更安全的密钥管理等。
    • 你也可以为开发环境和生产环境创建不同的 docker-compose.override.yml 文件来覆盖或扩展基础配置。
  • Maven Wrapper : 如果你的 Spring Boot 项目没有 mvnw.mvn 目录,请先在你的项目根目录下运行 mvn -N io.takari:maven:wrapper (或者根据你的 Maven 版本使用 mvn wrapper:wrapper) 来生成它们。

这个指南应该能帮助你顺利地用 Docker Compose 部署你的全栈应用!如果在过程中遇到任何问题,随时可以提出来。

我需要2个项目都从github拉取。 不是已经拉取好的

显示思路

好的,如果你的项目代码托管在 GitHub 上的公共仓库,我们可以修改 Dockerfile,让 Docker 在构建镜像的过程中直接从 GitHub 拉取最新的代码。

这样做的好处是,你本地只需要保留 Docker 相关的文件 (Dockerfile, docker-compose.yml, nginx.conf 等),代码总是从 GitHub 获取。

下面是更新后的方案:


🚀 项目结构 (更新后)

你的本地项目结构会变得更简洁:

复制代码
my-fullstack-app/
├── backend/                  # 存放后端项目的 Dockerfile
│   └── Dockerfile
│
├── frontend/                 # 存放前端项目的 Dockerfile 和 Nginx 配置
│   ├── Dockerfile
│   └── nginx.conf
│
├── db_init/                  # 存放数据库初始化脚本
│   └── db.sql                # 你需要手动将后端的 db.sql 放到这里
│
└── docker-compose.yml        # Docker Compose 配置文件

重要说明:

  • backend/frontend/ 目录现在只包含各自的 Dockerfile (前端目录还包含 nginx.conf)。实际的应用代码将在 Docker 镜像构建时从 GitHub 克隆。
  • db_init/db.sql : 因为 MySQL 服务需要在启动时访问 db.sql,而此时后端代码可能还没被克隆到 Docker 镜像中,所以你需要手动将你的 db.sql 文件(从你的后端 GitHub 仓库的 src/main/resources/db.sql 或相应位置获取)放到这个 db_init 目录下

🐳 Dockerfile 配置 (从 GitHub 拉取)

1. 后端 Spring Boot 应用 ( backend/Dockerfile )

这个 Dockerfile 会先安装 git,然后克隆你的 GitHub 仓库,最后再构建 Spring Boot 应用。

Dockerfile

复制代码
# 使用一个包含 JDK 和 Git 的基础镜像
FROM openjdk:17-jdk-slim as builder

# 安装 git
RUN apt-get update && apt-get install -y git

# 定义 GitHub 仓库 URL 和分支的参数 (可以在 docker-compose.yml 中设置)
ARG GIT_REPO_URL
ARG GIT_BRANCH=main  # 默认使用 main 分支

WORKDIR /app

# 克隆指定的仓库和分支
RUN git clone --branch ${GIT_BRANCH} ${GIT_REPO_URL} .
# 如果克隆失败,打印错误信息并退出
# RUN git clone --branch ${GIT_BRANCH} ${GIT_REPO_URL} . || { echo "Git clone failed"; exit 1; }


# -- 下面的步骤假设你的 Spring Boot 项目结构和之前一样 --
# -- 确保 pom.xml, .mvn 目录在克隆下来的项目的根目录下 --

# 复制 Maven Wrapper 相关文件 (如果你的项目使用 Maven Wrapper)
# 注意:这里的路径是相对于克隆下来的项目根目录
COPY .mvn/ .mvn
COPY mvnw .
COPY pom.xml .

# 下载依赖 (利用 Docker 缓存机制)
# 如果你的 pom.xml 不在仓库根目录,需要调整这里的路径
# 例如,如果项目在 'my-backend-app' 子目录:
# WORKDIR /app/my-backend-app
# RUN ./mvnw dependency:go-offline -B
RUN ./mvnw dependency:go-offline -B

# 复制源代码 (这一步其实在 git clone 后已经完成了整个项目代码的复制)
# 所以,如果 pom.xml 和 src 在克隆后的 /app 目录下,这里不需要额外复制 src
# COPY src ./src

# 打包应用 (确保在正确的目录下执行)
RUN ./mvnw package -DskipTests

# ---- 第二阶段:运行阶段 ----
FROM openjdk:17-jre-slim

WORKDIR /app

# 从构建阶段复制 JAR 文件
# 注意:这里的路径可能需要根据你的 target 目录和 JAR 文件名调整
# 通常是 target/*.jar,如果你的仓库名或模块名影响了路径,需要确认
COPY --from=builder /app/target/*.jar app.jar

# 暴露 Spring Boot 应用的端口 (默认为 8080)
EXPOSE 8080

# 运行应用
ENTRYPOINT ["java", "-jar", "app.jar"]

重要修改和说明:

  • FROM openjdk:17-jdk-slim as builder: 确保基础镜像可以安装 git。slim 版本可能不带,所以用 apt-get install -y git
  • ARG GIT_REPO_URL: 定义一个构建参数,用于接收你的后端 GitHub 仓库 URL。
  • ARG GIT_BRANCH=main: 定义一个构建参数,用于接收分支名,默认为 main
  • RUN git clone --branch ${GIT_BRANCH} ${GIT_REPO_URL} .: 克隆仓库到当前工作目录 (/app)。. 表示克隆到当前目录。
  • 路径调整 : git clone 之后,你的所有项目文件 (包括 pom.xml, .mvn, mvnw, src) 都会在 /app 目录下。确保后续的 COPYRUN ./mvnw 命令的路径是正确的。如果你的 Spring Boot 项目本身在一个子目录内(例如,仓库根目录不是直接的 Maven 项目根目录),你需要调整 WORKDIRCOPYRUN 命令中的路径。例如,如果项目在克隆下来的 my-actual-project-folder 子目录中,你可能需要 WORKDIR /app/my-actual-project-folder
  • db.sql 的位置 : 这个 Dockerfile 不再直接处理 db.sqldb.sql 会被克隆到镜像中,但我们使用上面提到的 db_init/db.sql 方案来初始化数据库。

2. 前端 React 应用 ( frontend/Dockerfile )

类似地,前端的 Dockerfile 也会先安装 git 并克隆仓库。

Dockerfile

复制代码
# ---- 构建阶段 ----
FROM node:18-alpine as builder

# 安装 git
RUN apk add --no-cache git

# 定义 GitHub 仓库 URL 和分支的参数
ARG GIT_REPO_URL
ARG GIT_BRANCH=main # 默认使用 main 分支

WORKDIR /app

# 克隆指定的仓库和分支
RUN git clone --branch ${GIT_BRANCH} ${GIT_REPO_URL} .
# RUN git clone --branch ${GIT_BRANCH} ${GIT_REPO_URL} . || { echo "Git clone failed"; exit 1; }

# -- 下面的步骤假设你的 React 项目结构和之前一样 --
# -- 确保 package.json 在克隆下来的项目的根目录下 --

# 复制 package.json 和 package-lock.json (或 yarn.lock)
# 注意:这里的路径是相对于克隆下来的项目根目录
COPY package*.json ./
# 如果使用 yarn
# COPY yarn.lock ./

# 安装依赖 (确保在正确的目录下执行)
RUN npm install
# 如果使用 yarn
# RUN yarn install

# 复制所有项目文件 (这一步其实在 git clone 后已经完成了整个项目代码的复制)
# COPY . .

# 构建应用 (确保在正确的目录下执行)
RUN npm run build
# 如果使用 yarn
# RUN yarn build

# ---- 运行阶段 ----
FROM nginx:stable-alpine

# 复制 Nginx 配置文件 (这个文件还是从本地的 frontend 目录复制)
COPY nginx.conf /etc/nginx/conf.d/default.conf

# 从构建阶段复制构建好的静态文件到 Nginx 的 www 目录
# 注意: /app/dist 路径可能需要根据你的 Vite build outputDir 配置进行调整
# 这个路径是相对于克隆后项目构建的输出路径
COPY --from=builder /app/dist /usr/share/nginx/html

# 暴露 Nginx 端口 (默认为 80)
EXPOSE 80

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

重要修改和说明:

  • FROM node:18-alpine as builder: alpine 版本的 Node 镜像通常不带 git,所以用 apk add --no-cache git 安装。
  • ARG GIT_REPO_URLARG GIT_BRANCH: 与后端类似,用于接收前端 GitHub 仓库 URL 和分支。
  • RUN git clone ...: 克隆前端仓库。
  • 路径调整 : 同样,确保 package.json 等文件以及 npm install, npm run build 命令在克隆下来的项目根目录或正确的子目录中执行。Vite 构建的输出目录 (dist) 路径也需要正确。
  • COPY nginx.conf ...: nginx.conf 文件仍然从你本地的 frontend/ 目录复制,因为它不是项目代码的一部分,而是部署配置文件。

Nginx 配置文件 (frontend/nginx.conf)

这个文件保持不变,和之前提供的一样。

Nginx

复制代码
server {
    listen 80;
    server_name localhost;

    root /usr/share/nginx/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ /index.html;
    }

    # 如果你需要通过 Nginx 代理 API 请求到后端
    # location /api/ {
    #     proxy_pass http://backend:8080/; # "backend" 是 docker-compose.yml 中定义的服务名
    #     proxy_set_header Host $host;
    #     proxy_set_header X-Real-IP $remote_addr;
    #     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    #     proxy_set_header X-Forwarded-Proto $scheme;
    # }
}

🐳 Docker Compose 配置 ( docker-compose.yml ) (更新后)

现在我们需要在 docker-compose.ymlbuild 部分传递 GitHub 仓库的 URL 和分支名给 Dockerfile。

YAML

复制代码
version: '3.8'

services:
  # 后端 Spring Boot 应用
  backend:
    build:
      context: ./backend  # Dockerfile 所在的目录
      dockerfile: Dockerfile
      args:
        # 替换为你的后端 GitHub 仓库 URL
        GIT_REPO_URL: https://github.com/YOUR_USERNAME/YOUR_BACKEND_REPO.git
        # GIT_BRANCH: your-feature-branch # 如果不是 main/master,取消注释并修改
    container_name: my-springboot-app
    ports:
      - "8080:8080"
    environment:
      - SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/mydatabase?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
      - SPRING_DATASOURCE_USERNAME=myuser
      - SPRING_DATASOURCE_PASSWORD=mypassword
      - SPRING_JPA_HIBERNATE_DDL_AUTO=update # 或者 validate, none
    depends_on:
      db:
        condition: service_healthy
    networks:
      - my-app-network

  # 前端 React 应用 (Nginx)
  frontend:
    build:
      context: ./frontend # Dockerfile 所在的目录
      dockerfile: Dockerfile
      args:
        # 替换为你的前端 GitHub 仓库 URL
        GIT_REPO_URL: https://github.com/YOUR_USERNAME/YOUR_FRONTEND_REPO.git
        # GIT_BRANCH: your-feature-branch # 如果不是 main/master,取消注释并修改
    container_name: my-react-app
    ports:
      - "80:80"
    depends_on:
      - backend
    networks:
      - my-app-network

  # MySQL 数据库
  db:
    image: mysql:8.0
    container_name: my-mysql-db
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: mydatabase
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypassword
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - mysql_data:/var/lib/mysql
      # 关键:从本地的 db_init 目录挂载初始化脚本
      - ./db_init/db.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "3306:3306" # (可选) 方便本地调试
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u$$MYSQL_USER", "-p$$MYSQL_PASSWORD"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    networks:
      - my-app-network

networks:
  my-app-network:
    driver: bridge

volumes:
  mysql_data:

关键修改和说明:

  • build.args :
    • backendfrontend 服务的 build 配置下,我们添加了 args
    • GIT_REPO_URL: 你必须将 https://github.com/YOUR_USERNAME/YOUR_BACKEND_REPO.githttps://github.com/YOUR_USERNAME/YOUR_FRONTEND_REPO.git 替换为你自己项目的实际 GitHub URL。
    • GIT_BRANCH: 如果你想拉取特定分支而不是默认的 main (或 master),取消注释并修改这一行。
  • db.volumes :
    • ./db_init/db.sql:/docker-entrypoint-initdb.d/init.sql: 这里明确了 MySQL 服务会从你本地项目根目录下的 db_init/db.sql 文件加载初始化脚本。

🛠️ 部署步骤 (更新后)

  1. 准备本地项目结构:

    • 创建父目录 my-fullstack-app/
    • my-fullstack-app/ 下创建 backend/ 目录,并在其中放入更新后的后端 Dockerfile
    • my-fullstack-app/ 下创建 frontend/ 目录,并在其中放入更新后的前端 Dockerfilenginx.conf 文件。
    • my-fullstack-app/ 下创建 db_init/ 目录。从你的后端 GitHub 仓库中获取 db.sql 文件 (通常在 src/main/resources/db.sql),并将其放入 my-fullstack-app/db_init/ 目录下。
  2. 创建 docker-compose.yml:

    • my-fullstack-app/ (项目根目录) 下创建上面提供的 docker-compose.yml 文件。
  3. 修改配置 (重要):

    • docker-compose.yml :
      • GitHub 仓库 URL : 在 backendfrontend 服务的 build.args 部分,将 GIT_REPO_URL 的值更新为你的实际 GitHub 仓库地址。如果需要,也设置 GIT_BRANCH
      • 数据库凭证 : 检查并修改 db 服务和 backend 服务中的数据库相关环境变量 (MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD, MYSQL_ROOT_PASSWORD, SPRING_DATASOURCE_USERNAME, SPRING_DATASOURCE_PASSWORD)。
      • 端口映射: 如果需要,调整端口。
    • Dockerfile (后端和前端) :
      • 仔细检查 git clone 后的文件路径是否与 mvnwpom.xmlpackage.json、构建命令 (mvn package, npm run build) 以及最终产物 (JAR 文件, dist 目录) 的路径一致。如果你的 GitHub 仓库的根目录不是 Maven/NPM 项目的根目录 (例如,代码在一个子文件夹里),你需要在 Dockerfile 中调整 WORKDIR 或者相关命令的路径。

      • 例如,如果后端代码在克隆下来的仓库中的 project-subfolder/ 目录下: Dockerfile

        复制代码
        # backend/Dockerfile
        # ...
        RUN git clone --branch ${GIT_BRANCH} ${GIT_REPO_URL} repo_code
        WORKDIR /app/repo_code/project-subfolder # 进入实际项目目录
        # 现在 ./mvnw, pom.xml 等应该能被找到
        RUN ./mvnw dependency:go-offline -B
        RUN ./mvnw package -DskipTests
        # ...
        COPY --from=builder /app/repo_code/project-subfolder/target/*.jar app.jar
  4. 构建并启动服务:

    • 打开终端,进入 my-fullstack-app/ 目录。

    • 运行: Bash

      复制代码
      docker-compose up --build

      Docker 会先为后端和前端构建镜像,这个过程会包括从 GitHub 克隆代码。然后启动所有服务。

  5. 访问和管理服务:

    • 访问方式、查看日志、停止服务等步骤与之前的指南相同。
      • 前端: http://localhost (或你映射的端口)
      • 后端: http://localhost:8080 (或你映射的端口)

这个方案通过在 Docker 构建时动态拉取代码,使得部署更加自动化,本地依赖更少。记得仔细替换 URL 和检查 Dockerfile 中的路径!

相关推荐
mqiqe6 小时前
vue发版html 生成打包到docker镜像进行发版
vue.js·docker·html
foundbug9996 小时前
docker运行centos提示Operation not permitted
docker·容器·centos
超級二蓋茨7 小时前
CentOS中安装Docker Compose
linux·docker·centos
AIGC_北苏8 小时前
Windows安装Docker部署dify,接入阿里云api-key进行rag测试
docker·容器·qwen·dify
CodeWithMe8 小时前
【C/C++】基于 Docker 容器运行的 Kafka + C++ 练手项目
c语言·c++·docker
iceland911 小时前
Docker安装
运维·docker·容器
HakunamatataWang11 小时前
meilisearch docker 简单安装
docker·elastic·melisearch
郁大锤12 小时前
Docker容器启动失败的常见原因分析
运维·docker·容器
AA-代码批发V哥12 小时前
Docker常用命令操作指南(一)
docker
安顾里13 小时前
Dockerfile 构建优化的方法
docker·容器·性能优化