去年这个时候写的JavaWeb选课系统迄今为止已经被我用来交了三次课设了虽然写的依托答辩,但每次都不想写一个新的(:-
这次受到了discourse-docker
项目的启发,想尝试把build-deploy放进docker里面,这样只需要一行命令就可以部署项目+数据库了
感觉这样搞发给别人用确实很方便,但自己用每次都吃不到manven缓存,想搞个reproduceable的环境不如nix-devshell
Approach
首先我们需要两个容器,一个运行数据库,一个运行app,运行多个容器就需要docker-compose
了 而运行webapp的容器需要先build和deploy,就需要一个dockerfile
了
DockerFile
- 其实很简单,它分为两个阶段:构建阶段和部署阶段。我使用多阶段构建来优化镜像大小和构建过程
- 在构建阶段选择基础镜像以后复制settings.xml->这个有点坑,我想让maven吃缓存,但是直接设置环境变量没有用,只能复制settings.xml
- 然后就是复制
pom.xml,src/**
并编译
- 复制构建结果&&启动应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| FROM maven:3.9.9-amazoncorretto-17-debian-bookworm AS build COPY settings.xml /root/.m2/settings.xml
WORKDIR /app
COPY pom.xml . COPY src ./src
RUN mvn clean package
FROM openjdk:24-ea-17-oraclelinux9 WORKDIR /app
COPY --from=build /app/target/CourseSelect-0.1.0-Release.jar app.jar
EXPOSE 80 443
ENTRYPOINT ["java", "-jar", "app.jar"]
|
Docker Compose
- 将本地的 table-with-procedure.sql 文件挂载到容器的 /docker-entrypoint-initdb.d/init.sql 路径。MySQL 容器启动时会自动执行该 SQL 文件,用于初始化数据库表或存储过程。
- 将 MySQL 服务连接到名为 network 的 Docker 网络。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| version: '3' services: mysql: image: mysql:8.0 container_name: mysql-container environment: MYSQL_ROOT_PASSWORD: 123456 ports: - "3306:3306" volumes: - ./table-with-procedure.sql:/docker-entrypoint-initdb.d/init.sql networks: - network
webapp: build: context: . dockerfile: Dockerfile.webapp container_name: webapp-container ports: - "80:80" environment: - DB_URL=jdbc:mysql://mysql-container:3306/courseSelect - DB_USERNAME=root - DB_PASSWORD=123456 depends_on: - mysql networks: - network
networks: network: driver: bridge
|