服务器运维 Docker 常用指令速查
日常维护自托管服务器,时间大多耗在两类事情上:系统资源出问题时要快速定位,容器服务起不来、连不上、磁盘悄悄膨胀时要逐层排查。这篇速查按照排查的顺序来整理常用指令,命令都在本机 Docker 29.5.3、Docker Compose v5.1.4 上实际验证过;Linux 系统命令针对 Debian/Ubuntu 系 systemd 环境。
系统资源与进程排查
先看机器整体状态,再缩小到进程:
uptime # 负载与开机时长
free -h # 内存用量,-h 人类可读
df -h # 磁盘分区用量
du -sh /var/lib/docker # 某个目录占用的空间
top # 实时进程视图,按 P 按 CPU 排序,按 M 按内存排序
ps aux --sort=-%mem # 一次性快照,按内存降序
ss -tlnp # 监听端口与对应进程,替代已过时的 netstat
journalctl -xe # 最近的系统日志与错误
systemctl status <service> # 某个 systemd 服务的状态与最近日志
排查时一般按这个顺序来:uptime 看负载,free -h 看内存,df -h 看磁盘,这三项都正常再往下用 top / ps 定位进程。ss -tlnp 对付”端口被占用""服务没监听”这类问题,比拿 telnet 一个个试连要直接得多。
容器生命周期管理
创建并运行容器
docker run -d --name web -p 8080:80 -v /data:/app/data -e TZ=Asia/Shanghai nginx:latest
最常用的选项:
| 选项 | 作用 |
|---|---|
-d | 后台运行 |
--name | 指定容器名,后续命令用名字代替 ID |
-p 8080:80 | 端口映射:宿主机 8080 映射到容器 80 |
-v /data:/app/data | 挂载目录:宿主机 /data 挂到容器 /app/data |
-e KEY=value | 设置环境变量,时区、数据库连接串等 |
-i -t | 配合使用进入交互终端(常写作 -it) |
--rm | 容器退出时自动删除,适合临时容器 |
--restart unless-stopped | 退出自动重启,开机自启,自托管服务常用 |
--network <网络名> | 加入指定网络,跨容器通信用 |
单条命令跑一个服务时,建议把 --restart 一并写上,不然服务器一重启,容器不会自己回来。
查看容器
docker ps # 只显示运行中的容器
docker ps -a # 包括已停止的
docker ps -a -q # 只输出 ID,配合批量操作
docker ps -a --format '{{.Names}}\t{{.Status}}\t{{.Ports}}' # 自定义列
docker ps -a 是排查”服务怎么没了”的第一步:容器可能崩溃后退出了,STATUS 列会给出退出码,比如 Exited (1),比翻系统日志更早暴露问题。
启停与删除
docker start <container> # 启动已存在的容器
docker stop <container> # 优雅停止,先发 SIGTERM
docker restart <container> # 重启
docker rm <container> # 删除容器
docker rm -f <container> # 强制删除运行中的容器
docker rm -v <container> # 删除容器时顺带删除其匿名卷
docker rename <old> <new> # 改名
进入容器与文件拷贝
docker exec -it <container> bash # 进入容器执行命令,容器内有 bash 时
docker exec -it <container> sh # 没有 bash 的镜像(alpine 系)用 sh
docker exec <container> env # 查看容器内环境变量,不进入容器
docker cp <container>:/etc/nginx/nginx.conf ./ # 从容器拷出文件
docker cp ./backup.sql <container>:/tmp/ # 拷入容器
docker exec 只对运行中的容器有效。容器已经退出的情况下,先 docker start 再进去,或者干脆用 docker cp 把文件拷出来看。
容器内部信息
docker top <container> # 容器内的进程列表
docker port <container> # 端口映射关系
docker inspect <container> # 完整配置(JSON),-f 可只取指定字段
docker inspect -f '{{.State.Status}}' <container> # 状态
docker inspect -f '{{.NetworkSettings.IPAddress}}' <container> # 容器 IP
docker inspect -f 配合 Go template 可以只挑需要的字段,比输出一整份 JSON 好读得多。字段路径拿不准时,先跑一遍不带 -f 的完整输出再挑。
镜像管理
docker images # 本地镜像列表
docker images -q # 只输出 ID
docker pull nginx:alpine # 拉取镜像,建议带标签
docker rmi nginx:alpine # 删除镜像
docker tag nginx:alpine myreg.local/nginx:alpine # 打标签,推送私有仓库前常用
docker build -t myapp:1.0 . # 用当前目录的 Dockerfile 构建
docker build -f Dockerfile.prod -t myapp:1.0 . # 指定 Dockerfile
docker build --no-cache -t myapp:1.0 . # 不用缓存层重新构建
docker push myreg.local/nginx:alpine # 推送到仓库
docker history nginx:alpine # 镜像分层历史
docker inspect nginx:alpine # 镜像元数据
docker history 排查”镜像为什么这么大”时很管用,每一层新增了什么都能看到;docker images 里 <none> 标签的悬空镜像大多是反复构建留下的,属于清理对象。
日志与监控
docker logs <container> # 查看全部日志
docker logs -f <container> # 跟踪输出,类似 tail -f
docker logs --tail 100 <container> # 只看最后 100 行
docker logs --since 30m <container> # 最近 30 分钟
docker logs -t <container> # 带时间戳,排查顺序问题时有用
docker stats # 实时资源占用(CPU/内存/网络)
docker stats --no-stream # 只取一次快照,适合写入脚本
容器反复重启时,先 docker logs --tail 50 <container> 看最后一段日志,再用 docker ps -a 对照退出码,大多数情况到这里就能定位。docker stats --no-stream 是抓容器资源占用最省事的方式。
网络与端口
docker network ls # 网络列表
docker network create mynet # 创建自定义网络
docker network connect mynet <container> # 容器加入网络
docker network disconnect mynet <container>
docker network inspect mynet # 查看网络内成员与容器 IP
自定义网络相比默认 bridge 有两个实际好处:容器之间可以用容器名互相访问,网络自带 DNS 解析;不同网络之间默认互相隔离。
端口与连通性排查组合:
docker ps # 看端口映射是否生效
docker port <container> # 确认映射关系
ss -tlnp # 确认宿主机端口在监听
curl -v http://localhost:8080/ # 本机验证服务是否响应
端口映射有几个常见坑:容器起来了但 ss 里看不到端口,多半是 -p 没写对,或者容器内进程根本没在监听;映射了却访问超时,就要回头查云厂商安全组和宿主机防火墙,ufw status / iptables -L 各看一眼。
数据卷
docker volume ls # 卷列表
docker volume create mydata # 创建命名卷
docker volume inspect mydata # 卷的挂载点与驱动信息
docker volume rm mydata # 删除卷
docker rm 删容器不会连卷一起删,卷里的数据因此得以保留,自托管数据库容器(MySQL、Postgres)通常配命名卷,冲的就是这一点。备份一个卷的思路是先起个临时容器把卷打包:
docker run --rm -v mydata:/data -v "$PWD":/backup alpine tar czf /backup/mydata.tar.gz -C /data .
恢复时反向解包就行。这套流程取自 Docker 官方文档推荐的卷备份做法,alpine 镜像自带 tar,不用额外装工具。
Docker Compose 项目级操作
多个容器组成一个服务,比如 nginx 加后端加数据库,用 Compose 管理比逐个 docker run 靠谱,配置统一收敛在 compose.yaml 里:
docker compose up -d # 启动项目,-d 后台运行
docker compose up -d --build # 改了 Dockerfile 后重建镜像再启动
docker compose down # 停止并删除项目容器与网络
docker compose ps # 项目内容器状态
docker compose logs -f # 跟踪所有服务的日志
docker compose logs web # 只看某个服务的日志
docker compose exec web bash # 进入某个服务容器
docker compose restart web # 重启单个服务
docker compose config # 校验并打印最终配置
docker compose pull # 拉取新镜像
docker compose config 适合在改完 compose.yaml 之后先跑一遍,语法或缩进错误当场就报出来,比等 up 失败再排查省时间。
磁盘清理
docker system df # 各类对象占用概览
docker system df -v # 详细到每个对象
docker system prune -a -f # 清理:停止的容器、未使用的网络、悬空和未用镜像
docker system prune --volumes -f # 连带清理未使用的卷
docker system df 的 TYPE 列把镜像、容器、卷、构建缓存分开统计,先看清楚哪类占得多,再决定清理目标。两个注意点:
prune -a会删掉所有没有被容器引用的镜像,要是线上只有这一份镜像,容器又恰好全停了,清完就得重新拉取;--volumes默认不参与prune,这是刻意保留的。误删卷没有撤销手段,只有确认卷里的数据确实不再需要了,才加这个选项。
常用组合速查
| 目的 | 命令 |
|---|---|
| 看所有容器及退出码 | docker ps -a |
| 进容器排查 | docker exec -it <container> sh |
| 看最后 100 行日志 | docker logs --tail 100 <container> |
| 跟踪日志 | docker logs -f <container> |
| 容器资源占用快照 | docker stats --no-stream |
| 磁盘占用概览 | docker system df |
| 一键清理悬空对象 | docker system prune -a -f |
| 端口连通性 | ss -tlnp + curl -v http://localhost:<port>/ |
上面这些命令覆盖了日常运维的大多数场景。要牢记的规则只有一条:删除类操作(rm、rmi、prune)先确认对象名再动手,删卷尤其要三思。