news 2026/9/9 17:05:21

Docker常用命令实战:从镜像管理到排障全攻略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Docker常用命令实战:从镜像管理到排障全攻略

1. 内容整体设计与思路拆解

1.1 为什么你总是记不住Docker命令

我见过太多人把Docker当虚拟机用:docker run启动一个容器,docker exec进去敲命令,然后就没有然后了。一旦容器删了就啥都不剩,数据丢了才想起来没挂载卷,IP变了才想起来没用--network。说句不好听的,这不是Docker的问题,是你根本没建立Docker的思维模型。

Docker和虚拟机最大的区别在于:虚拟机是完整的一台“电脑”,你把它当服务器折腾;而容器是“进程”,它天生就是临时、易碎、可丢弃的。你见过有人给一个进程做备份吗?没有。所以Docker的设计哲学是:容器随时可以删,镜像随时可以重新拉,数据必须放卷里,配置必须用环境变量注入。理解了这句话,你再看那些命令,思路就顺了。

那为什么还要整理“常用命令”?因为Docker的命令确实不少,而且很多命令的--选项多得吓人。docker run一个命令就有上百个参数,你不可能全记住,也没必要。真正的用法是:先掌握最核心的30个命令,把日常开发、部署、排障能跑通,其他的用到再查

这篇东西我不会像man手册一样给你罗列所有命令,而是按照实际操作场景来组织:安装启动、镜像管理、容器生命周期、数据卷、网络、日志与排障、镜像构建、Compose编排。每个场景里我只挑真正高频的、踩过坑的命令,附上为什么这么用的解释。

1.2 这套命令体系的适用场景与核心价值

先看这套东西能解决什么问题。本地开发环境搭建:装个 MySQL、Redis、Nginx,用 Docker 一条命令起来,不用再往自己电脑里装一堆原生服务,脏了系统还得卸载。项目交付部署:用 Dockerfile 把应用打成镜像,到服务器上docker run直接跑,依赖、环境变量、启动命令全都固化在镜像里,从“在我机器上能跑”变成“在哪都能跑”。多环境一致性:开发、测试、生产用同一套镜像,避免“开发好好的,测试崩了”的经典问题。微服务本地联调:一个docker-compose.yml把 MySQL、Redis、Nacos、微服务全拉起来,一条命令搞定。这些场景解决的是同一个核心痛点:环境的一致性与交付效率

我给你的价值不是列命令,而是把每条命令背后的判断逻辑讲清楚。比如同样都是删容器,docker rmdocker rm -f有什么区别?docker rmidocker image prune分别什么时候用?这些如果只背命令不去理解,遇到真实场景还是会卡壳。

适合看这篇内容的读者,我大致分三类:

  • Docker 新手,刚装好环境,想知道从哪下手,怎么不把系统搞坏。
  • 用了半年一年但一直靠复制粘贴,想系统梳理一下命令体系的开发者。
  • 要把 Docker 用到生产环境的运维或全栈工程师,需要掌握排障思路和最佳实践。

无论你是哪一类,我的建议是:别背命令,跟着场景走。你在真实需求里用过的命令,比看十遍文档记得都牢。

2. 安装与基础环境配置实操

2.1 Docker Engine 与 Docker Desktop 怎么选

先解决安装问题。现在装 Docker 基本两条路:装 Docker Engine(服务端+命令行客户端),或者装 Docker Desktop(带图形界面的一体化工具)。

如果你用的是 Linux,直接装 Docker Engine。装完以后顺手做两件事:

# 把当前用户加入 docker 组,避免每次敲命令都加 sudo sudo usermod -aG docker $USER # 让 Docker 开机自启 sudo systemctl enable docker sudo systemctl start docker

注意第一个命令执行完要重新登录终端才生效。很多人改完直接敲docker ps发现还是提示权限不够,其实是没重新登录。

如果你是 Windows 或 macOS,正常推荐 Docker Desktop。但我必须提醒几个常见坑。Docker Desktop 启动的时候报 “WSL 2 kernel version is too low” 或者 “Virtualization support was detected but it is disabled” 这种错误,基本都是两个原因:一是 Windows 的虚拟化功能没开,去 BIOS 里把 Intel VT-x 或 AMD-V 打开;二是没启用 Windows 的“适用于 Linux 的 Windows 子系统”和“虚拟机平台”这两个可选功能,用管理员权限跑一下:

# Windows 10/11 管理员 PowerShell dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

执行完重启,然后再装或重启 Docker Desktop。还有一个坑:某些 Windows 版本对 Docker Desktop 有版本要求,系统太旧会直接提示“incompatible version of Windows”,那就先升级系统补丁,别硬装。

2.2 配置镜像加速,解决拉取慢的老大难问题

装好之后第一个痛点必然是:拉镜像慢。国内直连 Docker Hub 的速度,懂的都懂,一个几百兆的镜像可能拉到一半超时。解决办法是配置镜像加速器。

Linux 下在/etc/docker/daemon.json里写:

{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://dockerproxy.com", "https://docker.nju.edu.cn" ] }

然后重启:

sudo systemctl daemon-reload sudo systemctl restart docker

Docker Desktop 直接在设置界面的 Docker Engine 里改同样的 JSON,点 Apply & Restart 就行。

这里有个要点:加速器只对 Docker Hub 上的官方镜像和标准仓库生效。你要是从私有仓库或者 ghcr.io 拉镜像,加速器没用,得另想办法。另外这些加速地址时效性比较强,建议用之前先确认哪些还活着,多配几个作为兜底也是可以的。

配置完怎么看有没有生效?docker info输出的 Registry Mirrors 一节里能看到你配置的地址。然后试拉一个镜像测速度:

docker pull alpine docker images

Alpine 才几兆,拉得快又不占空间,拿来做连通性测试最合适。

2.3 验证环境是否正常的三个命令

环境装好、加速配好之后,用这三条命令确认一切正常:

docker version docker info docker run --rm hello-world

docker version看客户端和服务端版本,两个都要显示才说明 daemon 在跑。docker info看存储驱动、CPU/内存配额、镜像加速器的配置。最后跑hello-world是经典的“验证容器能正常创建和运行”的手段,--rm让它跑完自动删掉,不残留垃圾。

如果你执行docker run hello-world报错Cannot connect to the Docker daemon,通常就是 daemon 没启动,或者/var/run/docker.sock权限不对。按之前说的加入 docker 组重新登录,或者先sudo systemctl start docker拉起来再跑。

3. 镜像管理的核心命令与实操细节

3.1 镜像的拉取、查看与删除

镜像(Image)是容器的模板。理解这一点很重要:镜像相当于一个打包好的操作系统+运行环境的只读快照,容器是它的一次运行实例。你可以从同一个镜像启动无数个容器,它们互不影响,因为每个容器都有独立的可写层。

拉镜像的命令:

docker pull ubuntu:22.04 docker pull mysql:8.0 docker pull nginx:latest

语法是docker pull 仓库名:标签。标签不写默认是latest,但生产环境我强烈建议永远指定具体版本,否则过段时间你再docker pull拉下来一个完全不同的镜像,可能 API 变了、配置不兼容了,全得返工。

看本地有哪些镜像:

docker images # 或 docker image ls,效果一样

这个命令输出五列:REPOSITORY(仓库名)、TAG(标签)、IMAGE ID(镜像ID)、CREATED(创建时间)、SIZE(大小)。有个小技巧,docker images -a能看到所有镜像,包括中间层镜像;平时不用加,除非要排查构建缓存问题。

删除镜像:

docker rmi ubuntu:22.04 # 强制删除 docker rmi -f ubuntu:22.04

正常删除前,Docker 会检查是否有容器正在使用这个镜像,有的话会报错提示。所以想删除一个镜像,得先把相关容器停掉删掉。-f强制删除我不是很推荐日常用,容易顺手把正在使用的镜像删了,后面排查问题才想起来。

另外docker image prune能清理所有悬空镜像(即没有任何标签、也没有被容器引用的中间层镜像):

# 清理所有悬空镜像 docker image prune # 连未被使用的镜像一起清掉,-a 表示 all docker image prune -a

这个命令配合docker system df看磁盘占用情况特别有效。磁盘不够了,先docker system df看看哪一类占用最大,再针对性地清。

3.2 镜像标签的补充技巧

给本地镜像打标签有两种场景:一是本地构建完镜像,想推送到自己的仓库;二是想给某个镜像加个别名,方便后续操作。

docker tag myapp:v1.0 registry.example.com/myapp:v1.0

打完标签后,你会发现docker images里两条记录,镜像 ID 一样。这其实没有占双倍空间,只是同一份镜像多了两个引用。打标签在推送镜像前是必须的一步,因为docker push时仓库地址和命名空间都写在标签里。

还有一个挺管用的操作:用镜像 ID 来操作镜像。比如docker rmi 3b5a4a5b5e7a这种直接删,不用记完整仓库名。但注意 ID 可以只写前几位,只要不冲突就行,一般写前4位就够了,懒人福音。

3.3 镜像的导入导出

在某些内网环境里没法直接拉镜像,就得用 tar 包离线搬运:

# 导出镜像为 tar 文件 docker save -o ubuntu-22.04.tar ubuntu:22.04 # 导入 tar 文件为镜像 docker load -i ubuntu-22.04.tar

注意docker savedocker export有本质区别。save是把镜像完整的层级结构保存下来,适合镜像分发;export是把容器的文件系统导出成一个 tar,会丢失历史、层信息和元数据,适合做文件系统快照,不适合做镜像迁移。这个区别我踩过坑:有次图省事用docker export导容器再docker import,结果起来了发现 CMD、环境变量全丢了,应用起不来。你要迁移镜像就用save/load,别混。

4. 容器生命周期:从启动到删除的完整实操

4.1 docker run 的关键参数

容器是 Docker 的核心操作对象,docker run是最常用的命令,没有之一。每次创建一个新容器并启动,就是把镜像的实例跑起来。先看一个比较完整的例子:

docker run -d \ --name my-mysql \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ -v /my/data/mysql:/var/lib/mysql \ --network my-net \ --restart always \ mysql:8.0

我来逐项拆解这些参数。-d意思是后台运行,不加的话容器会挂在前台,你一关终端容器就停了。--name给容器起名字,不然 Docker 随机生成一个又长又怪的名字,管理起来非常痛苦。-p 3306:3306做端口映射,宿主机端口:容器端口,这样外部才能通过宿主机的3306端口访问容器里的 MySQL。-e注入环境变量,MySQL 镜像就是靠MYSQL_ROOT_PASSWORD这个变量来初始化密码的。-v挂载数据卷,把容器里的数据目录映射到宿主机路径,这样容器删了数据也还在。--network指定网络,多个容器可以通过自定义网桥互联。--restart always设置容器退出后自动重启,服务挂了能自动拉起来。

这里的核心思想是:run是一次性的。如果你只是敲docker run nginx,然后 Ctrl+C 退出,容器就变成 Exited 状态,下次你还得重新docker run。所以要么-d后台跑,要么配合--restart保证服务可用。

4.2 容器的查看与进入

查看正在运行的容器:

docker ps

看所有容器,包括已停止的:

docker ps -a

docker ps -a在排障时尤其有用。容器秒退、不断重启,你首先就要docker ps -a看它是不是 Exited 了,然后docker logs看日志找原因。

进入正在运行的容器,主流有两种方式:

# 方式一:exec 进入并启动 bash docker exec -it my-mysql bash # 方式二:如果你只想去执行单条命令 docker exec -it my-mysql mysql -uroot -p

-i是交互模式,-t是分配一个伪终端,两个组合在一起才像是“打开了一个终端窗口”。注意exec不启动新容器,是在现有容器里执行命令,这是和run最本质的区别。

容器里没有 bash 怎么办?有些精简镜像只有 sh:

docker exec -it my-container sh

连 sh 都没有的极简镜像,比如scratch或某些 distroless 镜像,你甚至没法进去,只能靠日志排障。这也提醒你:基础镜像选型时,如果后续有调试需求,别一味追求小,留个 shell 能省很多事。

4.3 容器的启停、重启与删除

docker stop my-container # 优雅停止,默认等10秒后再杀 docker start my-container # 启动已存在的容器 docker restart my-container # 重启 docker kill my-container # 强制杀掉

stopkill的区别值得展开说。stop会先给容器内主进程发一个 SIGTERM 信号,让它有善后清理的机会,等默认 10 秒超时后再发 SIGKILL。kill是直接 SIGKILL,立刻杀掉,不给机会。日常首选stop,除非进程卡死了再kill

删除容器:

docker rm my-container # 强制删除运行中的容器 docker rm -f my-container # 清理所有已停止的容器 docker container prune

docker rm只能删已停止的容器,删运行中的会报错。-f会先强制 stop 再删。docker container prune会把所有已停止容器一次性清理掉,包括之前忘删的。

批量清理容器的常用组合:

# 删除所有已停止容器 docker rm $(docker ps -aq --filter "status=exited") # 停止所有容器 docker stop $(docker ps -q)

这个$(docker ps -q)的用法很香,-q只输出容器 ID,配合其他命令做批量操作非常方便。不过批量操作前先用docker ps -a确认一下到底会影响到哪些容器,别手滑把该留的也删了。

4.4 容器与宿主机之间的文件拷贝

开发调试时经常要把本地文件拷进容器,或者从容器里拷日志出来:

# 从宿主机拷进容器 docker cp ./config.yml my-container:/app/config.yml # 从容器拷到宿主机 docker cp my-container:/var/log/nginx/access.log ./access.log

docker cp不需要容器在运行状态,已停止的容器也能拷。这个很实用,比如容器起不来,但你想看看容器里的配置文件时,docker cp出来看就行。

还有一个场景:docker cp拷贝整个目录也行:

docker cp ./data/ my-container:/data/

注意目录拷目录时,目标路径末尾是否带/会影响结果——带/表示拷贝到该目录下,不带则可能改名,细节参照cp命令的行为。

5. 数据卷、网络与日志排障的实战加深

5.1 数据卷的挂载与权限踩坑

前面提到-v挂载数据卷,这是 Docker 里最容易踩坑的地方。先看两种挂载方式:

# 方式一:绑定挂载(把宿主机的文件或目录挂进去) docker run -d --name nginx -v /home/user/html:/usr/share/nginx/html nginx # 方式二:命名卷(Docker 管理存储位置,数据在宿主机上但不用关心路径) docker volume create mydata docker run -d --name mysql -v mydata:/var/lib/mysql mysql:8.0

两种方式的区别:绑定挂载适合你把配置文件放宿主机、直接改文件就生效的场景;命名卷适合数据库这种纯数据存储,Docker 会在宿主机上找一个卷目录帮你存,不用自己指定路径。

权限坑是重点。很多人挂载宿主机目录后,容器里进程报权限不足。原因是容器内进程默认以 root 或指定 UID 运行,而宿主机目录可能是别的用户所有,或者 SELinux 标签不对。一个典型场景:MySQL 容器挂载了一个目录,结果报[ERROR] [MY-011011] ... Directory '/var/lib/mysql' ... permission denied

解决办法:要么给目录开权限chmod -R 777,要么指定容器内用户--user 1000:1000(要和宿主机目录属主一致),要么用命名卷让 Docker 管理权限。我一般更推荐用命名卷解决权限问题,省心很多。

5.2 网络模式与容器互联

Docker 网络是个大话题,但日常你只需要掌握几个基础点。默认情况下 Docker 有一个 bridge 网桥,容器通过它联网和互相通信。

# 创建自定义网络 docker network create my-net # 指定容器使用该网络 docker run -d --name mysql --network my-net mysql:8.0 docker run -d --name app --network my-net myapp:latest

在同一个自定义网络里,容器之间可以通过容器名直接互相访问。比如 app 容器里连数据库,host 写mysql:3306而不是 IP。这比用 IP 靠谱多了,容器重建 IP 会变,但名字不变。

查看网络:

docker network ls docker network inspect my-net

inspect会列出网络里的容器、网关、子网等详细信息。排查容器为什么互相 ping 不通,首先就该检查它们是否在同一个网络里。

比较常见的坑是:启动容器时忘了指定网络,容器都在默认 bridge 里,理论也能互联,但默认 bridge 不支持 DNS 解析,你得用 IP 访问,容器一重建 IP 就变了。所以多容器之间要通信,一定建自定义网络,这算是我比较强烈的一个建议。

5.3 日志查看的常用姿势

容器排障第一工具就是日志:

# 查看最近日志 docker logs my-container # 实时跟踪日志输出,相当于 tail -f docker logs -f my-container # 只看最后100行 docker logs --tail 100 my-container # 按时间过滤 docker logs --since 2024-01-01T08:00:00 my-container # 或只看最近30分钟 docker logs --since 30m my-container

日志这块有个实际经验:如果容器一直报错刷日志导致磁盘被写满,Docker 默认的 json-file 日志驱动不限制大小,短时间内能占到几十个 G。建议在daemon.json里做全局日志轮转配置:

{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } }

配置完重启 Docker,只对新建容器生效,已有容器不受影响。或者也可以在docker run时单独加--log-opt max-size=100m --log-opt max-file=3。这个坑我是在生产环境被教育过的,不配日志轮转的容器就像不清理的日志文件,迟早把磁盘搞爆。

5.4 inspect 与 system df 的排障用法

日志看完依然找不到原因,就需要看容器细节:

docker inspect my-container

inspect输出是一个巨大的 JSON,包含容器的全部元数据:环境变量、挂载点、网络配置、启动命令、重启策略、运行状态等。内容太多不好找,可以用--format配合 Go 模板筛选:

# 只看容器的 IP 地址 docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-container # 只看挂载情况 docker inspect -f '{{json .Mounts}}' my-container # 只看重启次数 docker inspect -f '{{.RestartCount}}' my-container

关于--format这个玩法,我建议你收藏几个高频模板,用得多了自然就明白 Go 模板的基本写法。不用每个字段都背,用到时docker inspect输出 JSON 里搜就行。

再看磁盘占用:

docker system df

输出有四行:Images、Containers、Local Volumes、Build Cache,分别显示占用磁盘大小。这是个很直观的“Docker 吃了我多少磁盘”答案来源。依次执行docker image prunedocker container prunedocker volume prunedocker builder prune就能逐个清理。

特别提醒:docker volume prune很重要,如果目录是数据卷,没有容器引用时它不会被自动删除,长期积累会很占空间。但反过来,这个命令会把所有没被容器引用的卷全删掉,如果有你想留的,得先确认再执行。

6. 日志排障之外的常见场景速查

6.1 构建镜像需要掌握的 Dockerfile 基础

日常开发中,你不会只docker pull别人的镜像,还得构建自己的镜像。Docker 构建镜像的入口是docker build

# 使用当前目录下的 Dockerfile 构建 docker build -t myapp:v1.0 . # 指定 Dockerfile 路径 docker build -f /path/to/Dockerfile -t myapp:v1.0 .

-t是打标签,.表示构建上下文路径。注意这里的上下文:docker build会把.目录下所有文件打包发给 daemon,所以目录里没什么用的文件尽量清理掉,或者用.dockerignore排除,不然构建会把很多垃圾传进去,速度慢镜像还大。

一个最简单的 Node.js 项目 Dockerfile 示例:

FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD ["node", "app.js"]

大致的意义是:基于 node 基础镜像,设置工作目录,先把 package.json 拷进去装依赖(利用层缓存提升效率),再拷源码,暴露 3000 端口,指定启动命令。

构建完成后查看镜像:

docker images | grep myapp

如果要推送到镜像仓库,先打标签再推送:

docker tag myapp:v1.0 myregistry.com/library/myapp:v1.0 docker push myregistry.com/library/myapp:v1.0

6.2 Docker Compose 一次拉起整套服务

微服务或本地开发环境往往不止一个容器,靠docker run一行行敲太痛苦。Docker Compose 可以让你用 YAML 声明式地定义多个服务,一条命令搞定。

先看一个经典的docker-compose.yml(新版 Compose 可以不带version字段):

services: mysql: image: mysql:8.0 container_name: my-mysql environment: - MYSQL_ROOT_PASSWORD=root123 - MYSQL_DATABASE=appdb ports: - "3306:3306" volumes: - mysql-data:/var/lib/mysql restart: always redis: image: redis:7.0 container_name: my-redis ports: - "6379:6379" restart: always app: build: ./app container_name: my-app depends_on: - mysql - redis environment: - DB_HOST=mysql - REDIS_HOST=redis ports: - "8080:8080" restart: always volumes: mysql-data:

docker-compose.yml所在目录执行:

# 启动所有服务 docker compose up -d # 查看服务状态 docker compose ps # 查看日志 docker compose logs -f # 停止所有服务 docker compose down # 停止同时删除数据卷(慎用,会清数据) docker compose down -v

注意新版 Docker 已经用docker compose(中间没有横杠)替代docker-compose(旧版独立命令)。如果你还在用docker-compose,建议升级并改用新命令。

depends_on只能保证启动顺序,不保证依赖完全就绪。比如 app 的 DB_HOST 指向 mysql,但 mysql 还在初始化,app 连接数据库就报错。解决方式通常是让应用具备重试机制,或者在 Compose 文件里用healthcheck加健康检查,再配合condition: service_healthy。这涉及一点高级用法,但这个知识点在生产中非常重要,建议有空就去查一下相关文档。

6.3 从容器生成新镜像

有时候你在容器里手动改了配置、装了软件,想让这个状态成为新镜像保存下来,用docker commit

docker commit my-container myapp:manual

这个用法我一般不建议当成常规操作。因为commit会把容器可写层整体打包成镜像,里面可能包含临时文件、历史操作残留,镜像臃肿不说,整个构建过程也不可重复。更规范的方式永远是写 Dockerfile,让构建流程可审计、可复现。commit只适合紧急情况下快速保存现场,比如容器快挂了先存个快照。

6.4 常见报错与排查速查表

最后把实际中高频遇到的报错整理成一个速查表,直接照着办:

报错信息原因排查及解决
Cannot connect to the Docker daemondaemon 未启动或 socket 权限不足systemctl start docker或检查用户是否在 docker 组
Port is already allocated端口被占用docker ps查看占用端口的容器,删掉或换端口
No space left on device磁盘满了或 inode 用完docker system df清理镜像、容器、卷;df -h确认宿主磁盘
pull access denied镜像不存在或没有权限检查仓库名和标签是否写错;私有仓库需要docker login
exec: "bash": executable file not found容器内没有 bash改用docker exec -it 容器名 sh
restarting (x) ... seconds ago容器启动后崩溃在反复重启docker logs 容器名看日志定位崩溃原因
OCI runtime exec failed容器已停止或 exec 参数错误docker ps -a确认容器还在运行;确认命令路径存在
mounted volume permission denied挂载目录权限不足chmod 目录或换命名卷;必要时--user指定 UID

这些报错基本覆盖了日常使用和环境搭建的 80% 问题。真遇到没见过的情况,第一反应应该是docker logsdocker inspect,先把可观测数据拿全,再决定怎么处理,别上来就删容器,删完要再拉数据就麻烦了。

7. 我踩过的坑与给你的建议

7.1 别拿容器当虚拟机

我见过很多人的用法是:docker run起一个 Ubuntu 容器,然后docker exec进去,像在虚拟机里一样装软件,改配置。这种做法首先是不符合镜像不可变、容器可丢弃的核心理念;其次是容器一删,所有改动全没了,如果没提前 commit 或挂数据卷,等于白忙。

正确的做法是:把应用、依赖、启动命令都固化在 Dockerfile 里。容器只是运行应用的一个进程壳,出了任何问题,直接删掉重新run一个,几秒钟的事。数据靠卷持久化,配置靠环境变量注入,日志靠docker logs和日志驱动收集。这套思路想明白了,你才算真正用对了 Docker。

7.2 批量操作之前务必先看一眼

docker rm $(docker ps -aq)docker volume prune -a这类批量命令很高效,但也危险。我建议你在敲这类命令之前,先跑一下不带删除动作的查询命令,确认自己到底会删掉哪些东西。比如:

# 先看看有多少容器、哪些状态 docker ps -a --format "table {{.Names}}\t{{.Status}}"

确认无误再执行批量删除。尤其docker volume prune,删了数据卷就是真的删了,没有后悔药。宁可多花十秒看清楚,也别事故后拍大腿。

7.3 随手加 --rm 让临时容器自动清理

如果是跑一次性任务的容器,比如临时跑个脚本、试个镜像,我建议直接加--rm

docker run --rm -it ubuntu:22.04 bash

这样容器退出时自动清理文件系统,不会留一堆已停止的容器堆着。这个习惯能很好保持开发机干净整洁。

7.4 给容器起个好名字

--name字段别偷懒。docker run --name test看着像没问题,但过了一周你根本想不起来这个容器是干嘛的。推荐命名规则:项目名-服务名-环境,比如order-service-prodmall-mysql-dev。配合 Compose 时,container_name保持一样。好的命名能让后续docker ps一眼看明白,省不少心智负担。

7.5 定期做一次 Docker 环境体检

一个小习惯:不定时执行docker system df看磁盘占用,再执行docker ps -a看有没有堆积的旧容器,然后趁机清理。同时看一眼docker infoServer Version和存储驱动,确保版本处于可维护状态。这个“体检”不需要很频繁,一到两周一次即可,但能避免很多因为磁盘占满、容器冲突引发的问题。

我个人实际用下来,docker 这套命令体系并不难,难的是改变“把容器当虚拟机”的思维习惯。真正常用命令其实就十几个,你梳理清楚场景,每个场景再沉淀出几条固定写法,日常效率就能提升非常明显。后续如果有需要,还可以往镜像多阶段构建、Compose 健康检查、容器监控方向继续深入。先把这篇文章里的命令亲手敲一遍,再回去读 Docker 文档,你会发现理解完全不一样。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 17:03:50

2026牛客网Java面试核心考点总结:JVM、并发、Spring与数据库

2026年牛客网Java面试题总结:我刷了三个月牛客后提炼出的核心考点又到了一年金三银四,后台不少朋友私信问我:牛客网的Java面试题到底该怎么刷?哪些题才是大厂真正会问的?说实话,我从去年年底开始系统性刷牛…

作者头像 李华
网站建设 2026/9/9 17:01:08

CompuCell3D入门:细胞波特模型与多细胞仿真环境搭建指南

做细胞群体仿真这行,绕不开一个名字:CompuCell3D。这是我近几年在肿瘤生长、细胞粘附排序、形态发生这些课题上用得最顺手的开源仿真平台。它解决的核心问题很直接:如何让成千上万个细胞在计算机里"活起来",让它们自己迁…

作者头像 李华
网站建设 2026/9/9 17:01:06

考虑风光不确定性和双向备用的电力系统鲁棒优化调度

1. 项目概述与问题背景搞过电力系统优化调度的人应该都有同感:风光出力预测数据永远是“看起来很美”,实际运行起来总会被现实打脸。今天要聊的这个问题,针对的就是这个痛点——风光负荷不同鲁棒性对系统总成本的影响,同时把系统向…

作者头像 李华
网站建设 2026/9/9 16:59:27

CPU不高却延迟飙升?从线程池到连接池的线上排障实战

半夜两点,监控告警突然响起:订单接口的 P99 延迟从 50ms 一路涨到 4.2s,错误率也在缓慢爬升。你打开服务器面板,第一眼看到的是 CPU 利用率只有 15%,内存还剩一大半,load average 也不算离谱。你第一反应是…

作者头像 李华
网站建设 2026/9/9 16:58:31

基于伴随灵敏度分析的肿瘤放疗时空优化:Matlab实现与实战

最近在整理一个和肿瘤生长模型相关的 Matlab 项目时,我把伴随灵敏度分析(Adjoint Sensitivity Analysis)完整跑通了一遍。整个过程最大的感受是:这个技术在国内的医学物理和计算生物领域讨论得不算多,但它在时空放射治…

作者头像 李华
网站建设 2026/9/9 16:58:28

深入剖析ConcurrentHashMap:从JDK7到JDK8的实现与实战避坑指南

从一次线上事故说起:为什么并发场景必须拥抱ConcurrentHashMap大概两年前,我负责的一个订单服务在大促期间突然出现CPU飙升,紧接着一批请求超时。刚开始大家都以为又是数据库连接池被打满了,结果一查线程栈,发现大量线…

作者头像 李华