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. 监控和告警:及时发现和解决问题

相关推荐
ascarl20102 小时前
准确--Kubernetes 修改 NodePort 端口范围操作文档
云原生·容器·kubernetes
从零开始学习人工智能2 小时前
解决Docker容器无法访问宿主机IP和端口的全维度实践指南
tcp/ip·docker·容器
运维技术小记2 小时前
以Jellyfin为例,给群晖NAS容器里的应用升级
容器
隔壁阿布都2 小时前
Docker 安装 Redis
redis·docker·容器
xUxIAOrUIII3 小时前
JWT和拦截器使用【附Maven中操作步骤】
java·maven
程序员老赵3 小时前
Apache IoTDB Docker 容器化部署指南:从入门到生产环境实践
docker·apache
少陽君3 小时前
Kubernetes Debug 专用镜像实践指南
云原生·容器·kubernetes
一过菜只因3 小时前
Docker入门
运维·docker·容器
weixin_46683 小时前
K8S-RBAC2
docker·容器·kubernetes