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 中的路径!

相关推荐
528303 小时前
容器技术入门与Docker环境部署
java·docker·容器
5173 小时前
通过Docker挂载nginx并修改页面
nginx·docker·容器
Fireworkitte10 小时前
如何使用 Dockerfile 创建自定义镜像
运维·docker·容器
Pseudo…14 小时前
容器技术与Docker环境部署
docker·微服务·容器
IT成长日记14 小时前
【Docker基础】Docker镜像管理:docker commit详解
运维·docker·容器·docker commit
IT成长日记14 小时前
【Docker基础】Docker镜像管理:docker build详解
运维·docker·容器·docker build
Byte Beat15 小时前
常用 Docker 命令整理
spring cloud·docker
运维技术分享与探索15 小时前
Centos7.6内网离线安装Docker环境和Portainer-博客
linux·运维·docker·容器·portainer
别骂我h18 小时前
容器技术技术入门与Docker环境部署
java·spring cloud·docker
最不会程序的程序猿18 小时前
docker执行yum报错Could not resolve host: mirrorlist.centos.org
docker·容器·centos