SpringBoot之Docker准备

本文深入解析Docker的安装与配置,详解从镜像下载、容器启动到高级操作的全流程。涵盖Docker基本命令、Tomcat及MySQL容器的搭建与管理,以及端口映射、日志查看等实用技巧。

回顾:

SpringBoot之基础

SpringBoot之配置

SpringBoot之日志

SpringBoot之Web开发基础

SpringBoot之Web开发实验

SpringBoot之Web开发后续处理

简介

Docker是一个开源的应用容器引擎;是一个轻量级容器技术;

Docker支持将软件编译成一个镜像;然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像;类似ghost系统的原理.

核心概念 

1) 安装linux系统(自行百度)

2) 在linux系统上安装docker

    ① 检查内核版本(3.10及以上), 使用命令uname -r查看

    ② 安装docker yum install docker

查看版本:   

    ③ 启动docker systemctl start docker

如果无法启动, 则进入/etc/sysconfig/目录下, 编辑selinux文件, 将selinux的属性值改为disabled.

    ④ 查询命令(如 docker search mysql)

    ⑤ 下载镜像(docker pull <镜像名称[可以是全名, 也可以是简称, 如: 全名[docker.io/mysql], 简称[mysql]]>)

    ⑥ 指定下载镜像的版本(默认是最新版[latest]): docker pull <镜像名称>:<版本名称>

    ⑦ 查询docker镜像(docker images)

    ⑧ 删除指定镜像(docker rmi <镜像id>)

容器操作

流程: 明确所需镜像 ==> 运行镜像 ==> 产生对应容器(软件本身, 如tomcat)

    搜索镜像: docker search tomcat

    拉取镜像: docker pull tomcat(默认是最新版)

    启动容器: docker run --name <自定义容器名称, 如: mytomcat> -d[表示后台运行] <镜像名称>[可加版本号]

    docker run --name mytomcat -d tomcat:latest

    查看运行中/所有的镜像(软件): docker ps / docker ps -a

    停止运行中的容器: docker stop <运行中的容器id>

    当知道容器id时, 启动该容器也可以使用命令docker start <容器id>

     删除容器, docker rm <容器id>

     外部访问tomcat的docker容器(做端口映射)

    命令: docker run --name <自定义容器名称> -d -p <虚拟机端口>:<要映射到tomcat中的端口> <tomcat镜像名称>

    例: 将虚拟机的8888端口映射给tomcat的8080端口, 这样外部就能通过8888端口访问tomcat的8080端口

访问: ip:8888  在此之前需要关闭linux的防火墙

     查看容器日志: docker logs <容器id>

    一个镜像可以启动多个容器

    更多命令: https://docs.docker.com/engine/reference/commandline/docker/ 

安装启动mysql

安装镜像, 参照上文, 启动镜像, 参照官方文档

docker run --name mysql01 -e MYSQL_ROOT_PASSWORD=<自定义密码> -d mysql

-p: 做端口映射

-e: 指定root账户的密码

-d: 后台运行

连接测试:

ps: 如果连接不成功报2059错误码, 请参考解决方案: https://blog.youkuaiyun.com/u013274055/article/details/83794340

步骤: 

    ① 查询具体mysql容器id: docker ps -a

    ② 连接mysql的docker容器: docker exec -it [指定容器id] bash

    ③ 连接mysql: mysql -u root -p

    ④ 修改加密方式为mysql_native_password, 密码为root: alter user 'root'@'%' identified with mysql_native_password by 'root'

    ⑤ 执行命令使权限配置项立即生效: flush privileges

其他的高级操作

官方文档说明: 

释义:

docker run --name [自定义mysql名称] -e MYSQL_ROOT_PASSWORD=[自定义root账户的密码] -d mysql:[指定版本, 默认最新版本] --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci  (红色部分是指定编码为utf-8)

docker run --name mysql_name -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

意为指定mysql的编码为utf-8

docker run --name [自定义名称] -v [自定义文件夹]:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=[自定义root账户的密码] -d mysql:[指定版本]

docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

意为把主机的[指定文件夹]挂载到 mysql的docker容器的/etc/mysql/conf.d文件夹里面, 这样以后就只需要把mysql的配置文件放到自定义的文件夹里面即可(docker容器会跟mysql原来的配置文件进行融合)

<think>我们根据用户需求编写Dockerfile,并给出构建和运行命令。 需求: 1. 基于JDK8镜像 2. 将位于/home/docker/springboot-docker-test的jar包构建成镜像(假设jar包名为app.jar,但实际可能不同,我们考虑动态指定) 3. 将程序数据持久化到宿主机的/home/docker/springboot-docker-test/data目录 4. 暴露端口8080 注意:数据持久化通常是指容器内应用程序产生的数据(如文件、日志等)需要保存到宿主机,以便容器重启后不丢失。这里用户指定了宿主机的持久化目录为`/home/docker/springboot-docker-test/data`。 有两种常见方式实现数据持久化: 1. 使用Docker的`VOLUME`指令在Dockerfile中声明一个卷,然后在运行容器时通过`-v`参数将宿主机的目录挂载到这个卷上。 2. 不在Dockerfile中声明卷,而是在运行容器时直接通过`-v`参数将宿主机目录挂载到容器内的某个目录。 由于用户要求将数据持久化到宿主机的特定目录(`/home/docker/springboot-docker-test/data`),我们选择在运行容器时挂载卷。 因此,Dockerfile中我们不需要声明卷,只需要指定容器内应用程序数据存储的路径(即需要挂载的容器内路径)。但是,如果应用程序有默认的数据存储路径,我们需要知道这个路径是什么,然后挂载到宿主机。 由于用户没有指定容器内数据存储的路径,这里假设应用程序将数据写入到容器内的`/app/data`目录(这个路径需要根据实际应用调整,如果应用没有指定,我们可以自行设计,并在启动命令中通过参数指定应用的数据目录,或者在配置文件中指定)。 如果用户的应用是Spring Boot,我们可以通过配置文件指定数据目录,或者在启动时通过`--spring.application.data.dir`等参数指定(具体参数名由应用决定)。 由于用户没有提供应用的详细情况,我们假设: - jar包名称:app.jar(实际可能不同,这里我们假设为app.jar,但构建时可以通过上下文复制具体的jar包) - 应用在容器内将数据写入到`/app/data`目录 步骤: 1. 在Dockerfile中,我们将jar包复制到镜像中,并指定启动命令运行jar包。 2. 在运行容器时,将宿主机的`/home/docker/springboot-docker-test/data`挂载到容器内的`/app/data`。 另外,用户要求暴露8080端口,我们在Dockerfile中使用`EXPOSE 8080`。 Dockerfile 示例: 注意:由于jar包在宿主机的`/home/docker/springboot-docker-test`目录下,我们需要将Dockerfile也放在这个目录,或者其子目录?但通常我们构建镜像时,Dockerfile的上下文就是当前目录,所以我们需要将jar包放在Dockerfile所在的目录,或者使用相对路径。 假设Dockerfile就放在`/home/docker/springboot-docker-test`目录下,并且该目录下有一个名为`app.jar`的jar文件(或者我们可以使用通配符,但建议明确名称)。 但是,为了灵活性(比如jar包名称带版本号),我们可以使用通配符,或者通过构建参数传递jar包名称。 这里我们使用构建参数(ARG)来指定jar包名称。 Dockerfile 内容如下: ```dockerfile # 使用JDK8作为基础镜像 FROM openjdk:8-jdk-alpine # 设置工作目录 WORKDIR /app # 定义构建参数,用于传递jar包名称 ARG JAR_FILE=app.jar # 将jar包复制到镜像中,命名为app.jar(固定名称,方便后续启动命令使用) COPY ${JAR_FILE} app.jar # 声明容器运行时监听的端口 EXPOSE 8080 # 设置容器启动时运行的命令 ENTRYPOINT ["java", "-jar", "app.jar"] ``` 构建镜像: 在`/home/docker/springboot-docker-test`目录下执行: ```bash docker build -t my-springboot-app . ``` 如果jar包名称不是app.jar,比如为app-1.0.0.jar,我们可以通过构建参数指定: ```bash docker build --build-arg JAR_FILE=app-1.0.0.jar -t my-springboot-app . ``` 运行容器: 我们需要将宿主机的数据目录挂载到容器内的`/app/data`(假设应用在容器内使用`/app/data`作为数据目录),同时暴露8080端口。 ```bash docker run -d --name springboot-app \ -p 8080:8080 \ -v /home/docker/springboot-docker-test/data:/app/data \ my-springboot-app ``` 注意:这里假设应用在容器内会将数据写入到`/app/data`目录。如果应用的数据目录不是这个,需要根据实际情况修改挂载点。 但是,如果应用的数据目录不是固定的,或者我们无法控制,那么可以在运行容器时通过环境变量或者命令行参数来指定数据目录。这需要应用支持。 例如,如果应用支持通过`--data.dir`参数指定数据目录,我们可以修改启动命令: Dockerfile中: ```dockerfile ENTRYPOINT ["java", "-jar", "app.jar", "--data.dir=/app/data"] ``` 或者在运行容器时通过环境变量传入(如果应用支持从环境变量读取): ```bash docker run ... -e DATA_DIR=/app/data ... ``` 由于用户没有提供应用的具体情况,我们按照默认情况处理。 另外,如果应用在运行过程中除了数据目录,可能还需要其他配置,比如日志目录,也可以同样挂载。 用户还要求将日志持久化?但是用户只提到了“程序数据”,如果日志也是程序数据的一部分,那么我们可以将日志目录也挂载出来。但用户没有明确,我们先按照数据目录挂载。 如果日志目录是单独的,比如在`/app/logs`,那么我们可以再挂载一个卷: ```bash -v /home/docker/springboot-docker-test/logs:/app/logs ``` 但是用户需求中只提到了数据持久化到`/home/docker/springboot-docker-test/data`,所以我们只挂载这个。 总结: 1. 编写Dockerfile(如上) 2. 构建镜像 3. 运行容器时挂载数据卷 注意:如果应用没有将数据写入到我们指定的`/app/data`,那么挂载不会生效。因此,需要确保应用配置正确。 另外,参考引用[2]中提供了一种动态更新jar包的方式,但我们这里的需求是数据持久化,不是更新jar包,所以不需要动态更新jar包。 如果用户希望以后方便更新jar包,可以考虑将jar包也挂载到宿主机,然后通过替换宿主机上的jar包并重启容器来更新。但是,在构建镜像时jar包已经打入镜像,所以无法通过挂载覆盖。因此,如果用户需要频繁更新jar包,可以采用引用[2]中的方式,将jar包放在宿主机目录,然后通过挂载的方式提供给容器,并在启动命令中指定jar包路径。 但是,用户的需求是“构建成镜像”,所以我们按照构建镜像的方式。 因此,我们提供两种方案供用户选择: 方案一:jar包打入镜像(如上),适合稳定版本部署。 方案二:jar包通过挂载提供,适合频繁更新。具体如下: 修改Dockerfile,不包含jar包,而是从挂载的卷中运行jar包: Dockerfile: ```dockerfile FROM openjdk:8-jdk-alpine WORKDIR /app # 不需要COPY jar包 # 暴露端口 EXPOSE 8080 # 设置一个环境变量用于指定jar包名称 ENV JAR_NAME="app.jar" ENTRYPOINT ["sh", "-c", "java -jar /app/jars/${JAR_NAME}"] ``` 构建镜像: ```bash docker build -t my-springboot-app . ``` 运行容器: ```bash docker run -d --name springboot-app \ -p 8080:8080 \ -v /home/docker/springboot-docker-test:/app/jars \ -v /home/docker/springboot-docker-test/data:/app/data \ -e JAR_NAME="app.jar" \ my-springboot-app ``` 这样,更新jar包时,只需要替换宿主机`/home/docker/springboot-docker-test`目录下的app.jar,然后重启容器即可。 但是,用户需求是“将jar包构建成镜像”,所以方案一更符合。如果用户后续需要频繁更新,再采用方案二。 我们按照用户最初的需求,提供方案一的Dockerfile。 最终Dockerfile(方案一): ```dockerfile # 使用JDK8作为基础镜像 FROM openjdk:8-jdk-alpine # 设置工作目录 WORKDIR /app # 定义构建参数,用于传递jar包名称 ARG JAR_FILE=app.jar # 将jar包复制到镜像中,命名为app.jar COPY ${JAR_FILE} app.jar # 声明容器运行时监听的端口 EXPOSE 8080 # 设置容器启动时运行的命令 ENTRYPOINT ["java", "-jar", "app.jar"] ``` 构建和运行命令如上。 注意:由于基础镜像`openjdk:8-jdk-alpine`是基于Alpine Linux的轻量级镜像,如果应用需要其他依赖(如字体等),可能需要安装额外的包。如果不需要轻量级,可以使用`openjdk:8`。 如果用户希望使用非Alpine的基础镜像,可以换成: ```dockerfile FROM openjdk:8 ``` 我们根据用户需求选择,这里使用Alpine以减小镜像体积。 因此,完整的步骤: 1. 将jar包放在`/home/docker/springboot-docker-test`目录下。 2. 在同一目录下创建Dockerfile,内容如上。 3. 构建镜像。 4. 运行容器,挂载数据卷。 如果用户有多个jar包,或者需要指定特定名称,构建时通过`--build-arg`指定。 最后,请用户确保应用在容器内运行时,将数据写入到`/app/data`目录。如果应用的数据目录不是这个,需要调整挂载路径。 如果应用的数据目录在代码中写死,无法修改,那么我们可以考虑在容器启动后,将数据目录软链接到挂载的目录?或者修改应用配置(如果支持配置文件,我们可以将配置文件挂载出来修改)。 但是,这些需要根据应用的具体情况处理。 我们提供的是通用方案,用户需要根据应用实际情况调整数据目录。 </think> ### 基于JDK8构建Spring Boot应用的Dockerfile及部署方案 #### 一、解决方案概述 1. **基础镜像**:使用官方`openjdk:8-jdk-alpine`镜像(轻量级) 2. **数据持久化**:通过`-v`参数将宿主机目录挂载到容器内 3. **端口映射**:使用`-p`参数暴露8080端口 4. **动态配置**:通过环境变量支持Jar包名称变更 #### 二、完整Dockerfile ```dockerfile # 使用官方JDK8 Alpine镜像(轻量级) FROM openjdk:8-jdk-alpine # 设置工作目录 WORKDIR /app # 添加Spring Boot Jar包(请替换your-app.jar为实际文件名) ARG JAR_FILE=your-app.jar COPY ${JAR_FILE} app.jar # 创建数据存储目录(用于挂载) RUN mkdir -p /app/data # 暴露应用端口 EXPOSE 8080 # 启动应用(考虑时区设置) ENTRYPOINT ["java", "-Duser.timezone=Asia/Shanghai", "-jar", "app.jar"] ``` #### 三、操作步骤 1. **准备环境** ```bash # 创建项目目录 mkdir -p /home/docker/springboot-docker-test/data # 进入工作目录(假设jar包在此) cd /home/docker/springboot-docker-test ``` 2. **构建Docker镜像** ```bash # 替换your-app.jar为实际文件名 docker build --build-arg JAR_FILE=your-app.jar -t springboot-app:1.0 . ``` 3. **运行容器** ```bash docker run -d --name springboot-app \ -p 8080:8080 \ -v /home/docker/springboot-docker-test/data:/app/data \ springboot-app:1.0 ``` #### 四、关键配置解析 1. **数据持久化** `-v /home/docker/springboot-docker-test/data:/app/data` 实现: - 宿主机目录:`/home/docker/springboot-docker-test/data` - 容器目录:`/app/data` - 应用需将数据写入`/app/data`目录实现持久化[^1] 2. **动态Jar包管理** 通过构建参数支持不同版本: ```bash # 构建v2.0版本 docker build --build-arg JAR_FILE=app-v2.0.jar -t springboot-app:2.0 . ``` 3. **时区配置** `-Duser.timezone=Asia/Shanghai` 解决容器内时区问题(按需修改) #### 五、更新部署流程 1. **更新Jar包** ```bash # 1. 停止并删除旧容器 docker stop springboot-app && docker rm springboot-app # 2. 构建新版本镜像 docker build --build-arg JAR_FILE=new-app.jar -t springboot-app:2.0 . # 3. 启动新容器(复用原数据卷) docker run -d --name springboot-app \ -p 8080:8080 \ -v /home/docker/springboot-docker-test/data:/app/data \ springboot-app:2.0 ``` 2. **热更新方案(无需重建镜像)** ```bash # 1. 替换宿主机Jar包 cp new-app.jar /home/docker/springboot-docker-test/app.jar # 2. 重启容器 docker restart springboot-app ``` #### 六、验证部署 ```bash # 检查容器状态 docker ps -f name=springboot-app # 查看日志 docker logs -f springboot-app # 测试访问 curl http://localhost:8080/health ``` #### 七、目录结构建议 ``` /home/docker/springboot-docker-test/ ├── data/ # 持久化数据(自动创建) ├── Dockerfile # 构建文件 ├── app-v1.0.jar # 应用jar包 └── app-v2.0.jar # 新版本jar包 ``` > ⚠️ 注意:确保应用配置文件中数据存储路径设置为`/app/data`(示例:Spring Boot配置`spring.servlet.multipart.location=/app/data`) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值