Docker入门

大家好,这依旧是一篇个人笔记,本次笔记内容是有关于Docker容器

本次笔记内容对应黑马JAVA WEB课程的191-197集

本次笔记由workbuddy协同完成,不喜勿喷,谢谢

一、Docker 核心概念

1.1 什么是 Docker

Docker 是一个开源的容器化平台,可以将应用程序及其依赖打包成一个标准化的单元(容器),实现快速部署和运行。

1.2 核心概念

|-----------------|---------------------------------|
| 概念 | 说明 |
| 镜像 (Image) | 一个只读的模板,包含运行应用所需的代码、库、环境变量和配置文件 |
| 容器 (Container) | 镜像的运行实例,是独立、隔离的运行环境 |
| 镜像仓库 (Registry) | 存储和分发镜像的服务,如 Docker Hub |

1.3 镜像命名规范

镜像名称格式:

复制代码
[repository]:[tag]

# 示例
nginx:latest
mysql:8.0
redis:7-alpine

二、Docker 常用命令

2.1 镜像操作命令

|-----------------------|--------------------|
| 命令 | 作用 |
| docker pull 镜像名 | 从仓库拉取镜像 |
| docker images | 查看本地所有镜像 |
| docker rmi 镜像ID | 删除指定镜像 |
| docker build -t 镜像名 . | 根据 Dockerfile 构建镜像 |

2.2 容器操作命令

|---------------------------|---------------|
| 命令 | 作用 |
| docker run 镜像名 | 创建并启动容器 |
| docker ps | 查看运行中的容器 |
| docker ps -a | 查看所有容器(包括停止的) |
| docker start 容器ID | 启动已停止的容器 |
| docker stop 容器ID | 停止运行中的容器 |
| docker rm 容器ID | 删除容器 |
| docker logs 容器ID | 查看容器日志 |
| docker exec -it 容器ID bash | 进入容器内部执行命令 |

2.3 docker run 常用参数

|-----------|--------------------|
| 参数 | 说明 |
| -d | 后台运行(守护模式) |
| --name | 为容器指定名称 |
| -p | 端口映射,格式 宿主机端口:容器端口 |
| -e | 设置环境变量 |
| -v | 挂载数据卷或目录 |
| --network | 指定容器网络 |

三、端口映射

3.1 端口映射的目的

容器是隔离的运行环境,外部无法直接访问容器内部。端口映射将宿主机的端口与容器端口关联,使外部请求可以通过宿主机访问容器服务。

3.2 端口映射的原理

当外部访问宿主机的某个端口时,Docker 会将请求转发到映射的容器端口,实现内外通信。

3.3 宿主机概念

宿主机(Host)是运行 Docker 的物理机或虚拟机。容器运行在宿主机上,共享宿主机的内核资源。

3.4 端口映射示例

复制代码
# 将宿主机的 80 端口映射到容器的 80 端口
docker run -d -p 80:80 --name nginx nginx:latest

# 将宿主机的 8080 端口映射到容器的 80 端口
docker run -d -p 8080:80 --name nginx nginx:latest

四、数据卷 (Volume)

4.1 为什么需要数据卷

Docker 容器默认是临时的,容器删除后数据会丢失。而且容器内部通常缺少 vim 等编辑工具,直接修改容器内文件不方便。

docker创建的容器很多linux有的命令都没有的,包括vim这种编辑文件的命令

因此,如果想要变价docker容器里面的文件的话,就必须借助"数据卷"

数据卷简单来说就是通过映射的形式把dockers容器里面的文件映射到宿主机上面,然后你要编辑docker文件的话直接编辑宿主机上面的映射文件即可

4.2 什么是数据卷

数据卷是一个虚拟目录,是容器内目录与宿主机目录之间的映射桥梁。通过数据卷,可以将容器内的文件映射到宿主机上,实现数据的持久化和便捷编辑。

4.3 数据卷操作命令

|--------------------------|-----------|
| 命令 | 作用 |
| docker volume create 卷名 | 创建数据卷 |
| docker volume ls | 查看所有数据卷 |
| docker volume rm 卷名 | 删除数据卷 |
| docker volume inspect 卷名 | 查看数据卷详情 |
| docker volume prune | 清理未使用的数据卷 |

4.4 数据卷挂载示例

复制代码
# 使用 -v 参数挂载数据卷
docker run -d \
  --name nginx \
  -p 80:80 \
  -v html:/usr/share/nginx/html \
  nginx:latest

提示

数据卷挂载后,修改宿主机上的映射文件会立即反映到容器中,反之亦然。

4.5 本地目录挂载

使用数据卷时,Docker 会自动管理存储位置(通常在 /var/lib/docker/volumes/ 下),路径较深不便操作。可以使用本地目录挂载,自定义宿主机路径:

复制代码
# 使用绝对路径或相对路径挂载本地目录
docker run -d \
  --name nginx \
  -p 80:80 \
  -v /home/user/nginx/html:/usr/share/nginx/html \
  nginx:latest

# 或使用相对路径(以 ./ 或 ../ 开头)
docker run -d \
  --name nginx \
  -p 80:80 \
  -v ./html:/usr/share/nginx/html \
  nginx:latest

4.6 两种挂载方式对比

|---------|-------------|---------------|
| 对比项 | 数据卷挂载 | 本地目录挂载 |
| 语法 | -v 卷名:容器路径 | -v /本地路径:容器路径 |
| 存储位置 | Docker 自动管理 | 用户自定义 |
| 适用场景 | 临时数据、缓存 | 配置文件、持久化数据 |

五、自定义镜像

5.1 镜像结构

Docker 镜像采用分层结构:

|------------|---------------------------------|
| 层级 | 说明 |
| BaseImage | 基础镜像层,包含基础系统文件(如 CentOS、Ubuntu) |
| Layer | 中间层,执行各种构建指令(如安装 JDK、复制应用文件) |
| Entrypoint | 入口层,配置容器启动时执行的命令 |

5.2 Dockerfile 常用指令

|------------|-------------|
| 指令 | 说明 |
| FROM | 指定基础镜像 |
| ENV | 设置环境变量 |
| COPY | 复制本地文件到镜像中 |
| RUN | 执行命令(构建时执行) |
| EXPOSE | 声明容器暴露的端口 |
| ENTRYPOINT | 容器启动时执行的命令 |

5.3 构建 Java 镜像示例

以下是一个构建 Java 应用的 Dockerfile 示例:

复制代码
# 基于 CentOS 7 基础镜像
FROM centos:7

# 设置环境变量
ENV JAVA_DIR=/usr/local

# 复制 JDK 和应用 jar 包到镜像
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar

# 解压 JDK 并配置环境变量
RUN cd $JAVA_DIR \
 && tar -xf ./jdk8.tar.gz \
 && mv ./jdk1.8.0_144 ./java8

ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin

# 暴露端口
EXPOSE 8090

# 容器启动命令
ENTRYPOINT ["java", "-jar", "/tmp/app.jar"]

5.4 构建镜像命令

复制代码
# 构建镜像
# -t: 指定镜像名称和标签
# .: 指定 Dockerfile 所在目录
docker build -t my-java-app:1.0 .

六、Docker 网络

6.1 默认网络的问题

默认情况下,Docker 创建的容器都连接到 Docker 自带的虚拟网桥。容器之间可以通过 IP 地址通信,但容器 IP 是随机分配的。如果容器重启,IP 地址会改变,导致依赖该 IP 的其他容器无法正常访问。

默认情况下,docker创建的容器都是连接到dockers自己提供的一个虚拟网桥上面,各个容器之间可以通过访问ip的形式去实现容器之间的通信(比如java引用去连接数据库)

但是由于ip地址是随机分配的,如果一开始先启动了一个容器A,并且容器B已经通过ip地址的形式和容器A实现了通信,这个时候关闭容器A再打开,此时容器A的ip地址就会发生改变,但是容器B访问的那个ip地址还是旧的容器A的地址,那就需要修改,非常不方便

因此为了应对这种情况,我们就可以自定义网络

6.2 自定义网络解决方案

创建自定义网络后,将容器加入该网络,容器之间可以通过容器名称(而非 IP)互相访问。即使容器重启导致 IP 变化,名称解析仍然有效。

6.3 网络操作命令

|---------------------------------|----------|
| 命令 | 作用 |
| docker network create 网络名 | 创建自定义网络 |
| docker network ls | 查看所有网络 |
| docker network rm 网络名 | 删除网络 |
| docker network connect 网络 容器 | 将容器连接到网络 |
| docker network disconnect 网络 容器 | 将容器从网络断开 |
| docker network inspect 网络名 | 查看网络详情 |

6.4 自定义网络使用示例

复制代码
# 1. 创建自定义网络
docker network create my-network

# 2. 启动容器时连接到自定义网络
docker run -d \
  --name mysql \
  --network my-network \
  -e MYSQL_ROOT_PASSWORD=123456 \
  mysql:8.0

# 3. Java 应用容器通过容器名访问 MySQL
docker run -d \
  --name java-app \
  --network my-network \
  -e DB_HOST=mysql \
  my-java-app:1.0

# 在 Java 应用中,使用 mysql 作为数据库主机名即可
相关推荐
吳所畏惧36 分钟前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
张忠琳1 小时前
【NVIDIA】 NVIDIA Container Toolkit v1.19.1 — OCI 模块超深度分析之三
云原生·容器·架构·kubernetes·nvidia
HiDev_1 小时前
【非标自动化】2、认识元器件(确定目标)
运维·自动化
Zhang~Ling2 小时前
从 fopen 到 struct file:从零开始拆解 Linux 文件 I/O
linux·运维·服务器
爱写代码的森2 小时前
蒙三方库 | harmony-utils之FileUtil文件重命名与属性查询详解
linux·运维·服务器·华为·harmonyos·鸿蒙·huawei
Elastic 中国社区官方博客2 小时前
将你的 Grafana Kubernetes 仪表板迁移到 Elastic Observability:相同的 PromQL,30 倍更快的查询
大数据·人工智能·elasticsearch·搜索引擎·容器·kubernetes·grafana
中微极客2 小时前
2026主流AI Agent框架技术选型与性能对比
运维·网络·人工智能
久曲健的测试窝3 小时前
智能座舱自动化测试落地方案:数字仿真搭配实车实测,解决用例运维与场景失真难题
运维
AOwhisky3 小时前
Python 学习笔记(第十五期)——运维自动化(下·后篇):堡垒机实战——paramiko高阶篇
运维·python·学习·云原生·自动化·运维开发
重生的黑客4 小时前
Linux 进程优先级、切换与调度:从孤儿进程到 O(1) 调度模型
linux·运维·服务器·进程优先级·nice