前言
一年前写了一篇 使用 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
命令查看当前已下载的镜像
设置 Docker 镜像源
由于某些不可描述的问题,Docker 官方镜像经常会拉不下来,常用方式是通过设置镜像源的方式解决(但是大部分源都已经挂了),其他方式可以自行 bing 搜索
首先修改 /etc/docker/daemon.json
文件为如下格式
1 | { |
上述镜像源只是一个示例,可以自行寻找或搭建其他源
然后重启 Docker:service docker restart
可以通过 docker info
命令查看配置是否生效
启动容器
创建并启动
可以用 docker run
命令启动容器
1 | docker run -d \ |
参数说明
参数 | 含义 |
---|---|
-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 | docker create \ |
与 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>
查看容器的所有信息,其中就包括了创建时使用的参数
查看容器日志
通过 docker logs <容器名>/<容器id>
查看容器日志
但是这种方式只能查看现有日志,不能刷新,可以在后面加 -f
参数使其滚动刷新追踪输出:docker logs <容器名>/<容器id> -f
进入容器内部
每个 Docker 容器都是一个独立的运行环境,每个容器内部表现的都像一个独立的 Linux 系统,可以使用 docker exec <容器名>/<容器id> <想要执行的命令>
在容器内部执行命令,比如我现在要查看容器的系统信息,可以执行 docker exec mysql-server uname
但是这样会非常的麻烦,可以通过 docker exec -it <容器名>/<容器id> /bin/sh
命令进入容器内部,获得一个交互式的命令行
之后可以用 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 所有的网络
使用 docker network rm <网络id>
可以删除一个子网
Docker Compose
如果我们要用 Docker 部署一个完整的包含前端、后端、中间件、数据库的项目,一种容易想到的方式是分别拉取不同镜像,分别创建容器,但是这样会有三个问题
- 比较繁琐 复杂
- 项目中可能存在容器互相依赖的情况
- 容器的网络可能会有特殊要求
可能这时候会想到,我把所有的项目都打包到一起,跑在一个巨大的容器里。这样也会有三个问题
- 镜像太大
- 如果有一个模块挂壁了,整个项目都直接挂壁了
- 不方便扩容
这时候就需要 Docker Compose 出场了
Docker Compose 是一个容器编排技术,使用 yaml 文件管理多个容器,里面描述了容器之间是如何创建以及如何协同工作的,比如在启动后端项目前,需要先启动一个 MySQL 容器:
1 | version: '3.8' |
这个 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