基础语法结构
bash
docker exec [选项] <容器名或ID> <命令> [命令参数...]
参数分解(通用版)
┌─────────┬──────┬──────────┬──────────────┬─────────────────┐
│ │ │ │ │ │
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
│ │ │ │ │
│ │ │ │ └─ 要在容器内执行的命令
│ │ │ │ 可以是:bash, sh, ls, echo等
│ │ │ │
│ │ │ └─ 目标容器的标识
│ │ │ 可以是:名称(--name指定的) 或 容器ID
│ │ │
│ │ └─ 执行选项
│ │ -i, -t, -d, -u, -w, -e等
│ │
│ └─ 子命令:在运行中的容器执行命令
│ 对比:run(创建新容器), start(启动), stop(停止)
│
└─ Docker 主命令
详细参数解释表
| 参数 | 简写 | 全称 | 作用 | 示例 |
|---|---|---|---|---|
-i |
- | --interactive |
保持标准输入打开(允许输入) | -i |
-t |
- | --tty |
分配伪终端(TTY) | -t |
-d |
- | --detach |
后台执行命令 | -d |
-u |
- | --user |
指定执行用户 | -u root, -u 1000 |
-w |
- | --workdir |
设置工作目录 | -w /app |
-e |
- | --env |
设置环境变量 | -e NAME=value |
--env-file |
- | - | 从文件读取环境变量 | --env-file .env |
通用执行模式分类
模式1:交互式会话(进入容器)
bash
# 经典用法:进入容器内部操作
docker exec -it <容器> bash
docker exec -it <容器> sh
docker exec -it <容器> /bin/bash
# 原理:启动一个新的shell进程,连接到当前终端
# 用途:调试、配置修改、手动操作
模式2:单次命令执行
bash
# 执行单条命令后立即退出
docker exec <容器> ls -la /
docker exec <容器> cat /etc/passwd
docker exec <容器> ps aux
# 原理:启动命令进程,执行后自动退出
# 用途:检查状态、获取信息、执行维护任务
模式3:后台任务执行
bash
# 在容器内启动后台任务
docker exec -d <容器> crontab -l
docker exec -d <容器> /app/start-background.sh
# 原理:在容器内启动进程,但不占用当前终端
# 用途:启动服务、执行定时任务
模式4:指定用户执行
bash
# 以特定用户身份执行
docker exec -u root <容器> whoami # root
docker exec -u www-data <容器> whoami # www-data
docker exec -u 1000 <容器> whoami # 用户ID 1000
# 原理:使用指定用户的权限执行命令
# 用途:权限管理、安全执行
完整工作流程
┌─────────────────────────────────────────────────────────┐
│ 宿主机终端 │
│ $ docker exec -it test bash │
│ ↓ │
│ Docker Client 发送请求到 Docker Daemon │
│ ↓ │
│ Docker Daemon 找到运行的 "test" 容器 │
│ ↓ │
│ 在容器内创建新进程:/bin/bash │
│ ↓ │
│ 分配伪终端(-t),连接标准输入(-i) │
│ ↓ │
│ 将终端控制权交给容器的 bash 进程 │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ 容器内部环境 │
│ root@容器ID:/# (容器内的bash提示符) │
│ │
│ ↓ 用户输入命令 → bash处理 → 返回输出 → 显示在终端 │
│ │
│ 所有操作都在容器的隔离环境中进行 │
└─────────────────────────────────────────────────────────┘
与相关命令的对比
docker exec vs docker run
bash
# docker exec: 在现有容器内执行
docker exec existing_container ls
# → 容器必须已经在运行
# → 不创建新容器
# → 在容器现有环境中执行
# docker run: 创建新容器并执行
docker run new_image ls
# → 从镜像创建新容器
# → 容器执行后默认停止(除非 -d)
# → 使用镜像的初始环境
docker exec vs docker attach
bash
# docker exec: 启动新进程
docker exec -it container bash
# → 启动新的 bash 进程
# → 可以同时多个 exec 会话
# → 退出时只结束当前进程
# docker attach: 连接到主进程
docker attach container
# → 连接到容器启动时的第一个进程(PID 1)
# → 只能有一个 attach 会话
# → Ctrl+C 会停止容器!
docker exec vs docker-compose exec
bash
# docker exec: 直接操作容器
docker exec web_app bash
# docker-compose exec: 通过服务名操作
docker-compose exec web bash
# → 在 docker-compose.yml 中定义的服务名
# → 自动找到对应的容器
实际应用场景矩阵
| 场景 | 命令示例 | 说明 |
|---|---|---|
| 调试容器 | docker exec -it app bash |
进入容器内部检查 |
| 查看日志 | docker exec app tail -f /app/logs/app.log |
实时查看应用日志 |
| 执行维护 | docker exec db mysql -u root -p -e "SHOW DATABASES;" |
数据库操作 |
| 备份数据 | docker exec app tar -czf /backup/app.tar.gz /app/data |
在容器内打包数据 |
| 安装软件 | docker exec -it app apt update && apt install vim |
临时安装工具 |
| 检查配置 | docker exec nginx nginx -T |
测试Nginx配置 |
| 重启服务 | docker exec app systemctl restart myservice |
重启容器内服务 |
| 性能监控 | docker exec app top |
查看容器内进程资源使用 |
高级用法示例
1. 链式命令执行
bash
# 多个命令组合
docker exec app sh -c "cd /app && npm install"
# 使用环境变量
docker exec -e NODE_ENV=production app node server.js
# 复杂管道
docker exec app ps aux | grep nginx | head -5
2. 工作目录设置
bash
# 在指定目录执行
docker exec -w /app/src test npm start
# 相当于在容器内执行:cd /app/src && npm start
3. 多环境变量
bash
# 设置多个环境变量
docker exec \
-e DB_HOST=localhost \
-e DB_PORT=3306 \
-e DEBUG=true \
app python manage.py migrate
4. 执行脚本文件
bash
# 将主机脚本传入容器执行
cat > myscript.sh << 'EOF'
#!/bin/bash
echo "Running in container"
date
EOF
docker exec -i app bash < myscript.sh
安全最佳实践
1. 最小权限原则
bash
# 避免总是用 root
docker exec -u app_user app bash # 使用应用用户
# 只读模式执行(某些Docker版本支持)
docker exec --read-only app cat /etc/config
2. 生产环境限制
bash
# 限制资源使用
docker exec \
--cpu-quota=50000 \
--memory=256m \
app stress --cpu 1
# 避免在容器内持久化修改
# 重要变更应通过镜像重建
3. 审计与日志
bash
# 记录执行的操作
docker exec app sh -c "echo '$(date): 执行了备份' >> /var/log/ops.log"
# 使用 --detach-keys 防止误操作
docker exec --detach-keys="ctrl-x" -it app bash
# 按 Ctrl+X 退出而不是 Ctrl+P+Q
故障排除指南
常见错误及解决
错误1:容器未运行
bash
Error: No such container: test
# 解决:先启动容器
docker start test
错误2:命令不存在
bash
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH
# 解决:使用 sh 或完整路径
docker exec -it test sh
docker exec -it test /bin/sh
错误3:权限不足
bash
rpc error: code = 13 desc = permission denied
# 解决:使用合适的用户
docker exec -u root test bash
错误4:终端问题
bash
the input device is not a TTY
# 解决:去掉 -t 或检查执行环境
docker exec -i test bash
性能影响说明
docker exec 对容器性能的影响:
1. 创建新进程:增加容器内进程数
2. 资源占用:命令执行期间占用CPU/内存
3. 网络延迟:与Daemon通信的微小开销
4. 文件系统:如果命令涉及大量IO操作
建议:
• 避免在循环中频繁执行
• 复杂操作尽量在镜像构建时完成
• 监控容器资源使用
总结:docker exec 的本质
核心理解 :docker exec 是 在容器的隔离环境中创建一个新的进程,而不是"进入"容器。
bash
# 类比理解
主机系统 vs Docker容器
─────────────────────────────────────
打开新终端窗口 docker exec -it bash
运行一个命令 docker exec <命令>
任务管理器查看进程 docker exec ps aux
远程连接到服务器 docker exec -it (类似SSH)
# 关键区别:
# 1. 所有操作都在容器的隔离视图内
# 2. 文件系统、进程、网络都是容器隔离的
# 3. 退出时,除非持久化存储,否则更改不保留
掌握了 docker exec,你就掌握了与运行中容器交互的最重要工具!