Docker查看镜像分层构建历史history命令 Docker
前言
一个镜像由多层叠加而成,想知道每层做了什么、哪层最占空间、Dockerfile 每一步结果,用 docker history 查看。排查镜像体积过大、复现构建过程时很有用。本文讲解 history 基本用法、看层大小、压缩显示、与 inspect 的区别。
操作步骤
1. 查看镜像构建历史
docker history nginx:1.28
2. 以精简格式输出(不截断命令)
docker history --no-trunc nginx:1.28
3. 按人类可读单位显示大小
docker history -H nginx:1.28
4. 查看某层占用,配合统计
docker history nginx:1.28 --format "{{.Size}}\t{{.CreatedBy}}"
5. 对比基础镜像与最终镜像层
docker history debian:bookworm
docker history myapp:latest
6. 查看镜像详细信息用 inspect
docker inspect nginx:1.28
常见坑
- history 只显示构建层,看不到运行时写入的数据卷内容。
- 层大小是累计差值,别把每层简单相加等于总大小。
- --no-trunc 命令很长,适合定位具体指令。
- 多阶段构建只保留最终阶段的层,中间层不显示。
- 有些层是虚拟层(shared),大小为 0 正常。
- 镜像过大要在 Dockerfile 里合并 RUN、清理缓存,history 帮你定位元凶层。
- history 是只读展示,不能修改已有层。
总结
docker history 按层显示镜像构建指令和大小,--no-trunc 看完整命令、-H 看可读单位。它帮助定位体积膨胀层和复现构建过程。优化镜像要回到 Dockerfile 合并命令、清理依赖,history 只是诊断工具。
遇到问题加QQ23979811 协助处理
Docker镜像导出导入save与load命令用法 Docker
前言
离线环境或内网服务器无法拉取公共镜像,需要把一台机器上的镜像导出成压缩包,拷贝到另一台机器导入。docker save 和 docker load 负责镜像的迁移,区别于容器的导出。本文讲解 save 导出、load 导入、压缩体积、查看镜像、与容器导出的区别。
操作步骤
1. 查看本地镜像
docker images
2. 导出镜像为 tar
docker save nginx:1.28 -o nginx.tar
3. 压缩导出节省体积
docker save nginx:1.28 | gzip > nginx.tar.gz
4. 在目标机器导入
docker load -i nginx.tar
压缩包先解压:
gunzip nginx.tar.gz && docker load -i nginx.tar
或直接:
docker load < nginx.tar.gz
5. 验证导入成功
docker images
6. 多镜像一次性导出
docker save img1:tag img2:tag -o all.tar
常见坑
- save 导出的是镜像层,export 导出的是容器文件系统,两者不能混用。
- 不压缩 tar 体积大,跨网传输慢,用 gzip。
- 导入后 tag 丢失或名称不符,需要重新打 tag。
- 目标机器架构不同(amd64/arm),镜像无法运行。
- 镜像层很多,导出文件仍较大,注意磁盘。
- 版本 tag 写错,导入到旧版本。
- 私有仓库更适合规模化分发,save/load 用于离线迁移。
总结
save 打包镜像层、load 还原镜像,配合 gzip 压缩适合离线迁移。注意区分镜像 save/load 与容器 export/import,跨架构先确认 CPU 类型。迁移后 docker images 核对 tag,必要时重新打标签。
遇到问题加QQ23979811 协助处理
Docker自定义网络给容器分配固定IP方法 Docker
前言
默认 bridge 网络里容器重启后 IP 会变,互相依赖的服务(如应用连数据库)容易连不上。创建自定义网络并指定固定 IP,可以让容器拥有稳定地址。本文讲解新建自定义网络、启动容器指定 IP、查看网络、容器互通的完整步骤。
操作步骤
1. 创建自定义网络并指定子网
docker network create --subnet 172.20.0.0/24 mynet
2. 启动容器并分配固定 IP
docker run -d --name db --network mynet --ip 172.20.0.10 mysql:8
3. 查看网络详情与已分配 IP
docker network inspect mynet
4. 另一个容器加入同一网络通信
docker run -d --name app --network mynet --ip 172.20.0.20 nginx
容器间可用容器名或固定 IP 互通。
5. 查看容器 IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' db
6. 把已有容器接入网络
docker network connect mynet db
常见坑
- 默认 bridge 不支持 --ip 固定,必须自定义网络。
- 固定 IP 与子网冲突或重复分配,容器启动失败。
- 不建议依赖固定 IP,推荐用容器名+DNS 互通。
- 子网与宿主机内网网段重叠导致路由冲突。
- Compose 里固定 IP 需在 networks 配置 subnet 和 ipv4_address。
- 固定 IP 方案不利于容器横向扩容。
- 容器删重建后固定 IP 要重新分配。
总结
固定 IP 靠自定义网络 + --subnet + --ip,适合少量需要稳定地址的容器。现代做法更推荐容器名 DNS 和服务发现,减少硬编码 IP。Compose 部署在 networks 段声明子网和地址,保持与命令行一致。
遇到问题加QQ23979811 协助处理
Docker容器与宿主机互相复制文件docker cp Docker
前言
需要把宿主机的配置文件拷进容器,或把容器里生成的日志导出到宿主机,docker cp 是最直接的命令,不需要进入容器内部,也不依赖数据卷。本文讲解容器到宿主机、宿主机到容器、批量目录复制、结合挂载的区别和注意事项。
操作步骤
1. 宿主机文件复制到容器
docker cp ./config.conf 容器名:/etc/app/config.conf
2. 容器内文件复制到宿主机
docker cp 容器名:/var/log/app.log ./app.log
3. 复制整个目录
docker cp ./dir 容器名:/opt/
目标末尾加 / 表示放入该目录。
4. 用容器 ID 代替名称
docker cp ./file.txt abcd123:/path/file.txt
5. 查看容器内文件确认
docker exec -it 容器名 ls /etc/app
6. 与数据卷挂载的区别
docker cp 是一次性拷贝,修改不会同步;要持续同步用 -v 挂载。
常见坑
- 目标路径不存在,cp 报错,先确认容器内目录。
- 复制后容器重启,手动拷贝的文件仍在容器层,删除容器即丢失。
- 把目录当文件复制,目标层级错误。
- 权限属主不对,容器内程序读不到文件。
- 大文件复制占磁盘,注意容器层空间。
- 正在运行的容器也能 cp,无需停止。
- 挂载卷里的文件直接在宿主机改,不必 cp。
总结
docker cp 支持双向复制单个文件和目录,命令简单,适合临时传配置、导出日志。它是一次性拷贝不持久,长期文件同步用数据卷。复制后进容器确认路径和权限,重要文件注意容器删除后数据丢失。
遇到问题加QQ23979811 协助处理
Docker查看容器日志docker logs常用参数详解 Docker
前言
容器启动失败、接口报错时,最直接的排查手段就是看日志。docker logs 是查看容器标准输出日志的基础命令,但很多人只知道 docker logs 容器名,不会按时间、行数、实时跟踪来定位问题。本文讲解 docker logs 常用参数、实时跟踪、时间范围过滤、follow 与 tail 配合,以及日志过多时的处理方法,适配 Linux 下 Docker 环境。
操作步骤
1. 查看全部日志
docker logs 容器名或ID
2. 只看最后 100 行
docker logs --tail 100 容器名
3. 实时跟踪新增日志(类似 tail -f)
docker logs -f 容器名
4. 显示时间戳
docker logs -t 容器名
5. 组合:跟踪最新日志并显示时间
docker logs -f --tail 50 -t 容器名
6. 按时间范围查看
docker logs --since 2026-11-14T06:00:00 --until 2026-11-14T08:00:00 容器名
7. 查看容器日志文件位置
docker inspect --format '{{.LogPath}}' 容器名
8. 清理过大的容器日志
sudo truncate -s 0 $(docker inspect --format '{{.LogPath}}' 容器名)
常见坑
- 应用日志写到了容器内文件,docker logs 只收集 stdout/stderr,看不到文件日志。
- 启动失败退出后日志仍可查,容器被删除则日志随之消失。
- --since 时间格式写错,返回空结果,注意是 ISO8601。
- -f 一直挂着不退出,调试完按 Ctrl+C 结束。
- 高并发容器日志爆增占满磁盘,需配置日志轮转。
- 容器 ID 用前几位即可,但要保证唯一。
- 多容器用 docker compose logs 一次性看全部服务日志。
总结
docker logs 的核心参数是 --tail 看尾部、-f 实时跟踪、-t 加时间、--since/--until 圈定时间。应用日志若写入文件,需挂载到宿主机才能长期保留。生产环境给容器配置 max-size 日志限制,避免单日志文件无限增长。
遇到问题加QQ23979811 协助处理
Docker容器中文乱码与时区设置完整方法 Docker
前言
容器里经常出现两个问题:中文显示成问号或乱码,以及容器时间比宿主机差 8 小时。原因是基础镜像默认使用 POSIX locale 且 UTC 时区,而业务需要 zh_CN.UTF-8 和东八区。本文给出 Dockerfile 设置、运行时挂载、compose 配置三种解决方式,一次解决乱码和时间。
操作步骤
1. 查看容器当前 locale 和时间
docker exec -it 容器名 locale
docker exec -it 容器名 date
2. 运行时直接指定环境变量(最快)
docker run -d --name app \
-e LANG=zh_CN.UTF-8 \
-e TZ=Asia/Shanghai \
镜像名
3. Dockerfile 中固化
FROM debian:bookworm
ENV LANG=zh_CN.UTF-8
ENV TZ=Asia/Shanghai
RUN apt update && apt install -y locales tzdata \
&& locale-gen zh_CN.UTF-8 \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
4. 挂载宿主机时区文件
docker run -d -v /etc/localtime:/etc/localtime:ro --name app 镜像名
5. Docker Compose 配置
services:
app:
image: 镜像名
environment:
LANG: zh_CN.UTF-8
TZ: Asia/Shanghai
volumes:
- /etc/localtime:/etc/localtime:ro
6. 重建并验证
docker compose up -d
docker exec -it app date
docker exec -it app locale
时间显示东八区、locale 为 zh_CN.UTF-8 即成功。
常见坑
- 基础镜像没装 locales,只设 LANG 变量不生成中文 locale,仍乱码。
- 只改时区变量不挂载 /etc/localtime,个别程序仍读系统时区。
- 中文字体缺失导致图片、报表里中文方框,这是字体问题不是 locale。
- Java 程序还需要 JVM 时区参数,光设 TZ 不够。
- 改 Dockerfile 后没重新 build,只 run 新容器旧镜像不变。
- Alpine 镜像用 apk 装 tzdata 和 locale,包名与 Debian 不同。
- 多容器集群时间应统一用 UTC 还是东八区,需全栈约定,避免日志错乱。
总结
乱码靠 LANG=zh_CN.UTF-8 和 locale-gen,时区靠 TZ=Asia/Shanghai 加挂载 /etc/localtime。三种方式里运行时变量最快,Dockerfile 固化最规范。Java、数据库等特殊程序还要单独配置,改完重建容器再用 date 和 locale 双重验证。
遇到问题加QQ23979811 协助处理
Docker停止删除容器 Docker
Docker停止删除容器
引言
容器用多了会堆积一堆停止状态的旧实例,占磁盘、干扰排查。停止和删除是两步:先停再删,生产环境删容器前要确认数据已持久化,否则删除即丢失。
停止单个容器
docker stop 容器名或ID
发送SIGTERM优雅停止,等待默认10秒,超时再发SIGKILL强杀。
强制停止
docker kill 容器名或ID
直接SIGKILL,不给进程清理机会,只用于卡死不响应的容器。
删除已停止容器
docker rm 容器名或ID
只能删停止状态的容器,运行中需先stop或加-f。
强制删除运行中容器
docker rm -f 容器名或ID
一步停止并删除,慎用,等价于kill后rm。
批量清理
# 删除所有已停止容器
docker container prune
# 删除全部容器(含运行中,危险)
docker rm -f $(docker ps -aq)
prune只清停止的,相对安全;ps -aq配合rm -f会删光,生产禁止随手执行。
启动与重启
docker start 容器名
docker restart 容器名
停止的容器start可再次拉起,文件系统内改动仍在,只有删容器才清除。
注意事项
- 删除容器前确认挂载卷和数据,容器内非挂载目录删除即丢;
- 数据库容器先备份再删,别以为能找回来;
- -f强制删除跳过优雅停止,可能丢未刷盘数据;
- 批量命令先docker ps -aq列出确认,再删;
- 加了--rm的容器退出自动删除,不留残骸;
- 清理容器不影响镜像,镜像还在可随时重建。
总结
docker stop优雅停止,docker kill强杀,docker rm删已停容器,-f强制删运行中容器,container prune批量清停止实例。核心原则是先确认数据挂载和备份再删,生产慎用rm -f全量清理,执行批量命令前先列出ID核对,理解容器删除会清空非挂载层数据。
Docker查看运行容器 Docker
Docker查看运行容器
引言
部署多个服务后,先要看清哪些容器在跑、状态如何、映射了哪些端口、跑了多久。docker ps系列命令是日常运维入口,配合格式化和过滤快速定位目标容器。
只看运行中容器
docker ps
输出容器ID、镜像、命令、创建时间、状态、端口映射、名称,默认只列正在运行的。
查看全部容器(含已停止)
docker ps -a
把Exited状态的容器也列出来,排查退出残留时用。
只看容器ID
docker ps -q
输出纯ID,配合批量停止删除。
自定义输出列
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"
只保留关心的列,脚本采集更清晰。
按镜像过滤
docker ps --filter ancestor=nginx:latest
列出指定镜像启动的容器。
查看容器资源占用
docker stats
实时看每个容器CPU、内存、网络IO,Ctrl+C退出。
注意事项
- ps默认不含已停止容器,找退出容器用-a;
- STATUS显示Up时长或Exited码,退出码非0要查日志;
- PORTS列看清宿主端口到容器端口的映射;
- 容器名重复会冲突,--name要唯一;
- 配合docker inspect看单个容器完整配置;
- 批量操作前先用-q列出ID确认范围。
总结
docker ps看运行中容器,-a含已停止,-q取ID批量处理,--format自定义列,--filter按镜像过滤,docker stats看实时资源。运维先列清单确认状态和端口,再决定停止、重启或排查,避免凭印象操作容器。
Docker查看本地镜像 Docker
Docker查看本地镜像
引言
用Docker跑服务前先确认本地有哪些镜像、大小多少、标签是什么,避免重复拉取或用错版本。docker images系列命令能列出镜像仓库名、标签、ID、大小和创建时间。
列出全部本地镜像
docker images
# 等价
docker image ls
输出REPOSITORY、TAG、IMAGE ID、CREATED、SIZE五列。
只看镜像ID
docker images -q
只输出短ID,配合批量删除使用。
按名称过滤
docker images nginx
docker images | grep php
列出指定仓库名或关键词的镜像。
查看镜像详细信息
docker inspect nginx:latest
JSON输出架构、环境变量、挂载点、默认启动命令等。
查看镜像历史层
docker history nginx:latest
看每层做了什么改动、每层大小,理解镜像分层结构。
过滤和格式化
docker images --format "{{.Repository}}:{{.Tag}} {{.Size}}"
自定义输出列,脚本里取数更方便。
注意事项
- 同一个镜像不同TAG可能共用层,SIZE不重复累加;
- 悬空镜像
是旧版本残留,用prune清理; - 镜像大小是解压后占用,下载压缩包更小;
- 看磁盘占用用docker system df;
- 未被任何容器引用的镜像可安全删除;
- 拉取前先docker images判断是否已存在。
总结
docker images列出本地镜像,-q取ID、按仓库名过滤、inspect看详情、history看分层、--format自定义输出。日常先列镜像确认版本和大小,再决定拉取或删除,配合system df掌握磁盘占用。
Docker清理悬空镜像 Docker
Docker清理悬空镜像
引言
反复build镜像后,旧的无标签镜像(
先看占用
docker system df
查看镜像、容器、卷、构建缓存各占多少,先摸清再动手。
什么是悬空镜像
build出新标签后,旧层变成
只清悬空镜像(安全)
docker image prune
只删除无标签无引用的dangling镜像,已打标签和在用镜像不动,最稳妥。
清停止的容器
docker container prune
删掉所有已退出的容器,正在运行的不受影响。
清无用镜像和构建缓存(更彻底)
docker system prune
一次清悬空镜像、停止容器、无用网络和构建缓存,加-a连未被容器使用的镜像也删,加--volumes连未使用卷一起删:
docker system prune -a --volumes
手动删单个镜像
docker image rm 镜像ID
若提示被容器引用,先确认容器用途,别直接强制删。
注意事项
- 生产慎用-a和--volumes,卷里可能存数据库数据,删了不可恢复;
- 先docker system df看占用,再决定清哪一类;
- 清理前确认没有需要保留的停止容器和备份卷;
- 镜像仓库里还能重新拉取的镜像才适合-a全清;
- 定期配合定时任务清理,避免磁盘缓慢耗尽。
总结
日常用docker image prune清悬空镜像最安全,docker system prune清停止容器和缓存,-a和--volumes只在确认无保留价值时用。先df看占用、分级清理,避免误删业务卷和在用镜像。
Docker容器日志查看 Docker
Docker容器日志查看
引言
容器启动报错、服务运行异常时,不能进容器盲目找文件,第一时间用docker logs查看标准输出日志。应用把日志打到stdout/stderr,Docker统一收集,是容器排错最常用入口。
基础查看命令
#查看全部日志
docker logs 容器名或ID
#实时跟踪最新日志,类似tail -f
docker logs -f 容器名
#只看最近100行
docker logs --tail 100 容器名
#查看某时间之后日志
docker logs --since 30m 容器名
docker logs --since 2026-10-18T07:00:00 容器名
#带时间戳
docker logs -t 容器名
常用组合
#实时跟踪并显示时间戳、最近50行
docker logs -f -t --tail 50 myapp
排查重启循环、接口报错时,先tail看最后报错,再结合时间过滤。
日志原理
Docker默认把容器标准输出保存到本地json-file驱动,存在宿主机/var/lib/docker/containers目录。应用要把日志输出到控制台,而不是只写容器内文件,才能被docker logs抓到。
日志注意事项
- 默认json-file不限制大小,长时间运行会占满磁盘,生产配置日志轮转:
{"log-driver":"json-file","log-opts":{"max-size":"10m","max-file":"3"}} - 需要长期分析的日志,接入ELK等集中日志系统;
- 容器删除后默认日志随之丢失;
- 应用内部业务日志建议挂载到宿主机目录持久化。
总结
docker logs是容器排错第一命令,-f跟踪、--tail取尾部、--since按时间过滤。生产配置大小轮转避免磁盘写满,业务重要日志持久化或集中采集。
Docker多阶段镜像构建 Docker
Docker多阶段镜像构建
引言
直接打包项目代码、编译工具到镜像,镜像体积巨大,部署传输慢。Docker多阶段构建可以在第一阶段编译代码,第二阶段只复制编译后的成品,剔除编译器、源码,大幅度减小镜像大小。
原理
一个Dockerfile可以写多个FROM,每一个FROM代表一个阶段。阶段之间可以复制文件,最终镜像只保留最后一个阶段内容,前面阶段的编译环境不会打包进最终镜像。
示例Dockerfile(PHP项目)
#阶段1:构建
FROM php:8.2-cli AS builder
WORKDIR /app
COPY . .
RUN composer install --no-dev
#阶段2:运行环境
FROM php:8.2-cli-alpine
WORKDIR /app
COPY --from=builder /app .
CMD ["php","index.php"]
最终镜像只有php运行环境加业务代码,没有composer、源码缓存文件。
优势
- 镜像体积大幅缩小,传输更快;
- 减少攻击面,镜像内没有编译工具,安全性更高;
- 只维护单个Dockerfile,构建流程简单。
注意事项
- 多阶段命名便于阅读;
- 不要复制不需要的文件,
.dockerignore忽略日志、缓存; - 区分开发镜像与生产镜像,生产镜像精简。
总结
多阶段构建是容器化部署最佳实践,适合PHP、Go、前端打包等场景,生产环境镜像尽量使用多阶段构建,减小体积提升部署效率。
Docker常用命令大全,新手必看 Docker
前言
Docker现在用得越来越多,但很多新手记不住命令。本文整理了最常用的Docker命令,收藏起来随用随查。
一、镜像相关命令
拉取镜像
docker pull nginx:latest
查看本地镜像
docker images
删除镜像
docker rmi 镜像ID
强制删除镜像
docker rmi -f 镜像ID
搜索镜像
docker search nginx
二、容器相关命令
查看运行中的容器
docker ps
查看所有容器(包括停止的)
docker ps -a
启动容器
docker start 容器名/容器ID
停止容器
docker stop 容器名/容器ID
重启容器
docker restart 容器名/容器ID
删除容器
docker rm 容器名/容器ID
强制删除运行中的容器
docker rm -f 容器名/容器ID
进入容器
docker exec -it 容器名/容器ID /bin/bash
查看容器日志
docker logs 容器名/容器ID
实时查看日志
docker logs -f 容器名/容器ID
查看容器详细信息
docker inspect 容器名/容器ID
查看容器IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 容器名
查看容器资源占用
docker stats
三、运行容器
后台运行
docker run -d --name mynginx -p 80:80 nginx
参数解释:
- -d:后台运行
- --name:容器名
- -p:端口映射(宿主端口:容器端口)
运行并进入容器
docker run -it ubuntu /bin/bash
挂载目录
docker run -d -v /host/path:/container/path nginx
环境变量
docker run -e MYSQL_ROOT_PASSWORD=123456 mysql
自动重启
docker run --restart=always -d nginx
四、清理命令
停止所有容器
docker stop $(docker ps -q)
删除所有停止的容器
docker container prune
删除所有未使用的镜像
docker image prune -a
一键清理
docker system prune -a
五、Docker Compose命令
启动
docker-compose up -d
停止
docker-compose down
查看状态
docker-compose ps
查看日志
docker-compose logs -f
重启
docker-compose restart
六、常用场景
运行MySQL
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
运行Nginx
docker run -d \
--name nginx \
-p 80:80 \
-v /www:/usr/share/nginx/html \
nginx
运行Redis
docker run -d \
--name redis \
-p 6379:6379 \
redis:alpine
七、常见坑
坑1:容器启动后马上退出
原因: 容器没有前台进程。
解决: 加-it或者tail -f /dev/null。
坑2:端口映射不对
问题: 容器里跑的是80端口,映射成了8080:80。
解决: 确认容器内端口和宿主机端口。
坑3:数据丢失
问题: 容器删了数据就没了。
解决: 一定要挂载数据卷-v。
坑4:镜像太大
解决: 用alpine版本,比如redis:alpine。
八、命令速查表
| 功能 | 命令 |
|---|---|
| 查看运行中容器 | docker ps |
| 查看所有容器 | docker ps -a |
| 查看镜像 | docker images |
| 拉取镜像 | docker pull 镜像名 |
| 运行容器 | docker run -d --name 名字 -p 端口:端口 镜像 |
| 进入容器 | docker exec -it 名字 /bin/bash |
| 查看日志 | docker logs -f 名字 |
| 停止容器 | docker stop 名字 |
| 删除容器 | docker rm 名字 |
| 删除镜像 | docker rmi 镜像ID |
| 清理 | docker system prune -a |
总结
记住:
docker ps看容器docker images看镜像docker run启动容器docker exec -it进入容器docker logs -f看日志docker system prune清理
最常用:
docker ps
docker images
docker exec -it 容器名 /bin/bash
docker logs -f 容器名
遇到问题加QQ23979811 协助处理
Docker容器数据备份和迁移方法 Docker
前言
Docker容器删了数据就没了?想把容器从一台服务器迁到另一台?本文讲Docker容器数据备份和迁移的几种方法,包括容器快照、数据卷备份、镜像导出。
一、Docker数据存哪里
Docker数据有两种存法:
- 容器内部:数据存在容器的可写层,容器删了数据就没了
- 数据卷(Volume):数据存在宿主机上,容器删了数据还在
重要: 生产环境一定要用数据卷,不然容器一删数据全没。
二、方法1:容器快照(commit)
把容器当前状态打包成一个新镜像。
步骤
第一步:查看容器ID
docker ps
找到要备份的容器ID。
第二步:提交成新镜像
docker commit 容器ID 备份镜像名:标签
例子:
docker commit mynginx nginx-backup:v1
第三步:导出镜像成文件
docker save -o nginx-backup.tar nginx-backup:v1
第四步:传到新服务器
scp nginx-backup.tar root@新服务器IP:/root/
第五步:新服务器导入
docker load -i nginx-backup.tar
第六步:新服务器启动容器
docker run -d --name mynginx -p 80:80 nginx-backup:v1
优缺点
优点: 简单,整个容器都打包了
缺点: 镜像文件大,不适合大数据量
三、方法2:数据卷备份
如果用了数据卷,直接备份数据卷里的文件。
步骤
第一步:看数据卷挂载在哪
docker inspect 容器名 | grep Mounts
输出里找 Source,就是宿主机上的路径。
例子:
"Mounts": [
{
"Source": "/data/mysql",
"Destination": "/var/lib/mysql"
}
]
数据在宿主机的 /data/mysql 目录。
第二步:打包备份
tar -zcvf mysql-backup.tar.gz /data/mysql
第三步:传到新服务器
scp mysql-backup.tar.gz root@新服务器IP:/root/
第四步:新服务器解压
tar -zxvf mysql-backup.tar.gz -C /data/
第五步:新服务器启动容器,挂载数据卷
docker run -d --name mysql -v /data/mysql:/var/lib/mysql -p 3306:3306 mysql:5.7
优缺点
优点: 数据和容器分离,灵活
缺点: 要自己管理数据目录
四、方法3:docker cp拷贝文件
把容器里的文件拷出来。
拷出来
docker cp 容器名:/容器内路径 宿主机路径
例子:
docker cp mynginx:/usr/share/nginx/html /data/backup/html
拷进去
docker cp 宿主机路径 容器名:/容器内路径
例子:
docker cp /data/backup/html/index.html mynginx:/usr/share/nginx/html/
五、MySQL容器备份
备份MySQL数据
docker exec 容器名 mysqldump -uroot -p123456 数据库名 > backup.sql
例子:
docker exec mysql mysqldump -uroot -p123456 test > test.sql
恢复MySQL数据
docker exec -i 容器名 mysql -uroot -p123456 数据库名 < backup.sql
例子:
docker exec -i mysql mysql -uroot -p123456 test < test.sql
六、常见坑
坑1:容器删了数据没了
没用数据卷,容器删了数据全没。
解决: 一定要用 -v 挂载数据卷。
坑2:commit的镜像太大
把整个容器都打包了,包括临时文件。
解决: 尽量用数据卷备份,不要用commit。
坑3:数据权限不对
备份恢复后,容器里读不了数据。
原因: 文件所有者不对。
解决: 改权限:
chown -R 999:999 /data/mysql
(MySQL容器用的是999用户)
坑4:数据库没停就备份
MySQL还在写数据,备份出来不一致。
解决: 用mysqldump逻辑备份,不要直接拷文件。
总结
记住:
- 生产环境一定要用数据卷(-v)
- 小容器用commit快照备份
- 大数据量直接备份数据卷目录
- 数据库用mysqldump逻辑备份
- 备份完要测试能不能恢复
最常用:
# 备份数据卷
tar -zcvf backup.tar.gz /data/容器数据/
# 恢复数据卷
tar -zxvf backup.tar.gz -C /data/
遇到问题加QQ23979811 协助处理
Docker 常用命令大全 Docker
Docker 常用命令大全
Docker 现在开发必备,常用命令一定要熟练。
1. 镜像命令
查看本地镜像:
docker images
搜索镜像:
docker search nginx
拉取镜像:
docker pull nginx:latest
删除镜像:
docker rmi nginx:latest
删除所有镜像:
docker rmi $(docker images -q)
构建镜像:
# 在Dockerfile目录下
docker build -t myapp:1.0 .
2. 容器命令
查看运行中的容器:
docker ps
查看所有容器(包括停止的):
docker ps -a
启动容器:
docker run -d --name mynginx -p 80:80 nginx
参数说明:
- -d:后台运行
- --name:容器名
- -p:端口映射(主机:容器)
- -v:目录挂载
停止容器:
docker stop mynginx
启动已停止的容器:
docker start mynginx
重启容器:
docker restart mynginx
删除容器:
docker rm mynginx
强制删除运行中的容器:
docker rm -f mynginx
删除所有停止的容器:
docker container prune
3. 进入容器
进入容器命令行:
docker exec -it mynginx /bin/bash
退出容器:
exit
4. 日志查看
查看容器日志:
docker logs mynginx
实时查看日志:
docker logs -f mynginx
查看最近100行日志:
docker logs --tail 100 mynginx
5. 文件操作
从主机复制到容器:
docker cp index.html mynginx:/usr/share/nginx/html/
从容器复制到主机:
docker cp mynginx:/etc/nginx/nginx.conf ./
6. 容器信息
查看容器详情:
docker inspect mynginx
查看容器端口映射:
docker port mynginx
查看容器资源使用:
docker stats
7. 数据卷
创建数据卷:
docker volume create mydata
查看数据卷:
docker volume ls
使用数据卷:
docker run -d -v mydata:/data nginx
8. 网络
查看网络:
docker network ls
创建网络:
docker network create mynet
容器加入网络:
docker network connect mynet mynginx
9. 其他常用
查看Docker版本:
docker version
查看Docker信息:
docker info
清理无用资源:
docker system prune
10. 常用组合
启动一个PHP环境:
docker run -d --name php \
-p 8080:80 \
-v /www:/var/www/html \
php:apache
启动MySQL:
docker run -d --name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
启动Redis:
docker run -d --name redis \
-p 6379:6379 \
redis:latest
总结
Docker 常用命令要点:
- docker images 看镜像
- docker ps 看容器
- docker run 启动容器
- docker exec 进入容器
- docker logs 看日志
- docker cp 复制文件
- docker stats 看资源
- -d 后台运行
- -p 端口映射
- -v 目录挂载
Docker 命令熟练了,开发部署效率提升很多。
Docker 查看容器日志 Docker
Docker 查看容器日志
容器出问题怎么排查?先看日志,这些命令要会。
1. 查看容器日志
基本命令
# 查看全部日志
docker logs 容器名
# 查看容器ID
docker logs 容器ID
2. 常用参数
看最后几行
# 最后10行
docker logs --tail 10 容器名
# 最后20行
docker logs --tail 20 容器名
实时跟踪日志(最常用)
docker logs -f 容器名
带时间戳
docker logs -t 容器名
组合使用
# 实时跟踪 + 时间戳 + 最后10行
docker logs -f -t --tail 10 容器名
3. 按时间查看
# 最近10分钟的日志
docker logs --since 10m 容器名
# 最近1小时的日志
docker logs --since 1h 容器名
# 指定时间开始
docker logs --since "2024-01-01T00:00:00" 容器名
4. 多容器日志
docker-compose 查看日志
# 查看所有服务日志
docker-compose logs
# 实时跟踪
docker-compose logs -f
# 查看指定服务
docker-compose logs nginx
# 看最后50行
docker-compose logs --tail 50 nginx
5. 日志持久化
json-file 日志驱动(默认)
- 日志存在 /var/lib/docker/containers/
- 单个容器日志文件
配置日志大小限制
# docker-compose.yml
services:
app:
image: nginx
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
6. 常见排查场景
1)容器启动失败
docker logs 容器名
看最后几行报错信息。
2)接口报错
docker logs -f --tail 100 容器名
实时看请求日志。
3)查某个时间点的错误
docker logs --since "2024-01-01T10:00:00" 容器名 | grep "error"
7. 日志清理
清理单个容器日志
# 找到日志文件
sudo find /var/lib/docker/containers/ -name "*.log"
# 清空日志
sudo sh -c "echo > /var/lib/docker/containers/容器ID/容器ID-json.log"
重启容器自动清理
docker restart 容器名
总结
Docker 查看容器日志要点:
- docker logs 查看日志
- -f 实时跟踪最常用
- --tail 看最后几行
- -t 带时间戳
- --since 按时间查
- docker-compose logs 多容器
- 配置日志大小防止占满磁盘
- 排查问题先看日志
容器运维,看日志是第一步。
Docker容器自动重启,restart=always参数 Docker
前言
服务器重启了,Docker容器没跟着起来?或者容器崩了,不自动重启?本文讲怎么配置自动重启。
一、restart参数
Docker用 --restart 参数控制容器的重启策略。
四种策略
| 策略 | 说明 |
|---|---|
no |
不自动重启(默认) |
on-failure |
非正常退出时重启 |
always |
总是自动重启 |
unless-stopped |
除非手动停了,否则一直重启 |
二、always策略
用法
docker run -d --name nginx --restart=always nginx
什么时候会重启
- 容器崩了(非正常退出)
- Docker服务重启
- 服务器重启(只要Docker开机自启)
特点
- 不管什么原因停了,都会自动起来
- 服务器重启后也会自动启动
三、unless-stopped策略
用法
docker run -d --name nginx --restart=unless-stopped nginx
和always的区别
- always:就算你手动停了,重启Docker后还是会起来
- unless-stopped:如果你手动停了,重启Docker后就不起来了
推荐用unless-stopped,更灵活。
四、on-failure策略
用法
docker run -d --name nginx --restart=on-failure:5 nginx
说明
- 只有非正常退出时才重启
:5表示最多重启5次,超过就不重启了
什么时候用
比如批处理任务,失败了重试几次,一直失败就算了。
五、no策略(默认)
docker run -d --name nginx --restart=no nginx
不自动重启,停了就停了。
六、修改已有容器的重启策略
运行中的容器
docker update --restart=always 容器名
不用删容器,直接改。
例子
docker update --restart=always nginx
docker update --restart=unless-stopped mysql
七、Docker Compose里的配置
services:
nginx:
image: nginx
restart: always
或者:
restart: unless-stopped
八、服务器开机自启
1. Docker服务开机自启
systemctl enable docker
2. 容器开机自启
只要容器设了 --restart=always 或 unless-stopped,Docker启动后容器就会自动启动。
验证
重启服务器试试:
reboot
重启完看看容器起来没:
docker ps
九、查看重启策略
docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' 容器名
输出:
always
十、常见坑
坑1:设了always,服务器重启后没起来
原因: Docker服务没设开机自启。
解决:
systemctl enable docker
坑2:手动停了,又自动起来了
用了 always 策略,手动停了也会起来。
解决: 想彻底停掉:
docker update --restart=no 容器名
docker stop 容器名
坑3:一直重启,死循环
容器启动就崩,崩了又重启,死循环。
检查:
docker logs 容器名
看看为什么启动失败,先把问题修了。
坑4:on-failure重启次数
--restart=on-failure:5
最多重启5次,超过就不重启了。
注意: 这个5是次数,不是间隔。
十一、推荐配置
生产环境推荐
docker run -d \
--name nginx \
--restart=unless-stopped \
-p 80:80 \
nginx
- 服务器重启自动起来
- 手动停了就不自动起
- 灵活
数据库推荐
docker run -d \
--name mysql \
--restart=unless-stopped \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
总结
记住:
--restart=always总是自动重启--restart=unless-stopped推荐,手动停了不自动起- 改已有容器:
docker update --restart=xxx 容器名 - 服务器开机自启要先
systemctl enable docker
最常用:
docker run -d --name nginx --restart=unless-stopped nginx
遇到问题加QQ23979811 协助处理
Docker网络模式详解,bridge、host、none Docker
前言
Docker容器怎么联网的?bridge、host、none这些网络模式啥区别?本文一次讲清楚。
一、Docker网络模式
Docker有5种网络模式:
- bridge:默认模式,桥接网络
- host:主机网络,和宿主机共用
- none:无网络
- container:和另一个容器共用网络
- 自定义网络:自己建的网络
二、bridge模式(默认)
是什么
Docker默认的网络模式。每个容器有自己的虚拟网络,通过docker0网桥和宿主机通信。
特点
- 每个容器有自己的IP
- 容器之间可以通过容器名互相访问
- 外部要访问容器,要靠
-p端口映射
用法
docker run -d --name nginx -p 80:80 nginx
没指定 --network,默认就是bridge。
容器之间通信
docker run -d --name mysql mysql:5.7
docker run -d --name web --link mysql nginx
或者用自定义网络,容器名直接解析:
docker network create mynet
docker run -d --name mysql --network mynet mysql:5.7
docker run -d --name web --network mynet nginx
web容器里直接用 mysql 这个主机名就能连数据库。
三、host模式
是什么
容器直接用宿主机的网络,没有自己的虚拟网卡。
特点
- 没有独立IP,和宿主机共用
- 不用
-p映射,直接用宿主机的端口 - 性能最好,因为少了一层网络转发
- 安全性差点,容器直接暴露在宿主机网络上
用法
docker run -d --name nginx --network host nginx
注意
host模式下,-p 参数无效。容器用什么端口,直接就是宿主机的端口。
比如Nginx监听80,宿主机的80就被占了。
四、none模式
是什么
容器没有网络,完全断网。
特点
- 没有网卡,没有IP
- 只能通过localhost访问
- 适合不需要联网的任务,比如批量处理文件
用法
docker run -d --name test --network none nginx
查看
docker exec test ip addr
只能看到lo回环网卡。
五、container模式
是什么
新创建的容器和一个已有的容器共用网络。
特点
- 两个容器共用同一个网络命名空间
- 用
127.0.0.1就能互相访问 - 适合一个应用拆成多个容器的场景
用法
# 先跑一个web容器
docker run -d --name web nginx
# 再跑一个sidecar容器,和web共用网络
docker run -d --name sidecar --network container:web busybox
sidecar容器里 127.0.0.1 就是web容器的localhost。
六、自定义网络
创建网络
docker network create mynet
使用网络
docker run -d --name mysql --network mynet mysql:5.7
docker run -d --name redis --network mynet redis
好处
- 容器名自动解析,不用写IP
- 网络隔离,不同网络的容器不能互相访问
- 更灵活
查看网络
docker network ls
查看网络详情
docker network inspect mynet
七、常用命令
查看容器网络模式
docker inspect -f '{{.HostConfig.NetworkMode}}' 容器名
查看容器IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 容器名
查看所有网络
docker network ls
删除网络
docker network rm mynet
八、常见场景选什么模式
场景1:跑Web服务,要外网访问
选bridge,用 -p 映射端口。
场景2:追求高性能,比如数据库
选host,少一层转发,性能好。
场景3:不需要联网的任务
选none,安全。
场景4:两个容器紧耦合
选container,共用网络。
场景5:多容器编排
选自定义网络,容器名自动解析。
九、常见坑
坑1:容器之间ping不通
bridge模式下,容器之间默认是通的,但如果用了none就不通。
检查: 网络模式是什么?
docker inspect 容器名 | grep NetworkMode
坑2:host模式下端口冲突
host模式直接用宿主机端口,端口被占了就起不来。
检查: 宿主机端口有没有被占。
坑3:容器名解析不了
默认bridge网络不支持容器名解析。
解决: 用自定义网络。
坑4:改了网络模式,要重新建容器
网络模式是容器创建时定的,不能改。
解决: 删掉容器重新跑。
总结
记住:
- bridge:默认,端口映射,常用
- host:共用宿主机网络,性能好
- none:断网,安全
- container:和别的容器共用网络
- 自定义网络:容器名自动解析,推荐
最常用:
docker network create mynet
docker run -d --name nginx --network mynet nginx
遇到问题加QQ23979811 协助处理
Docker运行Nginx,挂载配置文件和网页 Docker
前言
用Docker跑Nginx,想改网站文件、改配置,每次进容器里改太麻烦。挂载出来就方便多了。本文讲怎么挂载网页和配置文件。
一、基本运行
最简单的跑法
docker run -d --name nginx -p 80:80 nginx
问题: 网站文件和配置都在容器里,改起来不方便。
二、挂载网页目录
完整命令
docker run -d \
--name nginx \
-p 80:80 \
-v /data/www:/usr/share/nginx/html \
nginx
解释
- 宿主机
/data/www目录 - 容器里
/usr/share/nginx/html目录
这样直接在宿主机改网页文件,刷新浏览器就生效了。
测试
在宿主机创建index.html:
echo "<h1>Hello Docker Nginx</h1>" > /data/www/index.html
浏览器访问:
http://服务器IP
就能看到了。
三、挂载配置文件
1. 先从容器里拷出默认配置
docker run -d --name nginx nginx
docker cp nginx:/etc/nginx/nginx.conf /data/nginx/nginx.conf
docker cp nginx:/etc/nginx/conf.d /data/nginx/conf.d
docker rm -f nginx
2. 挂载配置文件
docker run -d \
--name nginx \
-p 80:80 \
-v /data/www:/usr/share/nginx/html \
-v /data/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /data/nginx/conf.d:/etc/nginx/conf.d \
nginx
3. 改配置
直接在宿主机改 /data/nginx/conf.d/default.conf,改完重载:
docker exec nginx nginx -s reload
四、挂载日志
docker run -d \
--name nginx \
-p 80:80 \
-v /data/www:/usr/share/nginx/html \
-v /data/nginx/logs:/var/log/nginx \
nginx
日志直接在宿主机看:
tail -f /data/nginx/logs/access.log
五、Docker Compose完整配置
version: '3'
services:
nginx:
image: nginx:alpine
container_name: nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /data/www:/usr/share/nginx/html
- /data/nginx/nginx.conf:/etc/nginx/nginx.conf
- /data/nginx/conf.d:/etc/nginx/conf.d
- /data/nginx/logs:/var/log/nginx
启动:
docker-compose up -d
六、常用操作
重载配置
改了配置文件后:
docker exec nginx nginx -s reload
查看日志
docker logs nginx
# 实时看
docker logs -f nginx
进容器
docker exec -it nginx sh
七、常见坑
坑1:挂载后网站403
原因: 宿主机目录权限不对。
解决:
chmod -R 755 /data/www
chown -R nginx:nginx /data/www
坑2:改了配置不生效
原因: 没重载配置。
解决:
docker exec nginx nginx -s reload
坑3:挂载文件不存在,变成目录
-v /data/nginx.conf:/etc/nginx/nginx.conf
如果 /data/nginx.conf 不存在,Docker会自动建一个叫nginx.conf的目录。
解决: 先创建文件:
touch /data/nginx.conf
坑4:端口被占用
80端口被宿主机的Nginx占了。
解决: 停掉宿主机的Nginx,或者换端口。
坑5:改了代码不生效
如果用了CDN或者浏览器缓存,强刷一下(Ctrl+F5)。
八、多站点配置
在 /data/nginx/conf.d/ 下建多个配置文件:
/data/nginx/conf.d/
├── site1.conf
├── site2.conf
└── default.conf
site1.conf:
server {
listen 80;
server_name site1.com;
root /data/www/site1;
index index.html;
}
改完重载:
docker exec nginx nginx -s reload
九、HTTPS配置
挂载证书:
docker run -d \
--name nginx \
-p 80:80 \
-p 443:443 \
-v /data/www:/usr/share/nginx/html \
-v /data/nginx/conf.d:/etc/nginx/conf.d \
-v /data/ssl:/etc/nginx/ssl \
nginx
配置文件里引用证书:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
root /data/www;
}
总结
记住:
- 挂载网页目录:
-v /data/www:/usr/share/nginx/html - 挂载配置文件:
-v /data/nginx/nginx.conf:/etc/nginx/nginx.conf - 挂载日志:
-v /data/nginx/logs:/var/log/nginx - 改完配置重载:
docker exec nginx nginx -s reload
最常用:
docker run -d --name nginx -p 80:80 \
-v /data/www:/usr/share/nginx/html \
-v /data/nginx/conf.d:/etc/nginx/conf.d \
nginx
遇到问题加QQ23979811 协助处理
Docker运行MySQL,数据持久化配置 Docker
前言
用Docker跑MySQL,删了容器数据就没了?那是没挂数据卷。本文讲怎么用Docker跑MySQL并持久化数据。
一、基本运行
最简单的跑法
docker run -d \
--name mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
问题: 删了容器,数据库里的数据全没了。
二、加数据卷持久化
完整命令
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
解释
-p 3306:3306端口映射-e MYSQL_ROOT_PASSWORD=123456设置root密码-v /data/mysql:/var/lib/mysql数据卷挂载- 宿主机
/data/mysql目录 - 容器里
/var/lib/mysql目录
- 宿主机
这样容器删了,数据还在宿主机上。
三、其他常用配置
1. 设置字符集
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
-v /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf \
mysql:5.7 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
2. 创建数据库和用户
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=mydb \
-e MYSQL_USER=myuser \
-e MYSQL_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
3. 挂载配置文件
先在宿主机创建my.cnf:
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
max_connections=1000
然后挂载:
docker run -d \
--name mysql \
-v /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
四、Docker Compose方式
version: '3'
services:
mysql:
image: mysql:5.7
container_name: mysql
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
volumes:
- /data/mysql:/var/lib/mysql
- /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
启动:
docker-compose up -d
五、连接MySQL
进入容器连接
docker exec -it mysql mysql -uroot -p123456
从宿主机连接
mysql -h127.0.0.1 -P3306 -uroot -p123456
用Navicat等工具
- 主机:服务器IP
- 端口:3306
- 用户名:root
- 密码:123456
六、备份和恢复
备份数据库
docker exec mysql mysqldump -uroot -p123456 mydb > /data/backup/mydb.sql
恢复数据库
docker exec -i mysql mysql -uroot -p123456 mydb < /data/backup/mydb.sql
七、常见坑
坑1:密码不对
报错:
Access denied for user 'root'@'localhost'
检查: 环境变量 MYSQL_ROOT_PASSWORD 设了没?
坑2:权限问题
宿主机 /data/mysql 目录权限不对:
chmod -R 777 /data/mysql
坑3:端口被占用
3306端口被宿主机的MySQL占了:
Bind for 0.0.0.0:3306 failed: port is already allocated
解决: 换个端口:
-p 3307:3306
坑4:数据没持久化
没加 -v 挂载,删了容器数据就没了。
检查: 有没有 -v /data/mysql:/var/lib/mysql?
坑5:第一次启动慢
MySQL第一次启动要初始化数据,要等个十几秒。
等不及就先别连,过一会再试。
坑6:字符集不对,中文乱码
加参数:
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
八、推荐配置
docker run -d \
--name mysql \
--restart=always \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=你的密码 \
-v /data/mysql:/var/lib/mysql \
-v /data/mysql/my.cnf:/etc/mysql/conf.d/my.cnf \
mysql:5.7
--restart=always开机自动启动- 数据挂载到
/data/mysql - 配置文件挂载
总结
记住:
- 一定要挂数据卷,不然删容器数据就没了
- 用
-e MYSQL_ROOT_PASSWORD设密码 - 用
-p 3306:3306映射端口 - 配置文件也可以挂载进去
最常用:
docker run -d --name mysql -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
遇到问题加QQ23979811 协助处理