服务器运维 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>/

上面这些命令覆盖了日常运维的大多数场景。要牢记的规则只有一条:删除类操作(rmrmiprune)先确认对象名再动手,删卷尤其要三思。