1. 故事背景

每当春暖花开的下午,小王总是对着新完成的Spring Boot应用发愁。他的本地开发环境完美无缺,但上服务器就像换了台陌生电脑——这场景像极了网购时的"卖家秀"和"买家秀"。今天我们就要破解这个魔咒,手把手带你把应用装进行李箱(Jar包),再放进万能集装箱(Docker)。

2. 传统手工打包:Jar包的奇妙旅程

2.1 基础打包配方

// 必须的pom.xml配置片段
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <!-- 像给外卖贴标签,明确主菜位置 -->
                <mainClass>com.example.DemoApplication</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

执行打包咒语:

mvn clean package -DskipTests

2.2 那些年踩过的坑

# 错误示范:以为在吃自助餐却拿了限定餐
java -jar myapp.jar --server.port=8080 
# 正确打开方式:外置配置文件的秘密通道
java -Dspring.config.location=/opt/config/application.properties -jar myapp.jar

3. Docker魔法:让应用住在标准集装箱

3.1 制作你的专属镜像

# Dockerfile的精致配方
FROM openjdk:11-jre-slim  # 选餐厅的基础盘子

# 环境变量就像给容器准备的备忘录
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime

# 复制应用像放入微波炉的便当
COPY target/myapp.jar /app.jar 

# 暴露端口就像挂出营业招牌
EXPOSE 8080

# 开机启动命令就像说"芝麻开门"
ENTRYPOINT ["java","-jar","/app.jar"]

构建命令:

docker build -t myapp:1.0.0 . 

3.2 进阶版多阶段构建

# 阶段1:生产车间
FROM maven:3.8.6-jdk-11 AS build
WORKDIR /workspace
COPY . .
RUN mvn package -DskipTests

# 阶段2:精品包装
FROM openjdk:11-jre-slim
COPY --from=build /workspace/target/myapp.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

4. 现实舞台上的表演时刻

4.1 组合技能:Docker Compose

version: '3.8'
services:
  myapp:
    image: myapp:1.0.0
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
    volumes:
      - "/data/logs:/var/log/myapp"
  
  redis:
    image: redis:6.2-alpine
    ports:
      - "6379:6379"

4.2 健康检查魔法

HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8080/actuator/health || exit 1

5. 技术选择的红玫瑰与白玫瑰

5.1 应用场景对对碰

  • Jar包部署适合:小型项目、快速验证、单机环境
  • Docker化适合:微服务架构、集群部署、CI/CD流水线

5.2 优缺点比较表

比较项 Jar部署 Docker部署
环境依赖 需预装JDK 只需Docker环境
启动速度 快如猎豹 稍慢但稳定
资源占用 较轻量级 需要镜像存储空间
配置管理 外部文件分散 环境变量统一管理
跨平台能力 依赖JVM版本 真正的跨平台运行

6. 前辈们的经验笔记本

  1. 内存陷阱:Java应用要预留容器内存,使用"-XX:MaxRAMPercentage=75.0"
  2. 时间迷宫:容器内时区要显式设置,避免日志时间错乱
  3. 镜像膨胀:定期清理无用镜像,避免仓库变成垃圾场
  4. 日志管理:挂载volume持久化日志,防止容器销毁丢失证据
  5. 安全红线:永远不要使用root用户运行应用容器

7. 总结:从背包客到集装箱运输

当我们完成了这段奇幻旅程,终于理解部署的本质是创造可重复的确定性。就像把自家腌制的泡菜装进标准罐头,无论在哪台服务器打开都能保持相同风味。选择Jar部署如同带着背包自由行,Docker则像预定全套旅行套餐,各有所长但最终殊途同归。