这篇文章记录了我在 Windows 系统下使用 Docker 命令行打包并运行 Java 应用的完整流程。所采用的 Java 应用是一个已经打包好的 Spring Boot JAR 文件。本文特别适合 Docker 入门学习者参考实践。


1. 准备工作

  • Docker Desktop 已安装并启动(Windows 下必须依赖它)

  • 已经有一个可执行的 Java JAR 包


2. Dockerfile 编写

在项目根目录新建 Dockerfile 文件:

FROM openjdk:17-jdk-slim

COPY target/example-1.0-SNAPSHOT.jar app.jar

ENTRYPOINT ["java", "-jar", "/app.jar"]

逐行解释:

  1. FROM openjdk:17-jdk-slim

    • 指定基础镜像,这里选择的是官方的 OpenJDK 17 的精简版本。

    • 基础镜像里已经装好了 JDK,我们不需要自己再安装。

    • slim 版本体积更小,镜像构建出来更轻量。

  2. COPY target/example-1.0-SNAPSHOT.jar app.jar

    • 把宿主机上的 JAR 包复制进镜像。

    • 前面是宿主机路径,后面是镜像内的目标路径。

    • 这里我们把它命名为 app.jar,避免名字太长。

  3. ENTRYPOINT ["java", "-jar", "/app.jar"]

    • 设置容器启动时要运行的命令。

    • 这里就是用 java -jar 来运行我们打包好的应用。

    • 使用 JSON 数组格式(["..."]),比字符串写法更安全,不会被 shell 解释错误。


3. 构建镜像

执行:

docker build -t example:1.0 -t example:latest .

  • example:1.0 → 带版本号的镜像

  • example:latest→ 最新版本别名,方便直接使用

  • 也可以只指定一个镜像名,比如

    docker build -t example:1.0


4. 容器运行与端口绑定

运行一个实例

docker run -d -p 8080:8080 --name example-container example:latest

解释:

  • -p 8080:8080 → 把宿主机的 8080 端口映射到容器内的 8080 端口。访问http://localhost:8080 就能连上容器内的服务。

  • --name → 给容器取个名字,方便管理。

同时运行多个实例

docker run -d -p 8080:8080 --name example-container-v1 example:latest


docker run -d -p 8081:8080 --name example-container-v2 example:latest

小技巧:宿主机端口:容器端口 的左边必须唯一,但右边(容器端口)通常保持不变。


5. 查看和管理

查看镜像:docker images

docker images

查看容器(包括已停止):

docker ps -a

停止并删除容器:

docker stop <容器名>


docker rm <容器名>


6. 数据持久化(Volumes)

容器是一次性的,删除后数据会丢失。要保留数据,必须挂载卷或目录

方式一:绑定宿主机目录(Bind mount)

docker run -d -p 8080:8080 --name example-container -v <硬盘日志文件路径>:/app/logs example:latest

优点:你可以直接在资源管理器看到日志文件,方便查看或编辑。
缺点:和宿主机的路径耦合,不够通用。

方式二:使用 Docker Volume

让 Docker 自己管理存储:

docker volume create example-logs


docker run -d -p 8080:8080 --name example-container -v example-logs:/app/logs example:latest

卷的特点:

  • 存放位置

    • Linux 下 → /var/lib/docker/volumes/<卷名>/_data/

    • Windows 下 → 在 Docker Desktop 内部的虚拟机里,不直接暴露在 C 盘

  • 如何查看卷内容

    •  查看卷信息

    • docker volume inspect example-logs

    • 或用临时容器挂载卷:

    • docker run --rm -it -v example-logs:/data alpine sh
      cd /data && ls -l

  • 适用场景
    • Bind mount → 适合日志、配置文件

    • Volume → 适合数据库、缓存等长期数据,更稳定,升级容器也不会受影响


7. 概念总结

  • 镜像 (Image):应用的打包快照(只读)

  • 容器 (Container):镜像的运行实例(可写)

  • 卷 (Volume):独立于容器的数据存储(持久化)

  • 端口绑定:把容器里的端口暴露给宿主机,从而对外提供服务


8. 下一步学习方向:Docker 网络

当你需要多个容器协作(比如 Java 应用要连接 MySQL 容器),就会涉及 Docker 网络

下一章会介绍:

  1. 默认网络模式:bridge、host、none

  2. 自定义 bridge 网络:让容器之间通过名字互相访问

  3. 容器互联:跨容器通信的几种方式

  4. 端口映射与外部访问:如何把容器服务暴露给宿主机和外网

  5. 多容器编排(预告):docker-compose 如何简化网络与服务管理

更多推荐