Docker 常见命令与操作

前言

一年前写了一篇 使用 Docker 进行项目快速部署 的博客,是时候把当时鸽掉的完整教程补回来了

本教程将会以使用 Docker 安装 MySQL 为例讲解 Docker 常见命令与操作

下载镜像

可以使用 docker pull 命令从 Docker 仓库拉取镜像

1
docker pull --platform=linux/amd64 docker.io/library/mysql:8.4.5

--platform 参数后面可以指定操作系统和 CPU 架构,这里我们指定的是 Linux 下的 X86 架构。通常来说不需要也不建议手动指定,Docker 会帮我们自动寻找最适合当前宿主机的镜像

docker.io 是指定拉取镜像的源,这里选择的是官方源

library 是一个命名空间,专门用于存放官方镜像

mysql:8.4.5 是镜像名称和版本号

所以,这个命令其实可以直接简化为一行:

1
docker pull mysql:8.4.5

可以通过 docker images 命令查看当前已下载的镜像

image-20250705163735659

设置 Docker 镜像源

由于某些不可描述的问题,Docker 官方镜像经常会拉不下来,常用方式是通过设置镜像源的方式解决(但是大部分源都已经挂了),其他方式可以自行 bing 搜索

首先修改 /etc/docker/daemon.json 文件为如下格式

1
2
3
4
5
6
7
8
{
"registry-mirrors": [
"https://docker.xuanyuan.me",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.ccs.tencentyun.com",
"https://registry.docker-cn.com"
]
}

上述镜像源只是一个示例,可以自行寻找或搭建其他源

然后重启 Docker:service docker restart

可以通过 docker info 命令查看配置是否生效

启动容器

创建并启动

可以用 docker run 命令启动容器

1
2
3
4
5
6
7
docker run -d \
--name mysql-server \
-e MYSQL_ROOT_PASSWORD=... \
-p 3306:3306 \
-v mysql-data:/var/lib/mysql \
--restart unless-stopped \
mysql:8.4.5

参数说明

参数 含义
-d 后台运行容器(detached 模式)
--name my-mysql 容器名称
-p 3306:3306 映射主机端口到容器端口
-e MYSQL_ROOT_PASSWORD=... 设置 MySQL root 用户的密码
-v mysql-data:/var/lib/mysql 创建并挂载 Docker volume 到 MySQL 数据目录
--restart unless-stopped 容器在重启 Docker 后自动启动
mysql:8.4.5 镜像

Docker volume 的作用是持久化数据,正常情况下 Docker 所有的数据都保存在了容器内,如果容器被删除,数据也一并被删除。-v mysql-data:/var/lib/mysql 命令会自动创建一个名为 mysql-data 的 Docker volume,用于持久化 MySQL 的数据,即使删除容器也不会丢失数据

可以使用 docker volume inspect <容器卷> 查看挂载卷状态,其中 Mountpoint 字段的值是挂载卷的真实目录

仅创建

如果你仅仅是想创建一个容器,暂时并不想启动他,可以使用 docker create 命令

1
2
3
4
5
6
7
docker create \
--name my-mysql \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-p 3306:3306 \
-v mysql-data:/var/lib/mysql \
--restart unless-stopped \
mysql:8.4.5

docker run 命令几乎一致,只是少了 -p 参数。使用 docker create 创建的容器,在用 docker start 启动时,默认总是以后台(detached)方式运行,不管有没有加 -d 参数

查看容器信息

查看容器状态

可以使用 docker ps 命令查看容器状态

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3dac2f189933 mysql:8.4.5 “docker-entrypoint.s…” 11 seconds ago Up 11 seconds 0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp, 33060/tcp mysql-server

具体上面的状态是什么含义可以问 GPT

docker run 命令每次都会创建一个新的容器,如果我们想要启动 / 停止已有容器,可以使用 docker start <容器名>/<容器id>docker stop <容器名>/<容器id>

但是被停止的容器是无法使用 docker ps 查看的,docker ps 只能查看正在运行的容器, docker ps -a 可以查看所有容器

使用 docker start 启动的容器是不需要添加参数的,会保留使用 docker run 创建时使用的参数

可以使用 docker inspect <容器名>/<容器id> 查看容器的所有信息,其中就包括了创建时使用的参数

image-20250705200316599

查看容器日志

通过 docker logs <容器名>/<容器id> 查看容器日志

但是这种方式只能查看现有日志,不能刷新,可以在后面加 -f 参数使其滚动刷新追踪输出:docker logs <容器名>/<容器id> -f

进入容器内部

每个 Docker 容器都是一个独立的运行环境,每个容器内部表现的都像一个独立的 Linux 系统,可以使用 docker exec <容器名>/<容器id> <想要执行的命令> 在容器内部执行命令,比如我现在要查看容器的系统信息,可以执行 docker exec mysql-server uname

image-20250705204326027

但是这样会非常的麻烦,可以通过 docker exec -it <容器名>/<容器id> /bin/sh 命令进入容器内部,获得一个交互式的命令行

image-20250705210433386

之后可以用 exec 命令或者使用 Ctrl + D 快捷键退出到宿主机

Dockerfile

Dockerfile 是一个文件,用于描述镜像是如何制作的,之前用 docker pull 命令拉取的镜像就是用 Dockerfile 制作的

可以看菜鸟教程 Docker Dockerfile-菜鸟教程

Docker 网络

Docker 容器不光环境和宿主机隔离,网络也和宿主机隔离

Docker 主要有四种网络模式:Bridge、Host、Container、None。其中桥接模式(Bridge)和直连模式(Host)是最常用的,其余两种可以自行 bing 搜索

桥接模式

桥接模式是 Docker 的默认网路模式。所有容器都在一个子网内,通过网桥与宿主机连接,每个容器都分配了一个内部 ip 地址,容器网络与宿主机网络隔离,通过端口映射访问

可以通过 docker network create <子网名> 创建新的子网,默认创建的子网也是桥接模式,可以将指定容器加入指定的子网,子网间也是相互隔离的。并且 Docker 子网内部有 DNS 机制,可以将容器名转换为子网 ip 地址

直连模式

直接使用宿主机的 ip 地址,通过宿主机端口可以直接访问容器,无需建立端口映射。可以通过这个命令启动一个直连模式的容器:

1
docker run -d network host mysql-server

使用 docker network list 可以展示出 Docker 所有的网络

image-20250706112106723

使用 docker network rm <网络id> 可以删除一个子网

Docker Compose

如果我们要用 Docker 部署一个完整的包含前端、后端、中间件、数据库的项目,一种容易想到的方式是分别拉取不同镜像,分别创建容器,但是这样会有三个问题

  1. 比较繁琐 复杂
  2. 项目中可能存在容器互相依赖的情况
  3. 容器的网络可能会有特殊要求

可能这时候会想到,我把所有的项目都打包到一起,跑在一个巨大的容器里。这样也会有三个问题

  1. 镜像太大
  2. 如果有一个模块挂壁了,整个项目都直接挂壁了
  3. 不方便扩容

这时候就需要 Docker Compose 出场了

Docker Compose 是一个容器编排技术,使用 yaml 文件管理多个容器,里面描述了容器之间是如何创建以及如何协同工作的,比如在启动后端项目前,需要先启动一个 MySQL 容器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
version: '3.8'

services:
mysql-server:
image: mysql:8.4.5
container_name: mysql-server
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: mydb
MYSQL_USER: myuser
MYSQL_PASSWORD: mypassword
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql

backend:
build: ./backend
container_name: backend
depends_on:
- mysql-server
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-server:3306/mydb
SPRING_DATASOURCE_USERNAME: myuser
SPRING_DATASOURCE_PASSWORD: mypassword
ports:
- "8080:8080"
restart: unless-stopped

volumes:
mysql_data:

这个 depends_on 字段就可以规定容器的启动顺序

在写好了 docker-compose.yaml 文件后,就可以用 docker compose up -d 一键启动了,与 docker compose 相关的还有其他命令

  • docker compose stop: 停止所有容器
  • docker compose down: 停止并删除所有容器
  • docker compose start: 启动所有容器

注意 docker compose up -d 只能识别名为 docker-compose.yaml 的文件,改个名字就无法识别了。如果要识别其他名字的 yaml 文件可以使用 -f 参数:

1
docker compose -f <文件路径> up -d

Docker Compose 只适合简单项目启动,不适合大型项目启动。对于企业级大规模服务器集群的容器编排需求,通常会使用 Kubernetes