Step1、Docker开启远程访问
Step1、修改配置
# 编辑docker.service文件
sudo vi /etc/systemd/system/docker.service
# 或使用
sudo vi /usr/lib/systemd/system/docker.service
# 将 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock 修改为下面内容
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock
Step2、重载服务
# 重新加载systemd配置
sudo systemctl daemon-reload
# 重启Docker服务
sudo systemctl restart docker
# 检查服务状态
sudo systemctl status docker
# 查看端口监听
sudo netstat -tlnp | grep 2375
Step3、测试是否修改完成
# 本地测试
curl http://localhost:2375/version
# 远程测试
curl http://ip:2375/version
Step2、Docker制作Base基础镜像
仅构建JDK镜像
Step1、将本地jdk制作成镜像---新建Dockerfile
# 多阶段构建 - 第一阶段:准备JDK 1
FROM ubuntu:24.04 AS builder
WORKDIR /opt
# 复制JDK目录到容器中
# 此处的COPY ./jdk1.8 /opt/jdk1.8 ,其中的"jdk1.8"只能是Dockerfile所在目录下面的jdk1.8,不能是宿主机其他地方的目录
# 如果是其他目录可以使用下面cp命令操作
### # 在构建上下文目录中创建jdk目录
### mkdir -p /apps/docker_build/jdk
### # 复制JDK到构建上下文
### cp -r /usr/lib/jvm/java-1.8.0-openjdk-amd64/* /apps/docker_build/jdk/
COPY ./jdk1.8 /opt/jdk1.8
# 第二阶段:创建最终镜像
FROM ubuntu:24.04
# 更新包列表并安装必要的依赖
RUN apt-get update && apt-get install -y \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# 从第一阶段复制JDK
COPY --from=builder /opt/jdk1.8 /opt/java
# 设置环境变量
ENV JAVA_HOME=/opt/java
ENV PATH=$JAVA_HOME/bin:$PATH
# 验证Java安装
RUN java -version
# 设置默认命令
CMD ["java", "--version"]
Step2、执行Dockerfile脚本
# docekr build -t 镜像名称:镜像版本 Dockerfile所在位置
docker build -t my-jdk1.8:latest . (有一个点)
Step3、查看是否打包好
docker images;
Step4、运行容器测试
docker run --rm my-jdk1.8:latest java -version
Step5、容器打包:.tar包。保存为tar文件
docker save -o my-jdk-1.7.tar my-jdk1.8:latest
Step6、加载镜像文件
docker load -i my-jdk-1.7.tar
基础实际效果

在已有镜像的基础上增加环境
假设我们现在通过Docker images查看到我们有一个my-jdk1.8的镜像,但是这个镜像中我们只有一个jdk环境,我们现在需要新增一个比如ffmpeg的环境依赖时,有两种方法,一种是修改原有Dockerfile一种是使用"my-jdk1.8"镜像为基础镜像新增后续环境即可。
方法一:使用my-jdk1.8为基础镜像
Step1、创建一个Dockerfile.ffmpeg的Dockerfile文件
# 基于现有的JDK镜像
FROM my-jdk1.8:latest
# 安装FFmpeg
RUN apt-get update && apt-get install -y \
ffmpeg \
&& rm -rf /var/lib/apt/lists/*
# 验证FFmpeg安装
RUN ffmpeg -version
Step2、构建新镜像
# 如果新的Dockerfile文件名称也是Dockerfile,那么可以直接为"docker build -t my-jdk-ffmpeg(新镜像名称):1.0(新镜像版本) ."
docker build -t my-jdk-ffmpeg:1.0 -f Dockerfile.ffmpeg .(有一个·)
Step3、运行测试
# 测试Java
docker run --rm my-jdk-ffmpeg:1.0 java -version
# 测试FFmpeg
docker run --rm my-jdk-ffmpeg:1.0 ffmpeg -version
# 交互模式运行
docker run -it --rm my-jdk-ffmpeg:1.0 bash
方法二:直接修改原始Dockerfile文件,重新构建
Step1、创建新的Dockerfile 使用多阶段构建镜像
# 多阶段构建
FROM ubuntu:24.04 AS builder
WORKDIR /opt
# 复制JDK目录 --- 当前Dockerfile的目录下的jdk1.8
COPY ./jdk1.8 /opt/jdk1.8
# 第二阶段:基础环境
FROM ubuntu:24.04
# 设置时区和apt源(可选,加快下载速度)
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装基础依赖和FFmpeg
RUN apt-get update && apt-get install -y \
ca-certificates \
ffmpeg \
libavcodec-extra \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# 从第一阶段复制JDK
COPY --from=builder /opt/jdk1.8 /opt/java
# 设置环境变量
ENV JAVA_HOME=/opt/java
ENV PATH=$JAVA_HOME/bin:$PATH
ENV LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
# 验证安装
RUN java -version && \
ffmpeg -version
# 设置工作目录
WORKDIR /app
# 设置默认命令(可以根据需要修改)
CMD ["java", "--version"]
Step2、构建新的镜像
docker build -t my-jdk-ffmpeg:1.0.0 .(有一个点)
Step3、运行测试
# 测试Java
docker run --rm my-jdk-ffmpeg:1.0.0 java -version
# 测试FFmpeg
docker run --rm my-jdk-ffmpeg:1.0.0 ffmpeg -version
# 交互模式运行
docker run -it --rm my-jdk-ffmpeg:1.0.0 bash
Step3、正文-Docker+Maven插件自动打包
前提:要在第一步中打包jdk1.8本地镜像以后才能使用。
添加pom.xml配置文件依赖:
注意:我们在创建项目的时候一定要创建全小写名称,如果是多个单词中间可以使用"-"划分。如果是大写字母,系统要 报错。
有两种:
io.fabric8/docker-maven-plugin:可以实现自动docker run启动,但是配置麻烦
com.spotify/docker-maven-plugin:无法实现自动 docker run 启动,需要配合脚本或者手动 docker run命令才行
方法一:使用com.spotify/docker-maven-plugin
Step1、添加docker-maven插件
XML
<!--dockerfile-maven-plugin用于docker打包-->
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.2</version> <!-- 因本插件停止更新,所以1.2.2是最新版本 -->
<configuration>
<imageName>qy/${project.artifactId}:${project.version}</imageName>
<!-- 要上传到那个Docker服务器 -->
<dockerHost>http://192.168.0.168:2375</dockerHost>
<!-- 指定Dockerfile路径 -->
<dockerDirectory>${project.basedir}</dockerDirectory>
<!-- 构建参数 -->
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
Step2、创建Dockfile
XML
FROM my-jdk1.8:latest # Docker制作的Base基础镜像
# 创建日志目录
RUN mkdir -p /logs
# 复制jar包到容器,并重命名为 app.jar
ARG JAR_FILE=target/like-front-1.0.0.jar
COPY ${JAR_FILE} /app.jar
# 设置环境变量
ENV SPRING_PROFILES_ACTIVE=test \
JAVA_OPTS="-Xms512m -Xmx2048m"
# 设置启动命令
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app.jar -Dspring.profiles.active=$SPRING_PROFILES_ACTIVE"]
Step3、执行Maven命令
XML
mvn clean package -Dmaven.test.skip=true docker:removeImage docker:build
如果是在IDEA中,那么不需要mvn,如下:

最终效果:

方法二:使用io.fabric8/docker-maven-plugin
实现要求
本地install时,实现自动执行"
docker stop"、"docker rm"、"docker build"、"docker run"等命令。也就是可以实现将本地jar做成镜像,然后自动上传到docker服务器上,如果docker服务器上有对应的镜像会先停止然后删除相关的镜像以及容器,然后执行build命令再,执行启动命令,并对外暴露端口;本文通过maven-profile管理启动端口server.port以及启动环境spring.profiles.active;
通过Dockerfile管理build配置;
数据流转
执行maven命令(mvn clean install -Ptest -Dmaven.test.skip=true),指定启动环境为test;
读取profiles里面的id为test的profile(从而获取对应的server.port、spring.profiles.active等配置信息);
触发在docker-maven-plugin插件里面的生命周期配置,也就是executions里面中phase为install的execution配置,本文配置的是在install环境下执行goal为"stop、remove、build、start"也就是在maven install时系统会自动并依次为我们执行 docker stop、docker remove、docker build、docker start命令;
在执行docker stop时会根据configuration/images/image里面的stopNamePattern名称进行停止;
执行remove时,根据configuration/images/image里面的removeNamePattern名称移除;
执行build时,根据configuration/images/build里面的配置进行加载;
包括我们设置的args(也就是环境变量:我们通过在这里设置SPRING_PROFILES_ACTIVE、SERVER_PORT向Dockerfile/application.yml传递参数)
dockerFile(Dockerfile文件所在位置)
执行run 的时候我们可以在里面指定ports映射端口,相当于我们手动执行docker run时通过 -v xxx:xxx 来指定的端口;
详细配置以及步骤
Step1、io.fabric8/docker-maven-plugin插件配置
XML
<build>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.48.0</version>
<configuration>
<dockerHost>${docker.host}</dockerHost>
<images>
<image>
<!-- 镜像名称(是镜像名称不是容器名称) -->
<name>${docker.image.prefix}/${project.artifactId}:${project.version}</name>
<alias>${docker.container.name}</alias>
<stopNamePattern>${docker.container.name}</stopNamePattern>
<removeNamePattern>${docker.container.name}</removeNamePattern>
<build>
<dockerFile>${project.basedir}/Dockerfile</dockerFile>
<args>
<!--
在application.yml中可以通过如下方法获取:
# 服务配置
server:
port: ${SERVER_PORT:8085}
spring:
profiles:
active: ${SPRING_PROFILES_ACTIVE:dev}
在Dockerfile中可以通过如下方法获取;
ARG JAR_FILE
ARG SPRING_PROFILES_ACTIVE
ARG SERVER_PORT
-->
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
<!-- 添加以下参数 -->
<SPRING_PROFILES_ACTIVE>${spring.profiles.active}</SPRING_PROFILES_ACTIVE>
<SERVER_PORT>${server.port}</SERVER_PORT>
<DOCKER_HOST_DIR>${docker.host.dir}</DOCKER_HOST_DIR>
<DOCKER_WORKDIR_DIR>${docker.workdir.dir}</DOCKER_WORKDIR_DIR>
</args>
<!-- 构建上下文目录 -->
<contextDir>${project.basedir}</contextDir>
<!-- 清理中间镜像 -->
<cleanup>true</cleanup>
<!-- 不使用缓存 -->
<noCache>false</noCache>
<!-- 优化:缓存依赖层 -->
<optimise>true</optimise>
</build>
<!-- <run>配置是在镜像构建完成后运行容器的配置 -->
<run>
<!-- 容器配置 -->
<!-- 名字类型-别名 -->
<namingStrategy>alias</namingStrategy>
<containerNamePattern>${docker.container.name}</containerNamePattern>
<!-- 端口映射:主机端口:容器端口,和使用Docker-cli通过 -v来使用一样 -->
<ports>
<port>${docker.host.port}:${server.port}</port>
<port>8888:8895</port>
</ports>
<!-- 将容器日志输出到宿主机文件 -->
<volumes>
<bind>
<!-- 将宿主机目录挂载到容器内日志目录:
注意:如果我们直接将宿主机 目录 挂载到容器里面的工作目录 ${docker.workdir.dir}
这样会导致报错"Error: Unable to access jarfile /app/app.jar" 这是因为这样挂载会将宿主机的目录覆盖"${docker.workdir.dir}"目录。
所以必须挂载的是日志文件目录,或者其他目录 -->
<volume>${docker.host.dir}/logs:${docker.workdir.dir}/logs</volume>
</bind>
</volumes>
<!-- 添加重启策略 -->
<restartPolicy>
<name>always</name>
</restartPolicy>
</run>
</image>
</images>
</configuration>
<!-- Maven生命周期绑定 -->
<executions>
<!-- 在 deploy(部署)阶段停止旧容器并启动新容器,也就是在 执行maven deploy 时自动为我们执行 docker stop、 docker remove、 docker build、 docker start命令;除此之外phase还可以选择 clean、build、install比如(mvn clean install -Ptest -Dmaven.test.skip=true)或者 mvn clean install -Ptest -Dmaven.test.skip=true 进行绑定,
当然也可以不配置execution绑定maven的生命周期,也可以使用命令的形式绑定,比如:
mvn clean deploy -Ptest -Dmaven.test.skip=true -Dmaven.deploy.skip=true docker:stop docker:remove docker:build docker:start
或者
mvn clean deploy -Ptest -Dmaven.test.skip=true docker:stop docker:remove docker:build docker:start
-->
<execution>
<id>docker-run</id>
<phase>deploy</phase>
<goals>
<goal>stop</goal>
<goal>remove</goal>
<goal>build</goal>
<goal>start</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Maven Deploy Plugin - 跳过默认部署;
如果不加这个插件,那么就需要使用命令:mvn clean deploy -Ptest -Dmaven.test.skip=true -Dmaven.deploy.skip=true
不跳过的话,因为我们没有配置maven私服所以我们在使用mvn clean deploy 时可能报错:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:3.1.2:deploy (default-deploy) on project like-front: Deployment failed: repository element was not specified in the POM inside distributionManagement element or in -DaltDeploymentRepository=id::url parameter -> [Help 1] -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.4</version>
<configuration>
<skip>true</skip> <!-- 跳过默认的deploy部署 -->
</configuration>
</plugin>
<!-- 配置资源通配符匹配器:这个如果不配置,只能在application.yml中只能通过@...@带入,docker又无法通过@...@带入 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<delimiters>
<delimiter>${*}</delimiter>
</delimiters>
<useDefaultDelimiters>true</useDefaultDelimiters>
</configuration>
</plugin>
</build>
Step2、配置资源过滤器
XML
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering> <!-- 启用资源过滤 -->
<includes>
<include>**/application*.yml</include> <!-- 过滤所有环境配置文件 -->
</includes>
</resource>
</resources>
</build>
Step3、配置maven-profile管理器
XML
<profiles>
<!-- 开发环境 -->
<profile>
<id>dev</id>
<activation>
<!-- 是否默认选择 -->
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!-- 容器内IP -->
<server.port>8087</server.port>
<!-- 选择的环境 -->
<spring.profiles.active>dev</spring.profiles.active>
<!-- 工作目录 -->
<docker.workdir.dir>/app</docker.workdir.dir>
<!-- 宿主机目录 -->
<docker.host.dir>/apps/front</docker.host.dir>
<!-- docker服务器位置 -->
<docker.host>http://192.168.0.168:2375</docker.host>
<!-- 对外暴露的端口 -->
<docker.host.port>8084</docker.host.port>
</properties>
</profile>
</profiles>
Step4、配置application.yml
XML
# 服务配置
server:
port: ${SERVER_PORT:8085} # 大写说明是环境变量
spring:
profiles:
active: ${SPRING_PROFILES_ACTIVE:dev} # 大写说明是环境变量
Step5、配置Dockerfile
XML
# 使用官方基础镜像(推荐)
#FROM openjdk:8-jdk-alpine
# 使用您自己的基础镜像
FROM my-jdk-ffmpeg:1.0
# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 复制jar包到容器
### 获取环境变量里面的值 JAR_FILE、SPRING_PROFILES_ACTIVE、SERVER_PORT也就是xml中configuration/images/image/build/args里面的数据
#ARG JAR_FILE=target/like-front-1.0.0.jar
ARG JAR_FILE=target/like-front-1.0.0.jar
ARG SPRING_PROFILES_ACTIVE=test
ARG SERVER_PORT=8085
ARG DOCKER_WORKDIR_DIR=/app
# 设置工作目录
WORKDIR ${DOCKER_WORKDIR_DIR}
# 创建日志目录 /app/logs
RUN mkdir -p logs
# 复制JAR文件(保持在工作目录内) 完整路径:/app/app.jar
COPY ${JAR_FILE} app.jar
# 设置环境变量
#### 最打包后最终会使用这个的端口、环境以及java参数
#ENV SPRING_PROFILES_ACTIVE=test \
# JAVA_OPTS="-Xms512m -Xmx2048m"
# SERVER_PORT=8080:相当于指定application.yml中的"server.port"为8080
ENV SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE} \
SERVER_PORT=${SERVER_PORT} \
JAVA_OPTS="-Xms512m -Xmx2048m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/dump.hprof" \
TZ=Asia/Shanghai
# 设置日志环境变量(如果使用Spring Boot)
### 完整路径为:/app/logs/
ENV LOGGING_FILE_NAME=logs/like-front.log
# 对外暴露端口
EXPOSE ${SERVER_PORT}
# 设置启动命令
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Dspring.profiles.active=$SPRING_PROFILES_ACTIVE -Dserver.port=${SERVER_PORT} -jar app.jar " ]
Step6、配置Maven启动命令
如果是在IDEA中,就不需要配置mvn 。 之所以使用deploy,是因为我们在开发过程中可能会不断地 clean/install/package,如果绑定在这上面,那么后续我们所有的install..都会执行docker stop/docker build ...之类的命令,所以直接使用maven的deploy(部署)命令即可
XML
# 在execution/phase中绑定对应的生命周期
# 使用deploy命令:execution/phase=deploy
# ### 如果没有指定 maven-deploy-plugin 插件的默认部署行为 需要配置 -Dmaven.deploy.skip=true
mvn clean deploy -Ptest -Dmaven.test.skip=true -Dmaven.deploy.skip=true
# ### 如果有开启 即maven-deploy-plugin/skip=true,只需要如下即可:
mvn clean deploy -Ptest -Dmaven.test.skip=true
# -----
# 使用install命令:execution/phase=install
mvn clean install -Ptest -Dmaven.test.skip=true
# ------------------------------------------------------------------------------------------------------------
# 在mvn命令中指定,无需配置execution/phase=deploy
# 使用mvn deploy命令
# ### 如果没有指定 maven-deploy-plugin 插件的默认部署行为 需要配置 -Dmaven.deploy.skip=true
mvn clean deploy -Ptest -Dmaven.test.skip=true -Dmaven.deploy.skip=true docker:stop docker:remove docker:build docker:start
# ### 如果有开启 即maven-deploy-plugin/skip=true,只需要如下即可:
mvn clean deploy -Ptest -Dmaven.test.skip=true docker:stop docker:remove docker:build docker:start
# -----
# 使用mvn install命令
mvn clean install -Ptest -Dmaven.test.skip=true docker:stop docker:remove docker:build docker:start