当前位置: 代码迷 >> 综合 >> 使用 docker compose 管理 java web 项目
  详细解决方案

使用 docker compose 管理 java web 项目

热度:59   发布时间:2023-11-17 21:38:47.0

一、背景

docker-java-app https://github.com/ChaseDreamBoy/docker-java-app 是由 springboot + mysql + redis 组成的项目。对于 springboot 的 jar 包、mysql、redis,每一个软件都运行在一个容器中,使用 docker compose 来管理这三个容器。

二、文件结构

把 docker compose 组成内容定义到一个文件目录中,方便统一管理(仅供参考):

docker-compose-structure

其中各个文件夹与文件的作用是:

  • app : 存放 jar 包与, 定义镜像的 Dockerfile 文件
    • application.properties : springboot 装配文件, 方便更改一些参数
    • Dockerfile : 把这个 java 程序打包成镜像的 Dockerfile 文件
    • docker-java-app-1.0.0.jar : jar 包
  • bin : 自己编写的启动脚本方便快速的启动 docker compose
    • compose : docker compose 操作脚本
  • compose : docker compose 的定义目录, 包含配置文件 docker-compose.yml
    • docker-compose.yml : docker compose 配置文件
  • mysql : mysql 相关的文件
    • data : 用于存放 mysql 数据
    • init : 存放 mysql 初始化 sql
      • init.sql : mysql c初始化建数据库,建表sql
    • my.cnf : mysql 的配置文件
  • redis : redis 相关的文件
    • data : 存储 redis 持久的 rdb 文件
    • redis.conf : redis 配置文件

三、构建 java 程序镜像

  1. 把 jar 包上传到 app 目录
  2. 把配置文件上传到 app 中,方便修改配置
  3. 编写 Dockerfile

Dockerfile 的内容如下 :

# 基础镜像
FROM java:8
# 指定作者
MAINTAINER xiaohe
# 把文件复制到镜像中, 路径是相对于 Dockerfile
ADD docker-java-app-1.0.0.jar /app/docker-java-app-1.0.0.jar
ADD application.properties /app/application.properties
# 容器内部程序启动命令
ENTRYPOINT ["java","-jar","-Dspring.config.location=/app/application.properties","/app/docker-java-app-1.0.0.jar"]

四、redis 相关

如果需要把 redis 持久化数据复制出来,就把 redis 的持久化目录挂载到宿主机就好,我这里是挂载在 redis 目录下的 data 目录里面的,挂载是在 docker-compose.yml 文件中定义的。

如果需要自定义配置文件的话,可以从 https://github.com/antirez/redis/blob/5.0.7/redis.conf 复制一份到 redis 目录并挂载,修改需要的选项,在启动的时候指定配置文件就好了。

五、mysql 相关

mysql 的持久与 redis 一样,mysql 的配置文件,需要自己自定义一个 my.cnf 文件,并挂在容器中 mysql 启动时扫描的目录中。

对于在 mysql 中初始化 sql, 可以参考 : https://github.com/docker-library/docs/tree/master/mysql#initializing-a-fresh-instance

步骤 :

  1. 在 mysql 目录下建一个 .sql 均可以, 然后把要执行的 sql 复制到 .sql 文件中
  2. 对该文件执行 sudo chmod +x xxx.sql 命令使其有可执行权限
  3. 把这个文件挂到容器的 /docker-entrypoint-initdb.d/ 目录
  4. 如果 mysql 的数据文件夹是挂载的宿主机, 需要保证宿主机里面的数据文件夹是空的, 不然不会执行初始化sql

六、编写 docker-compose.yml

其内容大概如下:

version: "3"services:redis:# 镜像image: redis:5.0.7# 指定容器名container_name: redisvolumes:# 挂载 redis 配置文件,与 rdb 文件目录- ../redis/redis.conf:/etc/redis/redis.conf:ro- ../redis/data:/data# 启动命令command: ["redis-server", "/etc/redis/redis.conf"]# 映射端口ports:- "6379:6379"mysql:image: mysql:5.7.28container_name: mysqlvolumes:- ../mysql/my.cnf:/etc/mysql/my.cnf:ro- ../mysql/data:/data/mysql# 定义 mysql 初始化 sql, 参照 : https://github.com/docker-library/docs/tree/master/mysql#initializing-a-fresh-instance# 注意 : 本地目录的 .sh, .sql, .sql.gz 文件需要先添加执行权限# 由于这里的数据文件夹是挂载的宿主机, 需要保证宿主机里面的数据文件夹是空的, 不然不会执行初始化sql- ../mysql/init/:/docker-entrypoint-initdb.d/environment:# 定义 mysql root 用户的密码, 参照 : https://github.com/docker-library/docs/tree/master/mysql#environment-variablesMYSQL_ROOT_PASSWORD: 123456ports:- "3306:3306"docker_java_app:build:context: ../app# 这里的路径是相对于 content 的dockerfile: ./Dockerfilecontainer_name: my-appvolumes:- ../app/:/appports:- "8082:8082"# 定义容器 redis 与 mysql 启动后在启动这个容器depends_on:- redis- mysql

七、辅助脚本

这时候需要运行的话,可以在文件 docker-compose.yml 同目录运行命令 :

$ sudo docker-compose -p my-app up -d

但是可以编写脚本,方便操作,在 bin 目录新建文件 compose,其内容如下 :

#!/bin/bashroot=$(cd `dirname $0`; dirname `pwd`)# -p 后面的参数是容器名前缀
docker-compose -p my-app -f ${root}/compose/docker-compose.yml "$@"

使用命令 sudo chmod +x compose 给脚本 compose 添加可执行权限。

然后一些操作命令如下:

# 启动组件
sudo ./bin/compose up -d# 停止组件
sudo ./bin/compose down# 查看组件的日志
sudo ./bin/compose logs 容器名

使用 sudo ./bin/compose up -d 命令启动后,就可以使用 sudo docker imagesdocker ps,就可以看到新添加的镜像和容器了。

如果构建镜像错误,在命令 sudo ./bin/compose up -d 的控制台中就可以看到,但是如果 docker ps 中没有想要的容器,就需要使用 sudo ./bin/compose logs 容器名 或者 sudo docker logs 容器名 查看日志中的错误信息并做处理。

如果一切都没有问题,那么就可以访问 springboot 应用了。

八、资料

docker compose 示例 : https://github.com/ChaseDreamBoy/docker-java-app/tree/master/doc/docker-compose
java 测试应用 : https://github.com/ChaseDreamBoy/docker-java-app
docker compose : https://blog.csdn.net/qq_37502106/article/details/103547346

  相关解决方案