3、docker容器命令 | 进入/操作/复制/共享容器数据

1、命令总览

命令/组合作用
docker exec容器里开新进程
docker attach接管容器主进程
docker cp容器 ↔ 宿主机拷文件
docker export/import打包/恢复整个 rootfs
docker commit把容器变镜像
docker run --volumes-from跨容器共享卷
docker volume cp(社区脚本)用卷实现“volume cp”

2、 docker exec

运行中容器里启动一条新进程(默认 /bin/sh 或其他命令)

# 1) 交互式进入容器 bash(/bin/bash 或 /bin/sh 视镜像而定)
docker exec -it mysql8 bash

# 2) 一次性执行命令并返回结果
docker exec mysql8 mysqldump -uroot -pRoot@123456 appdb > appdb.sql

# 3) 以 root 用户身份在容器里执行
docker exec -u 0 -it web sh

# 4) 指定工作目录再执行命令
docker exec -w /var/www/html web ls -al
选项全称说明
-i--interactive保持 STDIN 打开,允许交互
-t--tty分配伪终端,常与 -i 连用
-d--detach在后台执行,不挂当前终端
-u--user指定 UID 或用户名
-w--workdir指定容器内工作目录
-e--env为本次命令新增环境变量
--privileged给予扩展权限(谨慎使用)

3、docker attach

把当前终端 挂到容器 PID 1 的标准输入/输出/错误,相当于“接管”主进程。

# 1) 挂到一个交互式容器(如 sh/bash)
docker run -dit --name demo alpine sh
docker attach demo          # 终端现在就是容器里的 sh

# 2) 挂到 nginx 查看实时 access log(容器启动命令是 nginx -g 'daemon off;')
docker attach nginx

# 3) 退出但不停止容器:Ctrl-p Ctrl-q(detach 键序列)
#    如果直接 Ctrl-c 会把 PID 1 杀掉,容器即停止。

docker attach 接管容器主进程(PID 1)的 stdin/stdout/stderr
docker exec 则在容器里 额外启动一条新进程

# 准备容器:主进程是 /bin/bash,保持交互
docker run -dit --name demo ubuntu bash
# 此时容器里只有 PID 1 = bash 这一个进程
wangqiang@wangqiang:~$ docker top demo
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                99972               99952               0                   22:15               pts/0               00:00:00            bash

# 实验 A:docker attach
# 把终端挂到 PID 1 的 bash 上
# 终端 1
docker attach demo
root@7d8a:/# echo "I am PID 1"
I am PID 1
root@7d8a:/# read -p "现在我是容器里唯一的 bash,按 Ctrl-p Ctrl-q 离开"
(llm) wangqiang@wangqiang:~$ docker top demo
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                104752              104731              0                   22:19               pts/0               00:00:00            bash

# 按 Ctrl-p 紧接着 Ctrl-q
# 终端 1 回到宿主机,容器继续运行

# 实验 B:docker exec
# 在容器里再开一个新的 bash 进程。
# 终端 2
docker exec -it demo bash
root@7d8a:/# echo "I am a new bash, PID ≠ 1"
I am a new bash, PID ≠ 1

(llm) wangqiang@wangqiang:~$ docker top demo
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                104752              104731              0                   22:19               pts/0               00:00:00            bash
root                106696              104731              0                   22:20               pts/1               00:00:00            bash

root@7d8a:/# exit   # 仅结束这条新 bash,容器仍运行

Ctrl-p Ctrl-q 默认会被 VS Code 的快捷键系统截获,所以不会传递给远端容器的 docker attach 会话。 在 VS Code 终端里先按 Ctrl(command)+Shift+p → 输入/选择Terminal: Detach Session即可安全离开 attach,容器继续运行。

4、docker cp

容器 ↔ 宿主机 之间拷贝文件/目录,语法类似 Linux 的 cp,但路径前需要加容器名前缀。

# 宿主机 → 容器
docker cp <宿主机路径> <容器名>:<容器内路径>

# 容器 → 宿主机
docker cp <容器名>:<容器内路径> <宿主机路径>


# 1) 把当前目录下的 app.py 拷进 nginx 容器 /usr/share/nginx/html
docker cp ./app.py nginx:/usr/share/nginx/html/

# 2) 把容器 /var/log/nginx/error.log 拷到本地当前目录
docker cp nginx:/var/log/nginx/error.log ./error.log

# 3) 递归拷整个目录(宿主机 → 容器)
docker cp ./dist web:/var/www/html

# 4) 递归拷整个目录(容器 → 宿主机)
docker cp web:/etc/nginx ./nginx-conf-backup

5、docker export / docker import

docker export + docker import = 把运行中/已停止的容器整个文件系统打包成 tar → 再变成一个新镜像
过程 不带历史层、元数据(ENV、CMD、ENTRYPOINT 等),相当于“裸根目录快照”。

# 1. 导出:把容器文件系统打成 tar
docker export <容器名/ID> > mycontainer.tar
# 或
docker export -o mycontainer.tar <容器名/ID>

# 2. 导入:tar → 镜像
cat mycontainer.tar | docker import - myrepo/myimage:tag
# 或
docker import mycontainer.tar myrepo/myimage:tag


# 1) 跑个容器并做点改动
docker run --name demo ubuntu bash -c "apt update && apt install -y curl && echo ok > /root/test"
docker stop demo

# 2) 导出
docker export demo -o demo.tar

# 3) 导入成新镜像
docker import demo.tar myubuntu:with-curl

# 4) 验证(CMD/ENTRYPOINT 需手动指定)
docker run --rm myubuntu:with-curl cat /root/test   # 输出 ok

6、docker commit

正在运行或已停止的容器当前状态(文件系统 + 元数据)拍成新的镜像层,生成一条可复用的镜像。
export/import 不同,它保留分层历史、ENV、CMD、ENTRYPOINT 等元数据,适合「调试后固化」或「增量开发」。

docker commit [选项] <容器名/ID>  [仓库:标签]
选项说明
-a, --author作者信息
-m, --message提交说明(类似 git commit -m)
-p, --pause提交前先暂停容器(默认 true)
# 1) 启动并改动容器
docker run -dit --name demo ubuntu
docker exec -u root -it demo bash
apt update && apt install -y curl

# 2) 提交成新镜像
docker commit -a "ops@corp.com" -m "add curl" demo myubuntu:curl

# 3) 验证
docker images | grep myubuntu
docker run --rm myubuntu:curl which curl   # /usr/bin/curl

(llm) wangqiang@wangqiang:~$ docker images
REPOSITORY                                TAG           IMAGE ID       CREATED          SIZE
myubuntu                                  curl          8f544bceceb9   10 seconds ago   139MB

7、docker run --volumes-from / docker create --volumes-from

另一个容器已经声明(或挂载)的全部卷零拷贝地共享到当前新容器里,实现“跨容器共享数据”。所有挂载了同一个数据卷的容器,都可以对该卷中的文件进行读写(除非显式设置为只读)。

# 创建并启动一个“纯数据容器”,挂载本地目录 /mydata 到 /data
docker run -d --name data-only \
           -v /mydata:/data \
           alpine tail -f /dev/null   # 保持容器运行

# 场景 A:docker run --volumes-from(立即启动)
# 新容器 app1 直接使用 data-only 的所有卷
docker run -d --name app1 \
           --volumes-from data-only \
           ubuntu bash -c "echo hello from app1 >> /data/log.txt"
# /mydata/log.txt 里出现 hello from app1。
# 若 data-only 有多个卷,app1 会全部继承。


# 场景 B:docker create --volumes-from(仅创建,不启动)
# 创建但不启动,方便以后手动 start
docker create --name app2 \
              --volumes-from data-only \
              nginx:latest
# 此时 app2 已和数据-only 共享卷;执行 docker start app2 即可使用共享目录。

Alpine 的 5 大核心用途

用途场景举例
容器镜像Docker/Kubernetes 基础镜像alpine:latest 只有 7MB,远小于 Ubuntu(80MB+)
嵌入式系统路由器、IoT 设备、树莓派OpenWrt、智能家居固件
CI/CD 流水线快速拉取、构建、测试GitLab CI、GitHub Actions
最小化服务器需要极致精简的 VM 或容器静态网站、API 网关、边缘计算
安全敏感场景减少攻击面金融、医疗、军工系统

Alpine 的 4 大优势

优势说明
极小体积基础镜像仅 5~7MB,拉取/启动极快
高安全性默认启用 musl libc + busybox,减少漏洞
包管理简单apk 命令简洁高效,包仓库纯净
社区活跃Docker Hub 官方推荐的基础镜像之一

8、docker volume cp(社区脚本)

Docker CLI 原生没有 volume cp,但可用一次性容器实现“宿主机 ↔ 命名卷”文件交换,本质也是 cp 的变形。

# 宿主机 → 命名卷
# 假设卷名 myvol,宿主机当前目录 ./data
docker run --rm \
  -v myvol:/target \      # 把卷挂到容器 /target
  -v "$PWD":/src \        # 把宿主机目录挂到 /src
  alpine \
  sh -c "cp -r /src/* /target/"


# 命名卷 → 宿主机
# 把卷 myvol 拷到当前目录 ./backup
docker run --rm \
  -v myvol:/src \
  -v "$PWD":/backup \
  alpine \
  sh -c "cp -r /src/. /backup/"


# 单文件示例
# 把本地 config.yml 拷到卷 myvol 根目录
docker run --rm -v myvol:/data -v "$PWD":/host alpine \
  cp /host/config.yml /data/


# 打包/解压大文件(速度更快)
# 宿主机 → 卷
tar -czf - ./bigdir | \
  docker run --rm -i -v myvol:/data alpine \
    sh -c "tar -xz -C /data"

# 卷 → 宿主机
docker run --rm -v myvol:/data alpine \
  tar -cz -C /data . > bigdir-backup.tgz

docker volume cp和docker cp的区别

命令作用对象典型场景
docker cp容器 ↔ 宿主机 之间复制文件/目录调试容器、把日志拷出来
docker volume cp卷 ↔ 宿主机 之间复制文件/目录备份/恢复卷数据、不启动容器也能操作
# 把容器里的 /etc/nginx/nginx.conf 拷到当前目录
docker cp my_nginx:/etc/nginx/nginx.conf ./nginx.conf

# 反过来,把宿主机文件拷进正在运行的容器
docker cp ./app.py my_nginx:/usr/share/nginx/html/
  • 源或目标路径前必须带 容器名/ID

  • 容器可以正在运行或已停止

  • 只能和 容器文件系统 打交道,不能直接碰卷。

# 把卷 myvol 的全部内容拷到宿主机 ./backup
docker volume cp myvol:/ ./backup

# 恢复:把宿主机 ./backup 拷回卷
docker volume cp ./backup myvol:/
  • 源或目标路径前必须带 卷名

  • 不需要容器参与,卷即使没被挂载也能操作。

  • 要求 Docker CLI ≥ v24(旧版本没有该子命令)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI风老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值