🚀 从 Java 到 Docker:一位八年开发的容器化实战笔记
作为一名有着八年 Java 开发经验的工程师,我经历了从传统部署到容器化的完整转变。本文将基于实际项目经验,深入介绍 Docker 的核心用法,如何使用数据卷实现持久化(以 MySQL 为例),以及如何通过 Dockerfile 和一键部署脚本,将微服务项目轻松部署到服务器。
🧱 为什么选择 Docker?
回顾过去,部署一个 Java 服务意味着手动配置环境、上传 .jar 包、启动服务。每个环境可能稍有不同,导致“在我这能跑啊”的经典问题层出不穷。
Docker 提供了解决方案:
- ✅ 一致的运行环境(容器即环境)
- ✅ 快速部署和回滚
- ✅ 易于集成 CI/CD 流程
- ✅ 支持微服务架构的天然载体
📦 Docker 基础命令速查
刚接触 Docker 的同学可以先了解以下常用命令:
# 拉取镜像
docker pull mysql:8.0
# 查看镜像
docker images
# 启动容器
docker run -d -p 3306:3306 --name mysql-test mysql:8.0
# 查看容器
docker ps -a
# 停止容器
docker stop 容器ID
# 删除容器
docker rm 容器ID
# 删除镜像
docker rmi 镜像ID
💾 MySQL 数据持久化挂载实践
在开发中,我们经常需要本地运行 MySQL。当使用 Docker 启动 MySQL 时,如果不挂载数据卷,容器一删,数据就没了。下面是我实际使用的挂载方案。
🧪 场景需求
我们期望:
- 数据库存储在宿主机固定目录
- 即使容器被删除,数据依然保留
- 下次启动容器时只要挂载同一个目录即可
✅ 持久化挂载命令
docker run -d \
--name mysql-dev \
-e MYSQL_ROOT_PASSWORD=root1234 \
-p 3306:3306 \
-v /mydata/mysql/conf:/etc/mysql/conf.d \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/logs:/var/log/mysql \
mysql:8.0
📁 挂载说明
| 挂载路径 | 宿主机目录 | 作用 |
|---|---|---|
/mydata/mysql/data | /var/lib/mysql | 存储数据库数据 |
/mydata/mysql/conf | /etc/mysql/conf.d | 自定义配置文件 |
/mydata/mysql/logs | /var/log/mysql | 日志输出 |
📌 验证持久化效果
- 进入数据库创建一个数据库:
CREATE DATABASE test_db;
- 删除容器:
docker rm -f mysql-dev
- 重新运行容器(挂载相同路径):
docker run -d \
--name mysql-dev \
-e MYSQL_ROOT_PASSWORD=root1234 \
-p 3306:3306 \
-v /mydata/mysql/conf:/etc/mysql/conf.d \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/logs:/var/log/mysql \
mysql:8.0
- 登录后查看数据库是否还在:
SHOW DATABASES;
-- 可以看到 test_db 仍然存在
🎉 成功实现数据持久化!
🧩 微服务项目 Dockerfile 编写实战
作为 Java 开发我们最常打包的是 Spring Boot 服务,假设我们的项目结构如下:
my-microservice/
├── Dockerfile
├── target/
│ └── app.jar
└── ...
✍️ 示例 Dockerfile
# 使用官方 OpenJDK 基础镜像
FROM openjdk:17-jdk-alpine
# 作者信息
LABEL maintainer="your.email@example.com"
# 设置时区
ENV TZ=Asia/Shanghai
# 创建目录
RUN mkdir /app
# 设置工作目录
WORKDIR /app
# 拷贝 jar 文件
COPY target/app.jar app.jar
# 暴露端口
EXPOSE 8080
# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]
🔨 构建镜像
docker build -t my-microservice:1.0 .
🚀 启动容器
docker run -d \
--name microservice-dev \
-p 8080:8080 \
my-microservice:1.0
⚙️ 一键部署脚本(适用于 Linux 服务器)
为了快速部署,我们可以写一个一键部署脚本 deploy.sh:
#!/bin/bash
APP_NAME="my-microservice"
VERSION="1.0"
PORT=8080
echo "🚀 停止并删除旧容器..."
docker stop $APP_NAME
docker rm $APP_NAME
echo "🔄 构建镜像..."
docker build -t $APP_NAME:$VERSION .
echo "🚀 启动新容器..."
docker run -d \
--name $APP_NAME \
-p $PORT:8080 \
$APP_NAME:$VERSION
echo "✅ 部署完成!"
使用方式:
chmod +x deploy.sh
./deploy.sh
🛠️ 多服务部署推荐:Docker Compose
如果你有多个服务(如:MySQL、Redis、Gateway、User-Service),强烈推荐使用 docker-compose 来管理。
📄 示例 docker-compose.yml
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: root1234
volumes:
- ./mysql/data:/var/lib/mysql
ports:
- "3306:3306"
redis:
image: redis:6.2
ports:
- "6379:6379"
user-service:
build:
context: ./user-service
ports:
- "8081:8080"
depends_on:
- mysql
- redis
启动所有服务:
docker-compose up -d
🧠 最后的思考
Docker 改变的不只是部署方式,更是我们整个研发流程的思维方式。对 Java 开发者来说,掌握 Docker 已不再是加分项,而是基础技能。
“懂 Docker 的 Java 工程师,才是真正的现代开发者。”