Contents

Docker学习笔记

本篇学习笔记是在学习 黑马的Docker课程 时整理的

Docker安装

本文的Docker安装是基于CentOS7.9

卸载旧版Docker

yum remove docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine \
    docker-selinux

配置Docker的yum库

如果是境外服务器,可以直接跳过这步

安装一个yum工具

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

安装成功后,执行命令,配置Docker的yum源(阿里云源)

sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo

更新yum,建立缓存

sudo yum makecache fast

安装Docker

yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

启动校验

# 启动Docker
systemctl start docker

# 停止Docker
systemctl stop docker

# 重启
systemctl restart docker

# 设置开机自启
systemctl enable docker

# 执行docker ps命令,如果不报错,说明安装启动成功
docker ps

配置命令别名

自定命令别名更简化查看容器运行情况,修改/root/.bashrc文件

# 编辑~/.bashrc文件
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
alias dis='docker images'


# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

使用 source /root/.bashrc 使其生效,命令别名生效后,即可直接使用 dps 展示运行的容器列表,如图:

https://ruanshelab.cn/oss/aetherial/2025/06/c92fb08f-1d79-4276-a379-3bb4dbaefb8e_image.png

配置镜像加速

Docker 默认从 docker.io(Docker Hub)拉取镜像,服务器位于国外,国内直接访问可能​​速度慢、不稳定​​,甚至因网络限制导致​​连接超时或失败​​。镜像加速服务,会​​定期同步 Docker Hub 上的常用镜像,配置后可以直接从国内服务器下载,速度快很多。

长期更新的国内可访问镜像地址

配置镜像加速

docker的镜像加速配置文件一般在 /etc/docker,命名为 daemon.json,可以用以下命令配置镜像源,也可以直接编辑该文件

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
  	"https://docker.xuanyuan.me",
  	"https://docker.sunzishaokao.com"
   ]
}
EOF

镜像源配置好后需要进行刷新

sudo systemctl daemon-reload
sudo systemctl restart docker

Docker快速入门

利用Docker部署MySQL

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  mysql

命令解读

  • docker run -d:创建一并允许一个容器,-d 则是可以让容器以后台进程运行
  • --name mysql:容器的名字
  • -p 3306:3306:设置端口映射,容器是高隔离环境,外界不可以访问,但是可以将宿主机端口映射到容器内端口,当方位宿主机指定端口时就是访问容器内部的端口了;容器内部端口往往是由容器内的进程决定的,例如MySQL进程默认端口是3306,因此容器内端口一定是3306,但是宿主机端口则可以任意指定,一般与容器内保持一致;端口映射的格式是 -p 宿主机端口:容器内端口
  • -e TZ=Asia/Shanghai:配置容器内进程运行时的一些参数,格式为 -e KEY=VALUE,KEY和VALUE都是由容器内进程决定的,在上述部署MySQL的代码中,TZ=Asia/Shanghai 是设置时区,MYSQL_ROOT_PASSWORD=123 是设置MySQL root用户默认密码。一般需要设置哪些参数需要去官网查看镜像的文档。
  • mysql:设置镜像名称,Docker会根据这个名字搜索并下载镜像。格式是 REPOSITORY:TAG,例如 mysql:8.0,其中 REPOSITORY 可以理解为镜像名,TAG 是版本号,在未指定 TAG 的情况下,默认是最新的版本,也就是 mysql:latest

镜像的名称不是随意的,而是要到DockerRegistry中寻找,镜像运行时的配置也不是随意的,要参考镜像的帮助文档,这些在 DockerHub 网站或者软件的官方网站中都能找到。

Docker 常用命令

命令说明文档地址
docker pull拉取镜像docker pull
docker push推送镜像到DockerRegistrydocker push
docker images查看本地镜像docker images
docker rmi删除本地镜像docker rmi
docker run创建并允许容器(不能重复创建)docker run
docker stop停止指定容器docker stop
docker start启动指定容器docker start
docker restart重写启动指定容器docker restart
docker rm删除指定容器docker.docker.com
docker ps查看容器docker ps
docker logs查看容器允许日志docker logs
docker exec进入容器docker exec
docker save保存镜像到本地压缩文件docker save
docker load加载本地压缩文件到镜像docker load
docker inspect查看容器详细信息docker inspect

默认情况下,每次重启虚拟机我们都需要手动启动Docker和Docker中的容器。通过命令可以实现开机自启:

# Docker开机自启
systemctl enable docker

# Docker容器开机自启
docker update --restart=always [容器名/容器id]

以Nginx为例给练习上述命令。

  • docker save -o 文件名称.tar 镜像名称:版本:将镜像包保存到本地
  • docker load -i 文件名称.tar:加载本地镜像,-p 不输出任何内容
# 先去DockerHub查看你滚下镜像仓库及相关信息
# 拉去nginx镜像
docker pull nginx
# 额外补充如何将镜像保存到本地和从本地加载镜像
docker save -o nginx.tar nginx:lotest # 保存
docker load -i nginx.tar -p # 加载
# 查看镜像
docker images
# 创建并允许 nginx 容器
docker run -d --name nginx -p 80:80 nginx
# 查看运行中的容器
docker ps
# 加格式化访问
docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 停止运行中的容器
docker stop nginx
# 启动nginx容器
docker start nginx
# 进入容器查看容器内目录
docker exec -it nginx bash
# 进入 MySQL
docker exec -it mysql mysql -utoot -p

# 删除容器
docker rm nginx
# 如果容器正在运行可以强制删除
docker rm -f nginx

数据卷

数据卷(volume)是一个虚拟目录,是容器内目录宿主机目录之间映射的桥梁。在容器内部不方便对文件或配置进行修改,因此需要利用数据卷将两个目录与宿主机目录关联,方便我们操作。

例如可以将nginx的conf目录和html目录分别与两个数据卷关联,这样修改nginx的配置等信息时只需要修改宿主卷的文件即可。

/var/lib/docker/volumes 这个目录就是默认的存放所有容器数据卷的目录,其下再根据数据卷名称创建新目录,格式为 /数据卷名/_data

数据卷的相关命令

命令说明文档地址
docker volume create创建数据卷docker volume create
docker volume ls查看所有数据卷docs.docker.com
docker volume rm删除指定数据卷docs.docker.com
docker volume inspect查看某个数据卷的详情docs.docker.com
docker volume prune清楚数据卷docker volume prune

注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建

  • 在执行 docker run 命令时,使用 -v 数据卷:容器内目录 可以完成数据卷挂载
  • 当创建容器时,如果挂载了数据卷且数据卷不存在,会自动创建数据卷

以创建nginx容器并指定数据卷为例

# 创建容器并指定数据卷,通过 -v 参数来指定数据卷
docker run --name nginx -p 80:80 -v html:/var/share/nginx/html nginx
# 查看数据卷
docker volume ls
# 结果
DRIVER    VOLUME NAME
local     0fabd824039a317b7f790c30bc395eda4e8da69e97c2913ead6d6d4f5ef6a2a3
local     html
# 查看数据卷详情
docker volume inspect html
# 结果
[
    {
        "CreatedAt": "2024-09-28T15:11:07+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/html/_data",  # 挂载点,这数据卷挂载到宿主机的哪个目录
        "Name": "html",
        "Options": null,
        "Scope": "local"
    }
]

此时在宿主机的映射目录进行任何修改都会同步到容器内的目录中。

以MySQL为例演示挂载本地目录

**匿名目录:**创建容器时自动挂载在 volumes 的数据卷目录,名字是随机生成的,建议使用。

# 查看容器的详细信息
docker inspect mysql
# 结果
{
  ....其余部分省略
  "Mounts": [
    {
      "Type": "volume",
      # name 是数据卷名称,由于容器未设置容器名,这里就是匿名卷自动生成的名字,一串哈希值
      "Name": "29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f",
      # 宿主机目录
      "Source": "/var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data",
      # 容器内目录
      "Destination": "/var/lib/mysql",
      "Driver": "local",
    }
  ]
  ....其余部分省略
}

挂载本地目录文件

在挂载mysql的目录时先要去查询需要挂载的数据目录、初始化目录、配置文件目录在容器中的位置

  • 挂载/root/mysql/data到容器内的/var/lib/mysql目录
  • 挂载/root/mysql/init到容器内的/docker-entrypoint-initdb.d目录(初始化的SQL脚本目录)
  • 挂载/root/mysql/conf到容器内的/etc/mysql/conf.d目录(这个是MySQL配置文件目录)

将资料的mysql文件夹上传到服务器进行挂载,文件夹位置在 D:\BaiduNetdiskDownload\Docker资料\mysql,其中hm.cnf主要是配置了MySQL的默认编码,改为utf8mb4;而hmall.sql则是后面学习要用到的黑马商城项目的初始化SQL脚本。

# 删除原来的MySQL容器
docker rm -f mysql
# 进入root目录 创建并运行新mysql容器并挂载本地目录
docker run -d \
	--name mysql \
	-p 3306:3306 \
	-e TZ=Asia/Shanghai \
	-e MYSQL_ROOT_PASSWORD=123 \
	-v ./mysql/data:/var/lib/mysql \
	-v ./mysql/conf:/etc/mysql/conf.d \
	-v ./mysql/init:/docker-entrypoint-initdb.d \
	mysql
# 查看   可以发现~/mysql/data目录已经自动创建好了
ls -l mysql
# 查看data目录,存在大量的数据库数据
ls -l data
# 进入容器内部数据库查看相关信息
docker exec -it mysql mysql -utoot -p123

镜像

镜像结构分为三层

  • **入口(Entrypoint):**镜像运行入口,一般是程序启动的脚本和参数
  • **层(Layer):**在BaseImage基础上添加安装包、依赖、配置等,每次操作都形成新的一层
  • **基础镜像(BaseImage):**应用依赖的系统函数库、环境、配置、文件等

由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以Docker就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给Docker去执行即可。

https://ruanshelab.cn/oss/aetherial/2025/06/262344de-f078-43ef-93bb-54a581409684_image.png

而这种记录镜像结构的文件就称为Dockerfile,其对应的语法可以参考 官方文档

Dockerfile常用语法

指令说明示例
FROM指定基础镜像FROM centos:6
ENV设置环境变量,可在后面指令使用ENV key value
COPY拷贝本地文件到镜像的指定目录COPY ./xx.jar /tmp/add.jar
RUN执行Linux的shell命令,一般是安装过程的命令RUN yum install gcc
EXPOSE指定容器运行时监听的端口,是给镜像使用者看的EXPOSE 8080
ENTRYPOINT镜像中应用的启动命令,容器运行时调用ENTRYPOINT java -jar xx.jar

例如,要基于Ubuntu镜像来构建一个Java应用,其Dockerfile的内容如下:

# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 设定时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装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 8080
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]

除此之外,有人提供了基础的系统加JDK环境,在此基础上制作java镜像,就可以省去JDK的配置了:

# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

构建镜像

# 进入镜像目录
cd /root/demo
# 开始构建
docker build -t docker-demo:1.0 .
  • docker build:就是构建一个docker镜像
  • -t docker-demo:1.0-t 参数是指定镜像的名称(repositorytag
  • .:最后的点是指定构建是Dockerfile所在路径,由于进入deom目录,所以指定的是 . 代表当前目录,也可以直接指定Dockerfile目录:
# 直接指定Dockerfile目录
docker build -t docker-demo:1.0 /root/demo

运行镜像

docker run -d --name wl -p 8080:8080 docker-demo:1.0

# 持续追踪镜像运行的日志
docker logs -f wl

网络

容器内的网络是互通的,各个容器之间是可以直接访问的。但是,容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。

必须借助于docker的网络功能来解决这个问题,官方文档

常见命令

命令说明文档地址
docker network create创建一个网络docker network create
docker network ls查看所有网络docker network ls
docker network rm删除指定网络docker network rm
docker network prune清除未使用网路docker network prune
docker network connect使指定容器连接加入某网络docker network connect
docker network disconnect使指定容器连接离开某网络docker network disconnect
docker network inspect查看网络详细信息docker network inspect

建立自定义网络的例子

# 通过命令创建一个网络
docker network create wlnb
# 查看网络
docker network ls
# 结果
NETWORK ID     NAME      DRIVER    SCOPE
e2dc836839d2   bridge    bridge    local
cf42e44fbae5   host      host      local
b226c2aef2c8   none      null      local
71f174cf37b9   test      bridge    local
# 其中,除了创建的test,其他都是默认网络

# 让aetherial和mysql都加入该网络,注意,在加入网络时可以通过 --alias 给容器起别名
# 在同一个网桥中,其他容器可以通过别名访问
# mysql容器 指定别名为db
docker network connect wlnb mysql --alias db
# aetherial容器 就是Java项目
docker network connect aetherial aetherial
# 可以直接在创建容器时指定其加入的网络
docker run -d --name aetherial 8080:8080 -network test docker-demo:1.0

# 进入容器 访问测试
docker exec -it aetherial bash
ping db # 成功
ping mysql # 成功
ping nginx # 失败 不在同一个网络

DockerCompose

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它使用 YAML 文件来配置应用程序的服务,然后通过一个简单的命令就能创建并启动所有服务。

https://ruanshelab.cn/oss/aetherial/2025/06/02b17bdc-b4e0-4421-9d0c-822c3ca8cb0e_image.png

安装教程

版本对应表

Docker版本Docker Compose文件版本
19.03.0+3.8
18.06.0+3.7
18.02.0+3.6
17.12.0+3.4
19.03.0+3.8
18.06.0+3.7
18.02.0+3.6
17.12.0+3.4

这里的文件版本并不是 Docker Compose 的版本的,而是 docker-compose.yml 文件中写在第一行的版本号

下载 Docker Compose 文件

v2.27.1 是 Docker Compose 的版本号,也可以采用本地下载然后将文件上传到服务器: 下载地址

wget https://github.com/docker/compose/releases/download/v2.27.1/docker-compose-linux-x86_64

将下载的文件移动到 /usr/local/bin/ 并重命名为 docker-compose

mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose

给文件赋权

chmod +x /usr/local/bin/docker-compose

检查是否安装成功

docker-compose --version
Docker Compose version v2.27.1 # 输出这行则代表安装成功

基本语法

docker-compose文件中可以定义多个相互关联的应用容器,每一个应用容器被称为一个服务(service)。由于service就是在定义某个应用的运行时参数,因此与docker run参数非常相似

docker run部署MySQL

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  -v ./mysql/data:/var/lib/mysql \
  -v ./mysql/conf:/etc/mysql/conf.d \
  -v ./mysql/init:/docker-entrypoint-initdb.d \
  --network hmall
  mysql

使用docker-compose.yml文件

version: "3.8"

services:
  mysql:
    image: mysql
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
    networks:
      - new
networks:
  new:
    name: hmall

参数的对比

docker run 参数docker compose指令说明
–namecontainer_name容器名称
-pports端口映射
-eenvironment环境变量
-vvolumes数据卷配置
–networknetworks网络

课程练习的黑马商城部署yml文件

version: "3.8"

services:
  mysql:
    image: mysql
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
      - "./mysql/init:/docker-entrypoint-initdb.d"
    networks:
      - hm-net
  hmall:
    build:
      context: . # 在当前目录上寻找Dockerfile文件
      dockerfile: Dockerfile
    container_name: hmall
    ports:
      - "8080:8080"
    networks:
      - hm-net
    depends_on:
      - mysql
  nginx:
    image: nginx
    container_name: nginx
    ports:
      - "18080:18080"
      - "18081:18081"
    volumes:
      - "./nginx/nginx.conf:/etc/nginx/nginx.conf"
      - "./nginx/html:/usr/share/nginx/html"
    depends_on:
      - hmall
    networks:
      - hm-net
networks: # 创建一个网络
  hm-net:
    name: hmall

基础命令

docker-compose的基本语法如下:docker compose [OPTIONS] [COMMAND]

OPTIONS参数

参数或指令说明
-f指定compose文件的路径和名称
-p指定project名称,project就是当前compose文件中设置的多个service的集合,是逻辑概念

COMMAND参数

参数或指令说明
up创建并启动所有的容器
down听指挥并移除所有的容器和网络
ps列出所有启动的容器
logs查看指定容器的日志
stop停止容器
start启动容器
restart重启容器
top查看运行的进程
exec在指定的运行的容器中执行命令