第4章:Docker命令行入门——pull、run、ps、exec、logs
Docker 的命令行,说白了就是你和容器引擎对话的方式。刚接触时我也觉得命令又多又乱,但其实真正高频用的就那几个。我个人习惯是先记透这五个命令:pull、run、ps、exec、logs。把这五个玩熟了,药物图谱的镜像下载、容器启动、状态查看、内部调试、日志追踪就全拿下了。
4.1 docker pull:把镜像拉到本地
没有镜像,容器就是个空壳。docker pull 就是从仓库(默认 Docker Hub)把镜像下载到本地。我刚开始部署时,老记不住镜像的全名,结果总是报错。你想想看,Docker Hub 上的镜像名格式是 [仓库地址/]用户名/镜像名:标签。
# 拉取最新版本的 Ubuntu 镜像
docker pull ubuntu:latest
# 拉取特定标签的 Node.js 镜像
docker pull node:18-alpine
# 从私有仓库拉取药物图谱镜像(假设仓库地址为 registry.example.com)
docker pull registry.example.com/drug-atlas:v1.0
--platform 参数指定架构(如 linux/amd64),避免在 Apple Silicon 或 ARM 服务器上拉错架构版本。我在项目中遇到过拉完镜像发现跑不了,就是因为默认拉了 arm64 而目标机器是 x86。
pull 命令可以拆出很多层,也经常配合 tag 和 push 使用。不过这里先聚焦下载操作。
4.2 docker run:创建并启动容器
docker run 是出现频率最高的命令。它的基本套路是:docker run [选项] 镜像名 [命令]。为什么说它重要?因为你每次启动药物图谱的数据库或后端服务,都要用这个命令。
# 最简启动
docker run nginx:alpine
# 带名字、后台运行、端口映射
docker run --name drug-mysql -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mysecret mysql:8.0
常见选项我在下面列个表,方便你查阅:
| 选项 | 含义 | 典型用法 |
|---|---|---|
-d | 后台运行(detached) | -d 或 --detach |
--name | 指定容器名称 | --name my-app |
-p | 端口映射 (宿主机:容器) | -p 8080:80 |
-e | 设置环境变量 | -e TZ=Asia/Shanghai |
-v | 挂载卷 | -v /data:/var/lib/mysql |
--rm | 容器停止后自动删除 | --rm (调试时常用) |
run 每次都会创建新容器,不是重启已有的。如果容器已经存在,你会看到名字冲突的错误。我曾经踩过这个坑——以为 run 是启动,结果反复报错找不到原因。正确做法是先 docker rm 容器名 再 run,或者直接用 docker start 启动已有容器。
4.3 docker ps:查看容器状态
容器启动后,怎么知道它活得好不好?docker ps。不加参数只显示正在运行的容器,加上 -a 才能看到所有(包含已停止的)。
# 只看运行中的
docker ps
# 看所有容器
docker ps -a
# 简洁模式(只显示容器ID)
docker ps -q
# 带过滤条件:只显示名为 drug-atlas 的容器
docker ps --filter "name=drug-atlas"
输出的列包括:CONTAINER ID、IMAGE、COMMAND、CREATED、STATUS、PORTS、NAMES。STATUS 列里经常能看到 Up 3 hours 或 Exited (0) 5 minutes ago。嗯,这里要注意:Exited 状态不一定代表崩溃,也可能是正常停止。
docker ps --format 可以自定义输出格式,比如只显示名字和状态:docker ps --format "table {{.Names}}\t{{.Status}}"。我在排查多容器集群时,会用这个快速扫一眼。
4.4 docker exec:进入容器内部
很多时候你需要“钻进”容器里看看——检查配置文件、运行临时命令、调试网络问题。docker exec 就是干这个的。语法:docker exec [选项] 容器名 命令。
# 在运行中的容器内执行 ls 命令
docker exec my-container ls -la /app
# 进入容器的交互式 shell(最常用)
docker exec -it my-container /bin/bash
# 如果容器没有 bash,改用 sh
docker exec -it my-container /bin/sh
# 以 root 用户执行命令(容器默认一般不是 root)
docker exec -u root my-container whoami
参数 -it 是 --interactive + --tty 的组合,缺了它就没法拿到交互终端。我一开始忽略了这个,直接 docker exec my-container bash,结果什么反应都没有,还以为容器挂了。
4.5 docker logs:查看容器日志
容器跑起来后,日志就是你的眼睛。特别是药物图谱的服务如果启动失败,第一个念头就是去看日志。
# 查看最近 100 行日志
docker logs --tail 100 my-container
# 实时追踪日志(类似 tail -f)
docker logs -f my-container
# 加上时间戳
docker logs -t my-container
# 查看指定时间范围后的日志(支持相对时间)
docker logs --since 5m my-container
logs 命令默认打印的是标准输出和标准错误流。如果你的应用把日志写到了文件而不是 stdout,那 docker logs 是看不到的。解决办法:在应用配置里把日志输出到 stdout,或者用 docker exec 进去看文件。
docker ps 确认容器在不在,再用 docker logs --tail 50 -f 动态看日志,最后用 docker exec -it 进入补充排查。这套流程我几乎天天用。
4.6 命令关系图:从拉取到监控的完整链路
这五个命令其实构成了一个闭环:拉取镜像 → 运行容器 → 查看状态 → 进入调试 → 查看日志。下面这张图帮你梳理它们的依赖关系:
4.7 常用组合与生产守则
单条命令不难,难的是把它们串起来。下面是我总结的高频组合场景:
- 首次部署:
docker pull→docker run -d --name xxx -p ... - 重新部署:
docker stop xxx && docker rm xxx→docker pull …→docker run … - 日常监控:
docker ps→docker logs --tail 20 -f - 临时进入:
docker exec -it xxx bash→ 检查后exit
commit、cp、inspect、stats 都是锦上添花。我在给团队培训时,都是先让人背这五个,然后再扩展。
4.8 常见错误与快速修复
| 现象 | 可能原因 | 快速解决 |
|---|---|---|
Unable to find image 'xxx' locally | 本地没有镜像,且 pull 失败 | 检查网络、镜像名、标签是否正确 |
Conflict. The container name "/xxx" is already in use | 同名容器已存在 | docker rm xxx 或换名字 |
Error response from daemon: Port is already allocated | 宿主机端口被占用 | netstat -tulpn | grep 端口 查占用进程 |
the container is not running | 尝试 exec 已停止的容器 | 先 docker start xxx 再 exec |
docker logs 看不到信息 | 应用日志写入文件而非 stdout | 修改应用配置或 exec 进去查看 |
遇到这些错误别慌。我记得刚用 Docker 时,端口冲突让我花了半小时查资料,后来才发现是之前部署的容器没删干净。所以现在每次部署前,我都会跑一遍 docker ps -a 确认环境。
--restart=always 或 --restart=unless-stopped,这样 Docker 守护进程重启或容器意外退出时能自动拉起。我在一个凌晨事故中吸取了教训——节点重启后,人工没来得及启动服务,导致中断了 20 分钟。
好了,到这你已经掌握了 Docker 命令行最核心的五板斧。后面的章节会基于这些基础操作,一步一步搭建药物图谱的完整部署环境。把这几个命令练熟,后面的路就顺多了。