Spring Boot, Mysql, React docker compose 应用的具体示例及代码集合

136 阅读3分钟

Spring Boot, Mysql, React docker compose 示例

Spring Boot, Mysql, React docker compose example

Docker compose可以让你定义和运行多容器的docker应用,该应用不依赖任何其他服务或数据库。

但是,在现实世界中,你会有与数据库交互的应用程序,也会依赖其他服务。因此,从本质上讲,你会有多个容器,它们之间相互作用。

Docker compose让你可以部署和管理涉及多个容器的应用程序。它大大改善了开发和测试的工作流程,你可以快速运行和测试整个堆栈。

注意,Docker compose默认在一台主机上运行所有的容器。但你也可以针对Swarm实例使用compose,在多个主机上运行你的应用程序。

在这篇文章中,你将学习如何使用docker compose在单个主机上运行多容器应用程序。如果你想了解如何在Swarm集群中部署你的应用程序,请查看这篇文章

构建docker镜像

在这篇文章中,我们将运行一个使用Spring Boot、React和MySQL构建的全栈应用。

这是一个投票应用程序,用户可以登录,创建一个投票,并为一个投票投票。

在进行下一步工作之前,请在本地克隆该应用程序。

Spring Boot应用程序的Docker文件

应用程序的后端(polling-app-server)是用Spring Boot编写的。下面是Spring Boot应用的Docker文件。

#### Stage 1: Build the application
FROM openjdk:8-jdk-alpine as build

# Set the current working directory inside the image
WORKDIR /app

# Copy maven executable to the image
COPY mvnw .
COPY .mvn .mvn

# Copy the pom.xml file
COPY pom.xml .

# Build all the dependencies in preparation to go offline. 
# This is a separate step so the dependencies will be cached unless 
# the pom.xml file has changed.
RUN ./mvnw dependency:go-offline -B

# Copy the project source
COPY src src

# Package the application
RUN ./mvnw package -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)

#### Stage 2: A minimal docker image with command to run the app 
FROM openjdk:8-jre-alpine

ARG DEPENDENCY=/app/target/dependency

# Copy project dependencies from the build stage
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app

ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.polls.PollsApplication"]

React应用程序的Docker文件

应用程序的前端(polling-app-client)是用React编写的。我们将在nginx服务器后面部署React应用程序。

以下是React应用程序的Docker文件(它使用同一目录下的nginx.conf。)

#### Stage 1: Build the react application
FROM node:12.4.0-alpine as build

# Configure the main working directory inside the docker image. 
# This is the base directory used in any further RUN, COPY, and ENTRYPOINT 
# commands.
WORKDIR /app

# Copy the package.json as well as the package-lock.json and install 
# the dependencies. This is a separate step so the dependencies 
# will be cached unless changes to one of those two files 
# are made.
COPY package.json package-lock.json ./
RUN npm install

# Copy the main application
COPY . ./

# Arguments
ARG REACT_APP_API_BASE_URL
ENV REACT_APP_API_BASE_URL=${REACT_APP_API_BASE_URL}

# Build the application
RUN npm run build

#### Stage 2: Serve the React application from Nginx 
FROM nginx:1.17.0-alpine

# Copy the react build from Stage 1
COPY --from=build /app/build /var/www

# Copy our custom nginx config
COPY nginx.conf /etc/nginx/nginx.conf

# Expose port 80 to the Docker host, so we can access it 
# from the outside.
EXPOSE 80

ENTRYPOINT ["nginx","-g","daemon off;"]

创建docker-compose.yml配置

为了使用docker compose部署你的应用程序,你需要创建一个docker-compose.yml 文件,其中包含整个堆栈中所有服务的配置。

以下是运行我们的民意调查应用程序的docker-compose.yml 文件。它有三个服务。app-server,app-client, 和dbapp-server 包含后台应用的配置,app-client 包含react应用的配置,而db 是mysql数据库的配置。

# Docker Compose file Reference (https://docs.docker.com/compose/compose-file/)

version: '3.7'

# Define services
services:
  # App backend service
  app-server:
    # Configuration for building the docker image for the backend service
    build:
      context: polling-app-server # Use an image built from the specified dockerfile in the `polling-app-server` directory.
      dockerfile: Dockerfile
    ports:
      - "8080:8080" # Forward the exposed port 8080 on the container to port 8080 on the host machine
    restart: always
    depends_on: 
      - db # This service depends on mysql. Start that first.
    environment: # Pass environment variables to the service
      SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/polls?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
      SPRING_DATASOURCE_USERNAME: callicoder
      SPRING_DATASOURCE_PASSWORD: callicoder     
    networks: # Networks to join (Services on the same network can communicate with each other using their name)
      - backend
      - frontend

  # Frontend Service 
  app-client:
    build:
      context: polling-app-client # Use an image built from the specified dockerfile in the `polling-app-client` directory.
      dockerfile: Dockerfile
      args:
        REACT_APP_API_BASE_URL: http://127.0.0.1:8080/api
    ports:
      - "9090:80" # Map the exposed port 80 on the container to port 9090 on the host machine
    restart: always
    depends_on:
      - app-server
    networks:
      - frontend  

  # Database Service (Mysql)
  db:
    image: mysql:5.7
    ports:
      - "3306:3306"
    restart: always
    environment:
      MYSQL_DATABASE: polls
      MYSQL_USER: callicoder
      MYSQL_PASSWORD: callicoder
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - backend  
  
# Volumes
volumes:
  db-data:

# Networks to be created to facilitate communication between containers
networks:
  backend:
  frontend:    

注意compose文件中的depends_on 关键字。Docker compose将确保在启动服务本身之前先启动服务的所有依赖项。

用docker compose运行完整的堆栈

好了,你现在只需一个命令就可以调出整个应用程序。

$ docker-compose up
Starting spring-security-react-ant-design-polls-app_db_1 ... done
Starting spring-security-react-ant-design-polls-app_app-server_1 ... done
Starting spring-security-react-ant-design-polls-app_app-client_1 ... done

## ...

你看,使用docker compose来运行所有的服务是非常容易的。你的团队中的任何一个新的开发者都可以直接运行这个命令,然后开始玩你的应用程序,而不需要任何设置。

你也可以用docker compose的以下命令一次性停止所有的服务。

$ docker-compose down

这就是所有的人。谢谢您的阅读。