Docker Maven 插件深度配置指南:Spotify vs Fabric8

📖 前言

本文深入探讨 Spotify dockerfile-maven-plugin 和 Fabric8 docker-maven-plugin 的多种灵活配置方式,涵盖从基础到高级的各种应用场景。无论你是初学者还是资深开发者,都能找到适合你项目的配置方案。

🏗️ 第一部分:Spotify dockerfile-maven-plugin 深度配置

1.1 基础配置的多种变体

方式一:最小化配置(使用默认值)
java 复制代码
<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>dockerfile-maven-plugin</artifactId>
    <version>1.4.13</version>
    <configuration>
        <repository>myapp</repository>
        <tag>latest</tag>
    </configuration>
</plugin>

特点 :使用项目根目录的 Dockerfile,构建上下文为项目目录

方式二:明确指定路径
java 复制代码
<configuration>
    <!-- 明确指定所有路径 -->
    <dockerfile>${project.basedir}/src/main/docker/Dockerfile</dockerfile>
    <contextDirectory>${project.basedir}/src/main/docker</contextDirectory>
    <repository>registry.company.com/${project.groupId}/${project.artifactId}</repository>
    <tag>${project.version}</tag>
</configuration>
方式三:多标签配置
java 复制代码
<configuration>
    <repository>mycompany/myapp</repository>
    <!-- 多个标签 -->
    <tags>
        <tag>${project.version}</tag>
        <tag>latest</tag>
        <tag>${git.commit.id.abbrev}</tag>
        <tag>${maven.build.timestamp}</tag>
    </tags>
</configuration>

1.2 认证配置的5种方式

方式1:Maven settings.xml(最安全)
java 复制代码
<!-- ~/.m2/settings.xml -->
<settings>
    <servers>
        <!-- 多个仓库配置 -->
        <server>
            <id>docker.io</id>
            <username>${env.DOCKERHUB_USER}</username>
            <password>${env.DOCKERHUB_TOKEN}</password>
        </server>
        <server>
            <id>registry.cn-beijing.aliyuncs.com</id>
            <username>${env.ALIYUN_USER}</username>
            <password>${env.ALIYUN_PASSWORD}</password>
            <configuration>
                <email>user@company.com</email>
            </configuration>
        </server>
        <server>
            <id>harbor.company.com</id>
            <username>robot$project+deploy</username>
            <password>${env.HARBOR_ROBOT_TOKEN}</password>
        </server>
    </servers>
</settings>

插件配置

java 复制代码
<configuration>
    <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
    <!-- 可选:指定serverId -->
    <serverId>registry.cn-beijing.aliyuncs.com</serverId>
</configuration>
方式2:环境变量
bash 复制代码
# Linux/Mac
export DOCKER_USERNAME="username"
export DOCKER_PASSWORD="password"
export DOCKER_EMAIL="email@company.com"

# Windows
set DOCKER_USERNAME=username
set DOCKER_PASSWORD=password
方式3:系统属性
java 复制代码
# 命令行传递
mvn dockerfile:build \
  -Ddockerfile.username=user \
  -Ddockerfile.password=pass \
  -Ddockerfile.email=email@company.com
方式4:POM 属性(不推荐用于生产)
java 复制代码
<properties>
    <!-- 注意:密码会暴露在POM中 -->
    <docker.username>admin</docker.username>
    <docker.password>password123</docker.password>
</properties>

<configuration>
    <username>${docker.username}</username>
    <password>${docker.password}</password>
</configuration>
方式5:加密配置
java 复制代码
<!-- 使用Maven密码加密 -->
<server>
    <id>docker-registry</id>
    <username>{jasypt}ENC(密文)</username>
    <password>{jasypt}ENC(密文)</password>
</server>

1.3 构建参数的高级配置

动态构建参数
javascript 复制代码
<configuration>
    <buildArgs>
        <!-- Maven属性 -->
        <APP_VERSION>${project.version}</APP_VERSION>
        <BUILD_TIME>${maven.build.timestamp}</BUILD_TIME>
        <GIT_COMMIT>${git.commit.id}</GIT_COMMIT>
        <GIT_BRANCH>${git.branch}</GIT_BRANCH>
        
        <!-- 环境特定参数 -->
        <JAVA_OPTS>-Xmx512m</JAVA_OPTS>
        <SPRING_PROFILES_ACTIVE>${profiles.active}</SPRING_PROFILES_ACTIVE>
        
        <!-- 系统属性 -->
        <DEBUG_ENABLED>${debug}</DEBUG_ENABLED>
    </buildArgs>
</configuration>
条件化构建参数
java 复制代码
<configuration>
    <buildArgs>
        <!-- 根据Profile设置不同值 -->
        <ENVIRONMENT>${env.type}</ENVIRONMENT>
        <LOG_LEVEL>${log.level}</LOG_LEVEL>
    </buildArgs>
</configuration>

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <env.type>development</env.type>
            <log.level>DEBUG</log.level>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <env.type>production</env.type>
            <log.level>WARN</log.level>
        </properties>
    </profile>
</profiles>

1.4 Dockerfile 模板化

模板 Dockerfile
java 复制代码
# Dockerfile.template
FROM ${BASE_IMAGE:-openjdk:17-jdk-slim}

ARG APP_VERSION
ARG BUILD_TIME
ARG GIT_COMMIT
ARG ENVIRONMENT

LABEL version="${APP_VERSION}"
LABEL build-time="${BUILD_TIME}"
LABEL git-commit="${GIT_COMMIT}"
LABEL environment="${ENVIRONMENT}"

COPY target/${JAR_FILE} app.jar

EXPOSE ${APP_PORT:-8080}

ENTRYPOINT ["java", "-jar", "/app.jar"]
Maven资源过滤
java 复制代码
<build>
    <resources>
        <resource>
            <directory>src/main/docker</directory>
            <filtering>true</filtering>
            <includes>
                <include>Dockerfile.template</include>
            </includes>
            <targetPath>${project.build.directory}/docker</targetPath>
        </resource>
    </resources>
</build>

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>dockerfile-maven-plugin</artifactId>
    <configuration>
        <dockerfile>${project.build.directory}/docker/Dockerfile.template</dockerfile>
        <buildArgs>
            <BASE_IMAGE>${docker.base.image}</BASE_IMAGE>
            <APP_PORT>${app.port}</APP_PORT>
        </buildArgs>
    </configuration>
</plugin>

1.5 多环境配置策略

方案一:Profile 驱动
java 复制代码
<profiles>
    <!-- 开发环境 -->
    <profile>
        <id>dev</id>
        <properties>
            <docker.registry>docker.io</docker.registry>
            <docker.namespace>dev-team</docker.namespace>
            <docker.image.tag>${project.version}-SNAPSHOT</docker.image.tag>
            <docker.build.skip>false</docker.build.skip>
        </properties>
    </profile>
    
    <!-- 测试环境 -->
    <profile>
        <id>test</id>
        <properties>
            <docker.registry>harbor.test.com</docker.registry>
            <docker.namespace>qa</docker.namespace>
            <docker.image.tag>${project.version}-${build.number}</docker.image.tag>
        </properties>
    </profile>
    
    <!-- 生产环境 -->
    <profile>
        <id>prod</id>
        <properties>
            <docker.registry>registry.prod.com</docker.registry>
            <docker.namespace>production</docker.namespace>
            <docker.image.tag>${project.version}</docker.image.tag>
            <docker.base.image>prod-java:17</docker.base.image>
        </properties>
    </profile>
</profiles>
方案二:属性文件驱动
bash 复制代码
# src/main/resources/docker/docker-dev.properties
docker.registry=harbor.dev.com
docker.namespace=dev
docker.base.image=openjdk:17-jdk-slim
docker.build.args=-DskipTests
java 复制代码
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>properties-maven-plugin</artifactId>
    <version>1.0.0</version>
    <executions>
        <execution>
            <phase>initialize</phase>
            <goals>
                <goal>read-project-properties</goal>
            </goals>
            <configuration>
                <files>
                    <file>src/main/resources/docker/docker-${profiles.active}.properties</file>
                </files>
            </configuration>
        </execution>
    </executions>
</plugin>

1.6 构建优化配置

缓存优化
java 复制代码
<configuration>
    <!-- 使用特定缓存目录 -->
    <cacheDirectory>${project.build.directory}/docker-cache</cacheDirectory>
    
    <!-- 清理策略 -->
    <cleanup>true</cleanup>
    <noCache>false</noCache>
    <pullNewerImage>true</pullNewerImage>
</configuration>
构建性能优化
java 复制代码
<configuration>
    <!-- 并行构建 -->
    <parallel>true</parallel>
    
    <!-- 跳过测试 -->
    <skipDockerBuild>${skip.docker}</skipDockerBuild>
    <skipDockerTag>${skip.docker.tag}</skipDockerTag>
    <skipDockerPush>${skip.docker.push}</skipDockerPush>
    
    <!-- 详细日志 -->
    <verbose>true</verbose>
</configuration>

资源限制

java 复制代码
<configuration>
    <!-- Docker构建资源限制 -->
    <dockerBuildArgs>
        <arg>--memory=2g</arg>
        <arg>--memory-swap=2g</arg>
        <arg>--cpus=2</arg>
        <arg>--ulimit nofile=1024:1024</arg>
    </dockerBuildArgs>
</configuration>

1.7 高级执行策略

条件化执行
java 复制代码
<executions>
    <execution>
        <id>docker-build</id>
        <phase>package</phase>
        <goals>
            <goal>build</goal>
        </goals>
        <configuration>
            <skip>${skip.docker.build}</skip>
        </configuration>
    </execution>
    
    <execution>
        <id>docker-push</id>
        <phase>deploy</phase>
        <goals>
            <goal>push</goal>
        </goals>
        <configuration>
            <!-- 只在特定分支推送 -->
            <skip>${skip.docker.push}</skip>
            <tag>${docker.image.tag}</tag>
        </configuration>
        <!-- 执行条件 -->
        <conditions>
            <condition>
                <and>
                    <not>
                        <equals>${env.CI_COMMIT_REF_NAME}</equals>
                        <value>develop</value>
                    </not>
                    <matches>
                        <string>${project.version}</string>
                        <pattern>\d+\.\d+\.\d+</pattern>
                    </matches>
                </and>
            </condition>
        </conditions>
    </execution>
</executions>
多阶段执行
java 复制代码
<executions>
    <!-- 阶段1:构建测试镜像 -->
    <execution>
        <id>build-test</id>
        <phase>pre-integration-test</phase>
        <goals>
            <goal>build</goal>
        </goals>
        <configuration>
            <tag>${project.version}-test</tag>
            <buildArgs>
                <SPRING_PROFILES_ACTIVE>test</SPRING_PROFILES_ACTIVE>
            </buildArgs>
        </configuration>
    </execution>
    
    <!-- 阶段2:推送生产镜像 -->
    <execution>
        <id>push-production</id>
        <phase>deploy</phase>
        <goals>
            <goal>push</goal>
        </goals>
        <configuration>
            <tag>${project.version}</tag>
        </configuration>
    </execution>
</executions>

🔧 第二部分:Fabric8 docker-maven-plugin 深度配置

2.1 构建方式的4种模式

模式1:纯Dockerfile模式
java 复制代码
<configuration>
    <images>
        <image>
            <name>myapp:${project.version}</name>
            <build>
                <!-- 指定Dockerfile -->
                <dockerFile>${project.basedir}/Dockerfile</dockerFile>
                
                <!-- 可选:docker build参数 -->
                <dockerBuildOptions>
                    <option>--no-cache</option>
                    <option>--pull</option>
                    <option>--build-arg</option>
                    <option>HTTP_PROXY=http://proxy:8080</option>
                </dockerBuildOptions>
                
                <!-- 构建参数 -->
                <args>
                    <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
                    <BUILD_NUMBER>${build.number}</BUILD_NUMBER>
                </args>
            </build>
        </image>
    </images>
</configuration>
模式2:纯XML配置模式
java 复制代码
<build>
    <!-- 基础镜像 -->
    <from>eclipse-temurin:17-jdk-jammy</from>
    
    <!-- 维护者信息 -->
    <maintainer>devops@company.com</maintainer>
    
    <!-- 工作目录 -->
    <workdir>/app</workdir>
    
    <!-- 环境变量 -->
    <env>
        <JAVA_OPTS>-Xmx512m -Xms256m</JAVA_OPTS>
        <TZ>Asia/Shanghai</TZ>
        <LANG>en_US.UTF-8</LANG>
    </env>
    
    <!-- 复制文件 -->
    <assembly>
        <descriptorRef>artifact</descriptorRef>
        <!-- 或自定义描述符 -->
        <!-- <descriptor>assembly/docker.xml</descriptor> -->
    </assembly>
    
    <!-- 入口点 -->
    <entryPoint>
        <exec>
            <arg>java</arg>
            <arg>${JAVA_OPTS}</arg>
            <arg>-jar</arg>
            <arg>/maven/${project.build.finalName}.jar</arg>
        </exec>
    </entryPoint>
    
    <!-- 执行命令 -->
    <runCmds>
        <run>
            echo "Application starting..."
        </run>
        <run>
            chmod +x /app/entrypoint.sh
        </run>
    </runCmds>
    
    <!-- 用户 -->
    <user>1001:1001</user>
    
    <!-- 卷 -->
    <volumes>
        <volume>/app/logs</volume>
        <volume>/app/data</volume>
    </volumes>
</build>
模式3:混合模式
java 复制代码
<build>
    <!-- 基础部分用XML -->
    <from>openjdk:17-jdk-slim</from>
    <env>
        <APP_HOME>/app</APP_HOME>
    </env>
    
    <!-- 复杂部分用Dockerfile -->
    <dockerFile>Dockerfile.partial</dockerFile>
    <dockerFileDir>${project.basedir}/docker</dockerFileDir>
</build>

模式4:继承模式

java 复制代码
<images>
    <!-- 基础镜像 -->
    <image>
        <name>base-image:${java.version}</name>
        <build>
            <from>openjdk:${java.version}-jdk-slim</from>
            <runCmds>
                <run>apt-get update && apt-get install -y curl vim</run>
            </runCmds>
        </build>
    </image>
    
    <!-- 应用镜像继承基础 -->
    <image>
        <name>app:${project.version}</name>
        <build>
            <from>base-image:${java.version}</from>
            <assembly>
                <descriptorRef>artifact</descriptorRef>
            </assembly>
        </build>
    </image>
</images>

2.2 高级Assembly配置

自定义Assembly描述符
java 复制代码
<!-- src/main/assembly/docker.xml -->
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 
          http://maven.apache.org/xsd/assembly-2.1.0.xsd">
    <id>docker</id>
    <formats>
        <format>dir</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.basedir}/src/main/docker</directory>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>*.sh</include>
                <include>*.conf</include>
            </includes>
            <fileMode>0755</fileMode>
        </fileSet>
        <fileSet>
            <directory>${project.basedir}/target</directory>
            <outputDirectory>/app</outputDirectory>
            <includes>
                <include>*.jar</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${project.basedir}/config</directory>
            <outputDirectory>/app/config</outputDirectory>
        </fileSet>
    </fileSets>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/app/lib</outputDirectory>
            <scope>runtime</scope>
            <excludes>
                <exclude>${project.groupId}:${project.artifactId}</exclude>
            </excludes>
        </dependencySet>
    </dependencySets>
</assembly>

插件配置

java 复制代码
<build>
    <assembly>
        <descriptor>assembly/docker.xml</descriptor>
        <!-- 或使用内联配置 -->
        <inline>
            <id>docker-inline</id>
            <fileSets>
                <fileSet>
                    <directory>target</directory>
                    <includes>
                        <include>*.jar</include>
                    </includes>
                    <outputDirectory>/app</outputDirectory>
                </fileSet>
            </fileSets>
        </inline>
    </assembly>
</build>
分层Assembly
java 复制代码
<build>
    <assembly>
        <descriptorRef>artifact</descriptorRef>
        <targetDir>/app</targetDir>
        <!-- 分层复制 -->
        <layerConfiguration>
            <layers>
                <layer>
                    <id>dependencies</id>
                    <files>
                        <file>
                            <source>${project.build.directory}/dependency</source>
                            <outputDirectory>/app/lib</outputDirectory>
                        </file>
                    </files>
                </layer>
                <layer>
                    <id>application</id>
                    <files>
                        <file>
                            <source>target/${project.build.finalName}.jar</source>
                            <outputDirectory>/app</outputDirectory>
                        </file>
                    </files>
                </layer>
                <layer>
                    <id>resources</id>
                    <files>
                        <file>
                            <source>src/main/resources</source>
                            <outputDirectory>/app/config</outputDirectory>
                        </file>
                    </files>
                </layer>
            </layers>
        </layerConfiguration>
    </assembly>
</build>

2.3 健康检查配置

多种健康检查策略
java 复制代码
<build>
    <healthCheck>
        <!-- HTTP检查 -->
        <http>
            <url>http://localhost:${app.port}/actuator/health</url>
            <method>GET</method>
            <status>200</status>
            <!-- 或者状态范围 -->
            <statusRange>200..299</statusRange>
        </http>
        
        <!-- TCP检查 -->
        <tcp>
            <port>${app.port}</port>
            <timeout>5s</timeout>
        </tcp>
        
        <!-- 命令检查 -->
        <cmd>
            <shell>curl -f http://localhost:${app.port}/health || exit 1</shell>
            <!-- 或者 -->
            <exec>
                <arg>pgrep</arg>
                <arg>java</arg>
            </exec>
        </cmd>
        
        <!-- 复合检查 -->
        <mode>any</mode> <!-- any或all -->
        
        <!-- 参数 -->
        <interval>30s</interval>
        <timeout>10s</timeout>
        <retries>3</retries>
        <startPeriod>60s</startPeriod>
    </healthCheck>
</build>

2.4 多镜像协同配置

微服务架构示例
java 复制代码
<images>
    <!-- API Gateway -->
    <image>
        <name>gateway:${project.version}</name>
        <alias>gateway</alias>
        <build>
            <dockerFile>${project.basedir}/gateway/Dockerfile</dockerFile>
            <ports>
                <port>8080</port>
            </ports>
        </build>
        <run>
            <network>
                <name>app-network</name>
                <alias>gateway</alias>
            </network>
            <dependsOn>
                <container>user-service</container>
                <container>order-service</container>
            </dependsOn>
        </run>
    </image>
    
    <!-- User Service -->
    <image>
        <name>user-service:${project.version}</name>
        <alias>user-service</alias>
        <build>
            <dockerFile>${project.basedir}/user-service/Dockerfile</dockerfile>
            <ports>
                <port>8081</port>
            </ports>
        </build>
        <run>
            <env>
                <DB_HOST>mysql</DB_HOST>
                <REDIS_HOST>redis</REDIS_HOST>
            </env>
        </run>
    </image>
    
    <!-- MySQL -->
    <image>
        <name>mysql:8.0</name>
        <alias>mysql</alias>
        <external>
            <type>compose</type>
            <alias>mysql</alias>
        </external>
    </image>
</images>

<!-- 网络配置 -->
<networks>
    <network>
        <name>app-network</name>
        <driver>bridge</driver>
        <labels>
            <env>${profiles.active}</env>
        </labels>
    </network>
</networks>

2.5 运行时配置详解

完整运行配置
java 复制代码
<run>
    <!-- 容器名称 -->
    <name>${project.artifactId}-${profiles.active}</name>
    
    <!-- 主机名 -->
    <hostname>app-${project.artifactId}</hostname>
    
    <!-- 域名 -->
    <domainname>internal.company.com</domainname>
    
    <!-- 用户 -->
    <user>appuser:appgroup</user>
    
    <!-- 重启策略 -->
    <restartPolicy>
        <name>on-failure</name>
        <retry>5</retry>
    </restartPolicy>
    
    <!-- 端口映射 -->
    <ports>
        <port>8080:8080</port>
        <port>5005:5005</port> <!-- 调试端口 -->
    </ports>
    
    <!-- 环境变量 -->
    <env>
        <JAVA_OPTS>-Xmx512m -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005</JAVA_OPTS>
        <SPRING_PROFILES_ACTIVE>${profiles.active}</SPRING_PROFILES_ACTIVE>
        <TZ>Asia/Shanghai</TZ>
    </env>
    
    <!-- 卷挂载 -->
    <volumes>
        <bind>
            <volume>/host/logs:/app/logs</volume>
            <volume>/host/config:/app/config:ro</volume>
        </bind>
        <from>
            <image>config-volume:latest</image>
        </from>
    </volumes>
    
    <!-- 网络 -->
    <network>
        <name>app-network</name>
        <aliases>
            <alias>${project.artifactId}</alias>
        </aliases>
    </network>
    
    <!-- 链接 -->
    <links>
        <link>mysql:db</link>
        <link>redis:cache</link>
    </links>
    
    <!-- 依赖 -->
    <dependsOn>
        <container>mysql</container>
        <container>redis</container>
    </dependsOn>
    
    <!-- 资源限制 -->
    <resource>
        <memory>1g</memory>
        <memorySwap>2g</memorySwap>
        <cpuShares>512</cpuShares>
        <cpuQuota>50000</cpuQuota>
        <cpuPeriod>100000</cpuPeriod>
    </resource>
    
    <!-- 健康检查 -->
    <healthcheck>
        <test>["CMD", "curl", "-f", "http://localhost:8080/health"]</test>
        <interval>30s</interval>
        <timeout>10s</timeout>
        <retries>3</retries>
        <startPeriod>40s</startPeriod>
    </healthcheck>
    
    <!-- 等待条件 -->
    <wait>
        <http>
            <url>http://localhost:8080/actuator/health</url>
            <status>200</status>
        </http>
        <time>120000</time>
        <shutdown>5000</shutdown>
    </wait>
    
    <!-- 日志配置 -->
    <log>
        <prefix>${project.artifactId}</prefix>
        <color>green</color>
        <enabled>true</enabled>
        <driver>json-file</driver>
        <opts>
            <max-size>10m</max-size>
            <max-file>3</max-file>
        </opts>
    </log>
    
    <!-- 标签 -->
    <labels>
        <env>${profiles.active}</env>
        <version>${project.version}</version>
        <maintainer>devops@company.com</maintainer>
    </labels>
    
    <!-- 特权模式 -->
    <privileged>false</privileged>
    
    <!-- 只读根文件系统 -->
    <readOnly>false</readOnly>
    
    <!-- 自动删除 -->
    <autoRemove>true</autoRemove>
    
    <!-- 入口点覆盖 -->
    <entrypoint>
        <arg>java</arg>
        <arg>-jar</arg>
        <arg>/app/app.jar</arg>
    </entrypoint>
</run>
开发环境特殊配置
java 复制代码
<profile>
    <id>dev</id>
    <properties>
        <docker.run.debug>true</docker.run.debug>
    </properties>
</profile>

<run>
    <!-- 开发模式特殊配置 -->
    <env>
        <JAVA_OPTS>${docker.run.debug ? '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Dspring.devtools.restart.enabled=true' : ''}</JAVA_OPTS>
    </env>
    <ports>
        <port>8080:8080</port>
        <port>${docker.run.debug ? '5005:5005' : ''}</port>
    </ports>
    <volumes>
        <bind>
            <volume>${project.basedir}/src:/app/src:ro</volume>
            <volume>${project.basedir}/target/classes:/app/classes</volume>
        </bind>
    </volumes>
</run>

2.6 Docker Compose集成

完整的Compose配置
java 复制代码
<configuration>
    <!-- Docker Compose配置 -->
    <compose>
        <!-- Compose文件 -->
        <composeFile>${project.basedir}/docker-compose.yml</composeFile>
        <composeFile>${project.basedir}/docker-compose.override.yml</composeFile>
        
        <!-- 启动配置 -->
        <up>
            <detached>true</detached>
            <build>true</build>
            <forceBuild>${docker.compose.force.build}</forceBuild>
            <recreate>true</recreate>
            <removeOrphans>true</removeOrphans>
            <wait>true</wait>
            <waitTimeout>300</waitTimeout>
            <waitLog>Service started</waitLog>
            <scale>
                <service>app=2</service>
                <service>nginx=1</service>
            </scale>
        </up>
        
        <!-- 停止配置 -->
        <down>
            <removeVolumes>true</removeVolumes>
            <removeImages>all</removeImages>
            <removeOrphans>true</removeOrphans>
            <timeout>10</timeout>
        </down>
        
        <!-- 日志配置 -->
        <logs>
            <follow>false</follow>
            <timestamps>true</timestamps>
            <tail>100</tail>
        </logs>
        
        <!-- 环境变量 -->
        <envProperties>
            <ENV>${profiles.active}</ENV>
            <APP_VERSION>${project.version}</APP_VERSION>
        </envProperties>
        
        <!-- 项目名称 -->
        <projectName>${project.artifactId}-${profiles.active}</projectName>
    </compose>
</configuration>
动态Compose生成
java 复制代码
<plugin>
    <groupId>io.fabric8</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>generate-compose</id>
            <phase>process-resources</phase>
            <goals>
                <goal>resource</goal>
            </goals>
            <configuration>
                <images>
                    <!-- 镜像定义 -->
                </images>
                <generator>
                    <config>
                        <compose>
                            <enabled>true</enabled>
                            <name>${project.artifactId}</name>
                            <version>3.8</version>
                            <outputFile>${project.build.directory}/docker-compose.yml</outputFile>
                        </compose>
                    </config>
                </generator>
            </configuration>
        </execution>
    </executions>
</plugin>

2.7 监控与日志集成

Prometheus监控配置
java 复制代码
<build>
    <!-- 添加监控agent -->
    <runCmds>
        <run>
            wget -O /app/jmx_prometheus_javaagent.jar \
            https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.19.0/jmx_prometheus_javaagent-0.19.0.jar
        </run>
    </runCmds>
    
    <!-- 暴露监控端口 -->
    <ports>
        <port>9090</port>
    </ports>
    
    <!-- 监控配置 -->
    <env>
        <JAVA_OPTS>-javaagent:/app/jmx_prometheus_javaagent.jar=9090:/app/config/prometheus.yml ${JAVA_OPTS}</JAVA_OPTS>
    </env>
</build>

<assembly>
    <fileSets>
        <fileSet>
            <directory>${project.basedir}/monitoring</directory>
            <outputDirectory>/app/config</outputDirectory>
            <includes>
                <include>prometheus.yml</include>
                <include>alert-rules.yml</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>

集中式日志配置

java 复制代码
<run>
    <log>
        <driver>fluentd</driver>
        <opts>
            <fluentd-address>fluentd:24224</fluentd-address>
            <tag>docker.{{.Name}}</tag>
            <labels>env,version</labels>
            <env>OS,SPRING_PROFILES_ACTIVE</env>
        </opts>
    </log>
    
    <env>
        <LOG_LEVEL>${log.level}</LOG_LEVEL>
        <LOG_FORMAT>json</LOG_FORMAT>
        <LOG_APPENDER>CONSOLE,FILE</LOG_APPENDER>
    </env>
    
    <labels>
        <log.rotate>daily</log.rotate>
        <log.retention>30d</log.retention>
    </labels>
</run>

2.8 安全增强配置

安全上下文配置
java 复制代码
<run>
    <!-- 安全选项 -->
    <securityOpts>
        <securityOpt>no-new-privileges</securityOpt>
        <securityOpt>label=type:svirt_apache_t</securityOpt>
    </securityOpts>
    
    <!-- Capabilities -->
    <capAdd>
        <cap>CHOWN</cap>
    </capAdd>
    <capDrop>
        <cap>ALL</cap>
    </capDrop>
    
    <!-- 只读根文件系统 -->
    <readOnly>true</readOnly>
    
    <!-- 临时文件系统 -->
    <tmpfs>
        <mount>/tmp</mount>
        <mount>/run</mount>
    </tmpfs>
</run>
镜像签名验证
java 复制代码
<configuration>
    <!-- 镜像验证 -->
    <imageVerification>
        <enabled>true</enabled>
        <verify>always</verify>
        <failOnMissing>true</failOnMissing>
        <registry>docker.io</registry>
        <publicKey>${docker.signing.key}</publicKey>
    </imageVerification>
    
    <!-- 内容信任 -->
    <contentTrust>
        <enabled>true</enabled>
        <server>https://notary.docker.io</server>
    </contentTrust>
</configuration>

🎯 第三部分:高级集成方案

3.1 与CI/CD工具集成

Jenkins Pipeline集成
java 复制代码
// Jenkinsfile
pipeline {
    agent any
    
    environment {
        DOCKER_REGISTRY = 'registry.company.com'
        DOCKER_NAMESPACE = 'team'
    }
    
    stages {
        stage('Build') {
            steps {
                script {
                    // 使用Spotify插件
                    sh 'mvn clean package -DskipTests'
                }
            }
        }
        
        stage('Build Docker Image') {
            steps {
                script {
                    // 选择插件
                    if (params.DOCKER_PLUGIN == 'spotify') {
                        sh '''
                            mvn dockerfile:build \
                                -Ddockerfile.repository=${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/${JOB_NAME} \
                                -Ddockerfile.tag=${BUILD_NUMBER}
                        '''
                    } else if (params.DOCKER_PLUGIN == 'fabric8') {
                        sh '''
                            mvn docker:build \
                                -Ddocker.image.name=${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/${JOB_NAME} \
                                -Ddocker.image.tag=${BUILD_NUMBER}
                        '''
                    }
                }
            }
        }
        
        stage('Push Image') {
            steps {
                withCredentials([
                    usernamePassword(
                        credentialsId: 'docker-registry',
                        usernameVariable: 'DOCKER_USER',
                        passwordVariable: 'DOCKER_PASS'
                    )
                ]) {
                    script {
                        sh '''
                            echo "${DOCKER_PASS}" | docker login ${DOCKER_REGISTRY} \
                                -u "${DOCKER_USER}" --password-stdin
                            
                            if [ "$DOCKER_PLUGIN" = "spotify" ]; then
                                mvn dockerfile:push \
                                    -Ddockerfile.username=${DOCKER_USER} \
                                    -Ddockerfile.password=${DOCKER_PASS}
                            else
                                mvn docker:push \
                                    -Ddocker.username=${DOCKER_USER} \
                                    -Ddocker.password=${DOCKER_PASS}
                            fi
                        '''
                    }
                }
            }
        }
        
        stage('Scan Image') {
            steps {
                script {
                    // 镜像安全扫描
                    sh 'trivy image ${DOCKER_REGISTRY}/${DOCKER_NAMESPACE}/${JOB_NAME}:${BUILD_NUMBER}'
                }
            }
        }
    }
}
GitLab CI集成
java 复制代码
# .gitlab-ci.yml
variables:
  DOCKER_REGISTRY: "registry.gitlab.com"
  DOCKER_NAMESPACE: "${CI_PROJECT_PATH}"

stages:
  - build
  - test
  - package
  - deploy

build-maven:
  stage: build
  image: maven:3.9.6-eclipse-temurin-17
  script:
    - mvn clean compile
  artifacts:
    paths:
      - target/

build-docker-spotify:
  stage: package
  image: docker:20.10
  services:
    - docker:20.10-dind
  variables:
    DOCKER_HOST: "tcp://docker:2375"
    DOCKER_TLS_CERTDIR: ""
  script:
    - |
      mvn dockerfile:build \
        -Ddockerfile.repository=${DOCKER_REGISTRY}/${DOCKER_NAMESPACE} \
        -Ddockerfile.tag=${CI_COMMIT_SHORT_SHA} \
        -Ddockerfile.username=${CI_REGISTRY_USER} \
        -Ddockerfile.password=${CI_REGISTRY_PASSWORD}
  only:
    - master
    - tags

build-docker-fabric8:
  stage: package
  image: docker:20.10
  services:
    - docker:20.10-dind
  variables:
    DOCKER_HOST: "tcp://docker:2375"
  script:
    - |
      mvn docker:build \
        -Ddocker.registry=${DOCKER_REGISTRY} \
        -Ddocker.image.name=${DOCKER_NAMESPACE} \
        -Ddocker.image.tag=${CI_COMMIT_SHORT_SHA}
  only:
    - develop

push-image:
  stage: deploy
  image: docker:20.10
  services:
    - docker:20.10-dind
  script:
    - docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${DOCKER_REGISTRY}
    - |
      if [ "$DOCKER_PLUGIN" = "spotify" ]; then
        mvn dockerfile:push
      else
        mvn docker:push
      fi
  only:
    - master
    - tags

3.2 多模块项目配置

父POM配置
java 复制代码
<!-- parent/pom.xml -->
<properties>
    <docker.plugin>fabric8</docker.plugin>
    <docker.registry>registry.company.com</docker.registry>
    <docker.namespace>${project.groupId}</docker.namespace>
    <docker.base.image>openjdk:17-jdk-slim</docker.base.image>
</properties>

<build>
    <pluginManagement>
        <plugins>
            <!-- Spotify插件管理 -->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.4.13</version>
                <configuration>
                    <skip>${skip.docker}</skip>
                    <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
                </configuration>
            </plugin>
            
            <!-- Fabric8插件管理 -->
            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.41.0</version>
                <configuration>
                    <skip>${skip.docker}</skip>
                    <images>
                        <image>
                            <name>${docker.registry}/${docker.namespace}/${project.artifactId}:${project.version}</name>
                        </image>
                    </images>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

<profiles>
    <profile>
        <id>docker-all</id>
        <modules>
            <module>service-a</module>
            <module>service-b</module>
            <module>gateway</module>
        </modules>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>build-all-docker</id>
                            <phase>package</phase>
                            <goals>
                                <goal>exec</goal>
                            </goals>
                            <configuration>
                                <executable>mvn</executable>
                                <arguments>
                                    <argument>-pl</argument>
                                    <argument>service-a,service-b,gateway</argument>
                                    <argument>-am</argument>
                                    <argument>clean</argument>
                                    <argument>package</argument>
                                    <argument>${docker.plugin}:build</argument>
                                    <argument>-DskipTests</argument>
                                </arguments>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
子模块配置
java 复制代码
<!-- service-a/pom.xml -->
<build>
    <plugins>
        <plugin>
            <groupId>${docker.plugin.groupId}</groupId>
            <artifactId>${docker.plugin.artifactId}</artifactId>
            <configuration>
                <!-- 通用配置继承父POM -->
                <!-- 模块特定覆盖 -->
                <dockerfile>${project.basedir}/Dockerfile.service</dockerfile>
                <buildArgs>
                    <SERVICE_NAME>${project.artifactId}</SERVICE_NAME>
                    <SERVICE_PORT>8081</SERVICE_PORT>
                </buildArgs>
            </configuration>
        </plugin>
    </plugins>
</build>

3.3 条件化构建策略

基于分支的构建
java 复制代码
<configuration>
    <skip>${skip.docker.build}</skip>
    <tags>
        <tag>${project.version}</tag>
        <!-- 分支特定标签 -->
        <tag>${env.GIT_BRANCH}</tag>
        <!-- 条件化标签 -->
        <tag>${env.GIT_BRANCH == 'master' ? 'latest' : 'snapshot'}</tag>
    </tags>
</configuration>

构建触发器

java 复制代码
<executions>
    <execution>
        <id>docker-build-on-release</id>
        <phase>package</phase>
        <goals>
            <goal>build</goal>
        </goals>
        <configuration>
            <skip>${skip.docker.build}</skip>
            <!-- 只在发布版本构建 -->
            <filter>${project.version}</filter>
            <includes>
                <include>**/*-RELEASE.jar</include>
                <include>**/*-FINAL.jar</include>
            </includes>
        </configuration>
    </execution>
    
    <execution>
        <id>docker-push-on-tag</id>
        <phase>deploy</phase>
        <goals>
            <goal>push</goal>
        </goals>
        <configuration>
            <!-- 只在Git标签时推送 -->
            <skip>${env.GIT_TAG == ''}</skip>
            <tag>${env.GIT_TAG}</tag>
        </configuration>
    </execution>
</executions>

3.4 性能优化配置

并行构建优化
java 复制代码
<configuration>
    <!-- Spotify并行构建 -->
    <parallel>true</parallel>
    <threads>4</threads>
    
    <!-- Fabric8构建优化 -->
    <buildOptions>
        <dockerBuildOptions>
            <option>--parallel</option>
            <option>--memory=2g</option>
            <option>--cpus=2</option>
        </dockerBuildOptions>
    </buildOptions>
    
    <!-- 缓存优化 -->
    <cacheFrom>
        <cache>${docker.registry}/${docker.namespace}/${project.artifactId}:latest</cache>
    </cacheFrom>
    <cacheTo>
        <cache>type=registry,ref=${docker.registry}/${docker.namespace}/${project.artifactId}:buildcache</cache>
    </cacheTo>
</configuration>
分层构建优化
java 复制代码
<!-- 对于Spring Boot应用 -->
<build>
    <env>
        <JAR_LAYERS_ENABLED>true</JAR_LAYERS_ENABLED>
        <SPRING_BOOT_LAYERED_ENABLED>true</SPRING_BOOT_LAYERED_ENABLED>
    </env>
    
    <runCmds>
        <!-- 使用Spring Boot分层JAR -->
        <run>
            java -Djarmode=layertools -jar application.jar extract
        </run>
    </runCmds>
    
    <assembly>
        <layers>
            <layer>
                <id>dependencies</id>
                <includes>
                    <include>**/*.jar</include>
                </includes>
                <layerConfiguration>dependencies</layerConfiguration>
            </layer>
            <layer>
                <id>spring-boot-loader</id>
                <layerConfiguration>spring-boot-loader</layerConfiguration>
            </layer>
            <layer>
                <id>snapshot-dependencies</id>
                <layerConfiguration>snapshot-dependencies</layerConfiguration>
            </layer>
            <layer>
                <id>application</id>
                <layerConfiguration>application</layerConfiguration>
            </layer>
        </layers>
    </assembly>
</build>

📊 第四部分:对比总结与选择建议

4.1 详细功能对比矩阵

功能维度 Spotify Fabric8 优胜方
基础构建 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ 平手
认证管理 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ Fabric8
多镜像支持 ⭐⭐ ⭐⭐⭐⭐⭐ Fabric8
运行时控制 ⭐⭐ ⭐⭐⭐⭐⭐ Fabric8
网络管理 ⭐⭐⭐⭐⭐ Fabric8
存储卷 ⭐⭐⭐⭐⭐ Fabric8
健康检查 ⭐⭐ ⭐⭐⭐⭐⭐ Fabric8
资源限制 ⭐⭐⭐⭐⭐ Fabric8
Compose集成 ⭐⭐⭐⭐⭐ Fabric8
监控集成 ⭐⭐⭐⭐ Fabric8
安全特性 ⭐⭐ ⭐⭐⭐⭐ Fabric8
构建性能 ⭐⭐⭐⭐ ⭐⭐⭐⭐ 平手
配置灵活性 ⭐⭐⭐ ⭐⭐⭐⭐⭐ Fabric8
文档完整性 ⭐⭐⭐⭐ ⭐⭐⭐⭐ 平手
社区活跃度 ⭐⭐ ⭐⭐⭐⭐⭐ Fabric8

4.2 具体场景选择指南

场景1:简单单服务应用

**# 选择: Spotify
理由:

  • 配置简单,学习成本低
  • 已有Dockerfile可复用
  • 构建速度快
    配置要点:
  1. 使用默认Dockerfile位置
  2. Maven settings管理认证
  3. 基础构建参数即可**
场景2:微服务架构

**# 选择: Fabric8
理由:

  • 多镜像统一管理
  • 服务依赖和网络配置
  • 完整的运行时控制
    配置要点:
  1. 使用XML定义所有服务
  2. 配置服务间网络
  3. 健康检查和依赖管理**
场景3:CI/CD流水线

**# 选择: 根据团队熟悉度
Spotify优势:

  • 命令简单明了
  • 环境变量支持好
  • 与大多数CI工具兼容**

**Fabric8优势:

  • 丰富的构建后操作
  • 自动生成Compose文件
  • 集成测试支持**

**推荐配置:

  1. 统一认证管理
  2. 标签策略标准化
  3. 构建缓存优化**
场景4:本地开发环境

**# 选择: Fabric8
理由:

  • Docker Compose集成
  • 热重载支持
  • 开发环境特殊配置
    配置要点:
  1. 开发模式Volume映射
  2. 调试端口暴露
  3. 快速重启配置**

4.3最佳实践总结

通用最佳实践
  1. 版本固定:始终固定插件版本

  2. 认证安全:使用Maven settings或环境变量

  3. 构建可重现:固定基础镜像版本

  4. 镜像标签:使用语义化版本控制

  5. 构建缓存:合理利用Docker层缓存

Spotify特有实践
  1. Dockerfile规范:遵循最佳实践编写

  2. .dockerignore:减少构建上下文大小

  3. 多阶段构建:减少最终镜像大小

  4. 构建参数:使用ARG传递动态值

Fabric8特有实践
  1. 配置模块化:拆分不同环境的配置

  2. 健康检查:配置完善的健康检查

  3. 资源限制:设置合理的资源限制

  4. 监控集成:集成应用监控

  5. 安全加固:应用容器安全最佳实践

4.4未来趋势

Spotify插件状态
  • 当前状态:已归档,不再维护

  • 建议:现有项目可继续使用,新项目考虑迁移

  • 替代方案:Google Jib、Buildpacks

Fabric8发展方向
  • 活跃维护,持续更新

  • 云原生特性增强

  • Kubernetes集成深化

  • 安全特性加强

新兴技术
  1. Google Jib:无需Docker守护进程

  2. Buildpacks:标准化构建流程

  3. ko(Go应用):极简容器构建

  4. nixpacks:多语言支持

🎁 第五部分:实用工具和脚本

5.1 辅助脚本

构建检查脚本
bash 复制代码
#!/bin/bash
# check-docker-build.sh

set -e

echo "🔍 Docker构建环境检查"

# 检查Docker
if ! command -v docker &> /dev/null; then
    echo "❌ Docker未安装"
    exit 1
fi
echo "✅ Docker已安装: $(docker --version)"

# 检查Docker运行状态
if ! docker info &> /dev/null; then
    echo "❌ Docker守护进程未运行"
    exit 1
fi
echo "✅ Docker守护进程运行正常"

# 检查Maven
if ! command -v mvn &> /dev/null; then
    echo "❌ Maven未安装"
    exit 1
fi
echo "✅ Maven已安装: $(mvn --version | head -1)"

# 检查插件
echo "📦 检查Maven插件..."
if mvn help:describe -Dplugin=dockerfile-maven-plugin -Ddetail &> /dev/null; then
    echo "✅ Spotify插件已安装"
else
    echo "⚠️  Spotify插件未安装"
fi

if mvn help:describe -Dplugin=docker-maven-plugin -Ddetail &> /dev/null; then
    echo "✅ Fabric8插件已安装"
else
    echo "⚠️  Fabric8插件未安装"
fi

# 检查Dockerfile
if [ -f "Dockerfile" ]; then
    echo "✅ Dockerfile存在"
    echo "  大小: $(wc -l < Dockerfile) 行"
else
    echo "⚠️  Dockerfile不存在"
fi

# 检查settings.xml认证
if [ -f "$HOME/.m2/settings.xml" ]; then
    if grep -q "docker.io\|registry" "$HOME/.m2/settings.xml"; then
        echo "✅ Maven settings包含Docker认证"
    else
        echo "⚠️  Maven settings中未找到Docker认证"
    fi
fi

echo ""
echo "🎉 环境检查完成!"
批量构建脚本
bash 复制代码
#!/bin/bash
# multi-build.sh

# 配置
REGISTRY="registry.company.com"
NAMESPACE="team"
PROJECTS=("service-a" "service-b" "gateway")
TAG="${1:-latest}"
PLUGIN="${2:-fabric8}" # spotify 或 fabric8

# 颜色输出
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m' # No Color

echo -e "${GREEN}🚀 开始批量构建${NC}"
echo "仓库: ${REGISTRY}/${NAMESPACE}"
echo "标签: ${TAG}"
echo "插件: ${PLUGIN}"
echo "项目: ${PROJECTS[*]}"
echo ""

success_count=0
fail_count=0

for project in "${PROJECTS[@]}"; do
    echo -e "\n📦 构建项目: ${project}"
    
    if [ ! -d "$project" ]; then
        echo -e "${RED}❌ 项目目录不存在: ${project}${NC}"
        fail_count=$((fail_count+1))
        continue
    fi
    
    cd "$project" || continue
    
    # 选择插件构建
    if [ "$PLUGIN" = "spotify" ]; then
        mvn_cmd="mvn dockerfile:build \
            -Ddockerfile.repository=${REGISTRY}/${NAMESPACE}/${project} \
            -Ddockerfile.tag=${TAG} \
            -DskipTests"
    else
        mvn_cmd="mvn docker:build \
            -Ddocker.registry=${REGISTRY} \
            -Ddocker.namespace=${NAMESPACE} \
            -Ddocker.image.name=${project} \
            -Ddocker.image.tag=${TAG} \
            -DskipTests"
    fi
    
    if eval "$mvn_cmd"; then
        echo -e "${GREEN}✅ ${project} 构建成功${NC}"
        success_count=$((success_count+1))
    else
        echo -e "${RED}❌ ${project} 构建失败${NC}"
        fail_count=$((fail_count+1))
    fi
    
    cd ..
done

echo -e "\n📊 构建结果:"
echo -e "${GREEN}成功: ${success_count}${NC}"
echo -e "${RED}失败: ${fail_count}${NC}"

if [ $fail_count -eq 0 ]; then
    echo -e "\n🎉 所有项目构建成功!"
    exit 0
else
    echo -e "\n😞 有项目构建失败"
    exit 1
fi

5.2 配置生成器

Dockerfile模板生成
java 复制代码
// DockerfileGenerator.java
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

public class DockerfileGenerator {
    
    public static void generate(String templateFile, Map<String, String> variables, 
                                String outputFile) throws IOException {
        String template = readTemplate(templateFile);
        
        for (Map.Entry<String, String> entry : variables.entrySet()) {
            template = template.replace("${" + entry.getKey() + "}", entry.getValue());
        }
        
        try (FileWriter writer = new FileWriter(outputFile)) {
            writer.write(template);
        }
        
        System.out.println("✅ Dockerfile已生成: " + outputFile);
    }
    
    private static String readTemplate(String templateFile) throws IOException {
        // 读取模板文件
        return Files.readString(Paths.get(templateFile));
    }
    
    public static void main(String[] args) {
        Map<String, String> vars = new HashMap<>();
        vars.put("BASE_IMAGE", "openjdk:17-jdk-slim");
        vars.put("MAINTAINER", "devops@company.com");
        vars.put("APP_PORT", "8080");
        vars.put("BUILD_TIME", LocalDateTime.now().format(
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        
        try {
            generate("Dockerfile.template", vars, "Dockerfile");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

5.3 监控和告警

构建监控脚本
bash 复制代码
#!/bin/bash
# monitor-build.sh

# 监控Docker构建,发送告警

LOG_FILE="docker-build.log"
ALERT_EMAIL="devops@company.com"
SLACK_WEBHOOK="https://hooks.slack.com/services/xxx"

# 监控函数
monitor_build() {
    local project=$1
    local start_time=$(date +%s)
    
    echo "$(date): 开始构建 $project" >> "$LOG_FILE"
    
    # 执行构建
    if mvn clean package docker:build -DskipTests; then
        local end_time=$(date +%s)
        local duration=$((end_time - start_time))
        
        echo "$(date): $project 构建成功,耗时 ${duration}秒" >> "$LOG_FILE"
        
        # 发送成功通知
        send_notification "success" "$project" "$duration"
    else
        echo "$(date): $project 构建失败" >> "$LOG_FILE"
        
        # 发送失败告警
        send_notification "failure" "$project"
        
        # 收集错误信息
        collect_errors "$project"
    fi
}

# 发送通知
send_notification() {
    local status=$1
    local project=$2
    local duration=$3
    
    if [ "$status" = "success" ]; then
        # Slack通知
        curl -X POST -H 'Content-type: application/json' \
            --data "{\"text\":\"✅ $project 构建成功,耗时 ${duration}秒\"}" \
            "$SLACK_WEBHOOK"
    else
        # 邮件告警
        echo "项目 $project 构建失败,请检查!" | \
            mail -s "Docker构建告警: $project" "$ALERT_EMAIL"
        
        # Slack告警
        curl -X POST -H 'Content-type: application/json' \
            --data "{\"text\":\"🚨 $project 构建失败,需要立即处理!\"}" \
            "$SLACK_WEBHOOK"
    fi
}

# 收集错误信息
collect_errors() {
    local project=$1
    local error_file="errors/$project-$(date +%Y%m%d-%H%M%S).log"
    
    # 收集最后100行日志
    tail -100 build.log > "$error_file"
    
    # 收集Docker错误
    docker ps -a --filter "name=$project" --format "table {{.Names}}\t{{.Status}}" >> "$error_file"
    
    # 收集系统资源
    echo "=== 系统资源 ===" >> "$error_file"
    free -h >> "$error_file"
    echo "" >> "$error_file"
    df -h >> "$error_file"
}

# 主监控循环
main() {
    while true; do
        for project in $(find . -name "pom.xml" -type f | xargs dirname); do
            if [ -f "$project/pom.xml" ]; then
                cd "$project" || continue
                monitor_build "$(basename "$project")"
                cd - > /dev/null
            fi
        done
        
        # 每小时检查一次
        sleep 3600
    done
}

# 启动监控
main

📚 总结

本文详细介绍了 Spotify dockerfile-maven-plugin 和 Fabric8 docker-maven-plugin 的各种灵活配置方式,涵盖:

  1. 基础到高级的配置方案

  2. 多种认证管理策略

  3. 多环境、多模块支持

  4. 性能优化和安全加固

  5. CI/CD集成方案

  6. 实用工具和脚本

核心建议:

  1. 新项目首选 Fabric8:功能丰富,活跃维护

  2. 简单项目可用 Spotify:配置简单,学习成本低

  3. 重视安全性:妥善管理认证信息

  4. 自动化一切:集成到CI/CD流水线

  5. 监控和告警:及时发现和解决问题

相关推荐
小敬爱吃饭2 分钟前
Ragflow Docker部署及问题解决方案(界面为Welcome to nginx,ragflow上传文件失败,Docker中的ragflow-cpu-1一直重启)
人工智能·python·nginx·docker·语言模型·容器·数据挖掘
MaCa .BaKa11 分钟前
47-心里健康咨询平台/心理咨询系统
java·spring boot·mysql·tomcat·maven·intellij-idea·个人开发
木子欢儿30 分钟前
Docker Hub 镜像发布指南
java·spring cloud·docker·容器·eureka
coppher2 小时前
Ubuntu 22.04 amd64 离线安装 Docker 完整教程
linux·docker
虚伪的空想家3 小时前
k8s集群configmap和secrets备份脚本
linux·容器·kubernetes
SXJR3 小时前
k8s中的Pod
云原生·容器·kubernetes
文静小土豆3 小时前
K8s 滚动更新在 Java 应用中的实践与优化
java·容器·kubernetes
w6100104664 小时前
CKA-2026-Ingress
云原生·容器·kubernetes·cka
enAn_4 小时前
对照片和视频文件名,程序追加日期,直观看
java·maven
bloglin999994 小时前
docker logs 如何一直监听日志输出
运维·docker·容器