Spring Boot, Mysql, React docker compose 示例
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, 和db 。app-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
这就是所有的人。谢谢您的阅读。
