Docker原理和使用指南、常用命令、Compose多容器部署

一、Docker 核心原理

1.1 什么是Docker?

Docker 是一款开源的容器化引擎,基于Linux内核虚拟化技术实现,可将应用程序(如Java项目)及其依赖、环境、配置打包成标准化容器,实现一次打包、随处运行。

对于Java工程师而言,核心解决的痛点:解决本地开发、测试、生产环境不一致问题(解决"本地能跑,线上报错"),同时实现服务快速部署、扩容、迁移。

1.2 核心三大概念(必懂)

1、镜像(Image)

Docker镜像就是一个只读的模板,相当于Java项目的"打包模板"。

镜像包含了运行应用所需的完整环境:操作系统极简内核、JDK、运行依赖、项目Jar包、配置文件等。

类比Java:镜像 = 编译好的Jar包 + 完整运行环境

2、容器(Container)

容器是镜像的运行实例,是独立的、可运行的隔离环境。

镜像只读,容器在镜像基础上添加了一层可读写层,每个容器相互隔离、互不影响,资源独立。

类比Java:镜像 = 类,容器 = new出来的实例对象

3、仓库(Repository)

用于存放Docker镜像的远程仓库,分为公共仓库(Docker Hub)和私有仓库(公司内网仓库),用于镜像的上传、下载、版本管理。

1.3 Docker 核心原理优势(对比虚拟机)

很多Java开发者会混淆Docker容器和虚拟机,核心区别如下:

  • 虚拟机:模拟完整硬件 + 完整操作系统,体积大(GB级)、启动慢、资源占用高

  • Docker容器:共享宿主机Linux内核,仅打包应用和依赖,体积小(MB级)、秒级启动、资源占用极低

核心底层技术: Namespace(资源隔离)、Cgroup(资源限制)、UnionFS(镜像分层存储),这也是Docker轻量、高效的核心原因。

二、Docker 核心常用命令(开发高频)

所有命令基于Docker官方标准语法,按使用场景分类,适配Java日常开发、部署、排查问题。

2.1 基础信息命令

用于查看Docker版本、运行状态、系统信息

Plain 复制代码
# 查看Docker版本
docker version

# 查看Docker详细系统信息
docker info

# 检查Docker是否启动成功
docker ps

2.2 镜像操作命令(重点)

Java打包、拉取环境镜像(JDK、Maven、MySQL、Nginx等)必备

Plain 复制代码
# 1、查看本地所有镜像
docker images

# 2、从远程仓库拉取镜像(以JDK8、MySQL8为例)
docker pull openjdk:8-jdk-alpine
docker pull mysql:8.0

# 3、搜索远程仓库镜像
docker search jdk

# 4、删除本地镜像(镜像ID可通过docker images查看)
docker rmi 镜像ID/镜像名

# 5、构建自定义镜像(核心!Java项目打包必备)
# 语法:docker build -t 镜像名:版本号 Dockerfile路径
docker build -t java-demo:1.0 .

# 6、镜像重命名、打标签
docker tag 旧镜像名:版本 新镜像名:版本

# 7、导出/导入镜像(离线部署用)
docker save -o 保存文件名.tar 镜像名:版本
docker load -i 文件名.tar

2.3 容器操作命令(高频使用)

启动、停止、排查Java容器服务核心命令

Plain 复制代码
# 1、查看正在运行的容器
docker ps

# 2、查看所有容器(包含已停止的)
docker ps -a

# 3、启动容器(Java项目最常用启动命令)
# 语法:docker run [参数] 镜像名:版本
# 常用参数说明:
# -d 后台运行、--name 自定义容器名、-p 宿主机端口:容器端口(端口映射)
# --restart=always 开机自启
docker run -d --name java-demo -p 8080:8080 --restart=always java-demo:1.0

# 4、停止/启动/重启容器
docker stop 容器ID/容器名
docker start 容器ID/容器名
docker restart 容器ID/容器名

# 5、删除容器(必须先停止容器)
docker rm 容器ID/容器名
# 强制删除运行中的容器
docker rm -f 容器ID/容器名

# 6、进入容器内部(排查Java日志、配置文件必备)
docker exec -it 容器名 /bin/sh
# 退出容器:exit

# 7、查看容器日志(排查项目报错核心命令)
docker logs 容器名
# 实时滚动查看日志(重点!)
docker logs -f 容器名

# 8、查看容器资源占用(CPU、内存)
docker stats

2.4 数据卷与挂载命令(Java项目必备)

解决容器删除后数据丢失、配置文件持久化问题,用于挂载Java配置文件、日志、数据库数据

Plain 复制代码
# 创建数据卷
docker volume create 卷名

# 查看所有数据卷
docker volume ls

# 挂载目录启动容器(常用:宿主机目录挂载到容器,修改配置无需重启镜像)
docker run -d -p 8080:8080 -v /宿主机路径:/容器内路径 java-demo:1.0

2.5 系统清理命令(开发常用)

清理无用镜像、容器、缓存,释放服务器资源

Plain 复制代码
# 清理所有停止的容器、悬空镜像、缓存
docker system prune

# 彻底清理无用资源(谨慎使用)
docker system prune -a

三、Java工程师专属核心知识点

3.1 Docker部署Java项目核心流程

  1. Maven/Gradle 打包项目生成 Jar 包

  2. 编写 Dockerfile 构建脚本(定义JDK环境、拷贝Jar、启动命令)

  3. 通过 docker build 构建自定义项目镜像

  4. 通过 docker run 启动容器,映射端口,完成部署

3.2 最简Java项目Dockerfile模板(可直接复用)

Plain 复制代码
# 基础镜像:轻量化JDK8
FROM openjdk:8-jdk-alpine
# 维护者信息
MAINTAINER java-dev
# 拷贝本地Jar包到容器内
COPY target/demo.jar /app.jar
# 容器启动命令,运行Java项目
ENTRYPOINT ["java","-jar","/app.jar"]
# 暴露端口(仅声明,不生效,需配合-p映射)
EXPOSE 8080

四、常见问题总结

  • 容器重启后数据丢失:未做数据卷挂载,容器读写层临时生效,删除容器数据清空

  • 外部访问不到Java服务:端口映射错误、服务器防火墙未开放端口、项目监听地址为localhost

  • 镜像体积过大:使用alpine轻量化镜像、清理冗余依赖、分层构建

五、Docker Compose 多容器部署实操教程(Java+MySQL+Redis)

在实际Java项目开发与部署中,单个容器无法满足业务需求,绝大多数项目需要同时依赖Java服务、MySQL数据库、Redis缓存多个组件。Docker Compose 是Docker官方的多容器编排工具,可通过一个YAML配置文件统一管理多个容器的创建、启动、停止、网络互通,无需逐个手动执行docker run命令,极大提升多服务部署效率,是Java开发运维必备技能。

5.1 Docker Compose 核心基础

5.1.1 核心作用

  • 统一编排:通过 docker-compose.yml 配置文件,定义多个容器的镜像、端口、挂载、依赖、网络

  • 一键操作:单命令完成多容器批量启动、停止、重启、删除,无需逐个操作容器

  • 自动组网:默认创建专属虚拟网络,实现Java、MySQL、Redis容器跨容器互通(核心解决多服务通信问题)

  • 环境统一:所有服务配置固化,开发、测试、生产环境完全一致

5.1.2 前置条件

  • Docker 已正常安装启动(主流Docker版本默认自带Compose插件,无需单独安装)

  • 准备好可正常运行的Java SpringBoot项目(打包为Jar包)

  • 服务器/本地环境端口8080、3306、6379未被占用

5.1.3 核心语法说明

docker-compose.yml 核心关键字(Java项目高频使用):

  • version:Compose配置文件版本,推荐3.8及以上兼容所有新特性

  • services:定义所有容器服务(java、mysql、redis)

  • image:指定容器镜像,自定义Java服务可通过build构建

  • ports:端口映射(宿主机端口:容器端口)

  • volumes:数据卷挂载,实现数据持久化、配置挂载

  • environment:容器环境变量(数据库账号密码、配置参数等)

  • depends_on:服务启动依赖,控制启动顺序(先启动数据库、缓存,再启动Java服务)

  • restart:容器重启策略,保障服务异常自动恢复

5.2 项目整体目录结构

标准化部署目录,规范文件管理,可直接复用

Plain 复制代码
java-docker-compose/
├── docker-compose.yml  # 核心编排配置文件
├── Dockerfile          # Java项目镜像构建文件
├── target/
│   └── demo.jar        # SpringBoot打包后的Jar包
├── mysql/
│   └── data/           # MySQL数据持久化目录
└── redis/
    └── data/           # Redis数据持久化目录

5.3 完整配置文件编写

5.3.1 Java项目Dockerfile(复用优化版)

优化轻量化镜像,删除废弃参数,适配Compose部署

Plain 复制代码
# 轻量化JDK8基础镜像
FROM openjdk:8-jdk-alpine
# 拷贝Jar包到容器工作目录
COPY target/demo.jar /app.jar
# 暴露服务端口
EXPOSE 8080
# 启动Java项目,添加JVM基础参数
ENTRYPOINT ["java","-Xms256m","-Xmx512m","-jar","/app.jar"]

5.3.2 核心:docker-compose.yml 完整配置

包含Java、MySQL8.0、Redis完整配置,支持数据持久化、开机自启、顺序启动、网络互通,可直接复制使用

Plain 复制代码
# Compose配置版本
version: '3.8'

# 定义所有服务容器
services:
  # MySQL数据库服务
  mysql:
    image: mysql:8.0
    container_name: java-mysql
    restart: always
    ports:
      - "3306:3306"
    # 数据库环境变量配置
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: demo_db
      MYSQL_USER: java_user
      MYSQL_PASSWORD: 123456
      TZ: Asia/Shanghai
    # 数据卷挂载,持久化数据库数据
    volumes:
      - ./mysql/data:/var/lib/mysql
    # 容器网络时区配置
    networks:
      - java-net

  # Redis缓存服务
  redis:
    image: redis:6.2-alpine
    container_name: java-redis
    restart: always
    ports:
      - "6379:6379"
    # Redis持久化配置
    volumes:
      - ./redis/data:/data
    # Redis启动参数,开启持久化
    command: redis-server --appendonly yes
    networks:
      - java-net

  # Java SpringBoot服务
  java-app:
    # 基于当前目录Dockerfile构建镜像
    build: .
    container_name: java-app
    restart: always
    ports:
      - "8080:8080"
    # 依赖先行启动的数据库和缓存服务
    depends_on:
      - mysql
      - redis
    networks:
      - java-net

# 定义专属自定义网络,实现多容器互通
networks:
  java-net:
    driver: bridge

5.4 Java项目配置适配(关键)

Docker容器互通不能使用localhost/127.0.0.1,需使用容器名作为服务地址,修改SpringBoot项目application.yml/application.properties配置

5.4.1 application.yml 配置示例

Plain 复制代码
spring:
  # MySQL数据库配置
  datasource:
    url: jdbc:mysql://java-mysql:3306/demo_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
    username: java_user
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  # Redis缓存配置
  redis:
    host: java-redis
    port: 6379

核心关键点 :数据库host填写配置文件中的mysql容器名 java-mysql,Redis host填写 java-redis,Compose自动通过容器名解析IP,实现跨容器通信。

5.5 Docker Compose 核心实操命令

所有命令需在 docker-compose.yml 所在目录 执行,为日常部署、运维高频命令

Plain 复制代码
【重要版本说明】
1. 旧版Docker(1.20及以下):使用带横杠命令 docker-compose
2. 新版Docker(20.10+ 主流版本):官方标准为 无横杠 docker compose
3. 新版完全兼容旧命令,本文统一更新为【官方最新标准命令】

# 1、后台启动所有服务(最常用,部署核心命令)
docker compose up -d

# 2、查看所有服务运行状态
docker compose ps

# 3、实时查看所有服务日志
docker compose logs -f

# 4、重启指定单个服务(无需重启所有服务)
docker compose restart java-app
docker compose restart mysql

# 5、停止所有服务,保留容器、镜像、数据卷
docker compose stop

# 6、停止并删除所有容器(保留数据卷和镜像)
docker compose down

# 7、彻底销毁所有容器、网络、镜像(清空环境,谨慎使用)
docker compose down --rmi all -v

5.6 完整部署流程(从零到上线)

  1. 项目打包:IDEA中执行Maven package,生成target/demo.jar包

  2. 整理目录:按照上述目录结构,上传Jar包、Dockerfile、yml配置文件到服务器

  3. 创建目录:执行mkdir -p mysql/data redis/data 创建持久化目录

  4. 启动服务:在根目录执行 docker-compose up -d 一键启动所有服务

  5. 验证服务:通过docker-compose ps查看运行状态,访问8080端口测试项目

  6. 查看日志:执行 docker compose logs -f 排查项目启动报错、运行异常

5.7 高频问题排查(Java专属)

  • 问题1:Java服务启动报错,连接MySQL/Redis失败

    原因:使用localhost地址、容器名写错、depends_on仅控制启动顺序,不等待服务完全就绪

    解决方案:改用容器名连接,项目添加重连机制,或添加健康检查

  • 问题2:重启容器后数据库数据丢失

    原因:未配置数据卷挂载、本地挂载目录权限不足

    解决方案:确认volumes配置生效,授权目录权限 chmod 777 -R mysql/ redis/

  • 问题3:修改Java代码后部署不生效

    原因:镜像未重新构建,依然使用旧镜像

    解决方案:执行 docker compose up -d --build 重新构建镜像并启动

  • 问题4:端口冲突报错

    原因:宿主机3306、6379、8080端口被占用

    解决方案:修改compose文件端口映射,或关闭占用端口的进程

5.8 生产环境优化建议

  • 开启日志持久化,配置容器日志大小限制,避免日志占满磁盘

  • 为Java服务添加JVM参数优化,适配容器内存资源

  • 生产环境关闭Redis默认外网访问,配置密码认证

  • 生产环境关闭Redis默认外网访问,配置密码认证

  • 通过环境变量统一管理敏感配置(数据库密码等),避免硬编码

5.9 Docker 容器日志全套实操(tail -f 实时排查)

Docker部署Java项目后,日常排查BUG、查看启动报错、实时监控运行日志是高频操作。原生Linux tail -f 无法直接查看容器内部日志,需使用Docker专属日志命令,下面整理开发/生产最常用的日志查询指令,等价、强化原生tail实时监控能力。

5.9.1 基础日志命令(替代 tail -f)

适用于所有Docker容器(Java、MySQL、Redis通用),核心满足实时滚动查看日志需求

Plain 复制代码
# 1、实时跟踪日志(完全等价:tail -f 实时刷新)
docker logs -f 容器名/容器ID

# 2、实时跟踪 + 只查看最后N行(重点常用!避免日志刷屏)
# 示例:只监听最新100行日志并实时刷新
docker logs -f --tail=100 java-app

# 3、查看历史全部日志(静态输出,不实时刷新)
docker logs java-app

# 4、查看带时间戳的日志(精准定位报错时间)
docker logs -f -t --tail=100 java-app

5.9.2 Docker Compose 专属日志命令(多容器适配)

针对当前Java+MySQL+Redis多容器场景,支持批量查看、单独查看指定服务日志

Plain 复制代码
# 1、实时查看所有服务日志(全部容器日志合并输出)
docker compose logs -f

# 2、只实时查看Java服务日志(精准排查项目问题,核心推荐)
docker compose logs -f --tail=100 java-app

# 3、单独查看MySQL/Redis日志
docker compose logs -f --tail=50 mysql
docker compose logs -f --tail=50 redis

5.9.3 日志筛选过滤(精准排查报错)

结合grep过滤异常、ERROR、WARN信息,快速定位Java项目BUG,生产排查必备

Plain 复制代码
# 实时监控并只输出报错日志
docker logs -f --tail=200 java-app | grep ERROR

# 实时过滤异常堆栈信息
docker logs -f java-app | grep Exception

# 过滤带关键字的日志(如数据库、Redis报错)
docker logs -f java-app | grep 数据库

5.9.4 容器日志原理与持久化说明

  • 日志存储位置:Docker默认将容器控制台日志存储在宿主机磁盘,无需进入容器即可查看

  • Java项目适配:SpringBoot项目默认控制台输出的日志,均可通过上述命令捕获;若需持久化文件日志,可挂载宿主机日志目录

  • 退出日志监控 :按下 Ctrl + C 即可退出实时监听,不会停止容器服务

5.9.5 常见日志排查问题

  • 日志刷屏太快 :搭配 --tail 指定行数,减少冗余日志输出

  • 查不到最新报错 :确认容器正常运行,使用 -f 实时监听,不要只查静态日志

  • 日志过多占满磁盘:生产环境需配置Docker日志大小限制,防止日志无限堆积

(注:文档部分内容可能由 AI 生成)

相关推荐
着迷不白1 小时前
实战一:用户、权限、组 案例
linux·运维
乐兮创想 小林1 小时前
企业官网的运维分工模型:内容自助、Bug 终身免费修与服务器托管的边界设计
运维·服务器·bug·网站建设·企业官网·北京网站建设公司
乐兮创想 小林1 小时前
生物科技官网的工程化设计:产品×应用二维信息架构、多语言与国际化 SEO 实践
运维·服务器·bug·网站建设·企业官网·北京网站建设公司
三无推导1 小时前
One API Docker 部署实战:从 0 搭建多模型统一接口管理平台
运维·ubuntu·docker·容器·github·api网关·token管理
超级大福宝1 小时前
在 Ghostty 中用 SSH 连接到服务器不能正常显示颜色的问题
运维·服务器·ssh
tang7451639621 小时前
Huawei Cloud EulerOS 2.0(x8664)安装OpenJDK 2120260323
linux·运维·centos
Black蜡笔小新1 小时前
零代码自动化企业私有化AI训练推理一体工作站DLTM重塑安全监控全智能自治新体系
运维·人工智能·自动化
biter down2 小时前
8:YAML 语法
运维·python
TechWJ2 小时前
被 Intercom Zendesk收费坑过?我用Chatwoot搭了个免费客服站
docker·ai·开源·客服·chatwoot