容器、数据与网络
容器是镜像的运行实例。掌握容器的创建、管理、进入、日志查看等命令是使用 Docker 的日常核心;再结合数据卷(持久化)与网络(通信),才能搭建出可用于生产的容器化服务。镜像基础见 镜像与 Dockerfile。
一、容器基础操作
1. 创建并运行容器
最常用的命令是 docker run,它先拉取镜像(如果本地没有),然后创建并启动容器。
# 运行一个 nginx 容器,后台运行,命名为 my-nginx,将宿主机的 8080 端口映射到容器的 80 端口
docker run -d --name my-nginx -p 8080:80 nginx
常用参数:
| 参数 | 说明 |
|---|---|
-d | 后台运行(detach),容器在后台运行,不占用当前终端 |
--name | 为容器指定一个名字,方便后续管理 |
-p | 端口映射,格式 宿主机端口:容器端口,可多次使用 |
-it | 交互式运行(例如进入容器执行 shell 时需要 -it) |
--rm | 容器退出后自动删除(常用于临时任务) |
-v | 挂载数据卷(宿主机目录:容器目录),见下文数据管理 |
-e | 设置环境变量,如 -e MY_VAR=value |
--restart | 重启策略,如 --restart unless-stopped(生产环境常用)、always、on-failure:3 |
--network | 指定加入的网络,见下文网络部分 |
--memory / --cpus | 限制内存、CPU 资源,防止单容器耗尽宿主机资源 |
2. 进入运行中的容器(交互式 shell)
# 进入正在运行的容器,执行 /bin/bash(若容器内没有 bash 可用 /bin/sh)
docker exec -it my-nginx /bin/bash
# 对于 alpine 系统(如 nginx:alpine),使用 /bin/sh
docker exec -it my-nginx /bin/sh
-it分配伪终端并保持 STDIN 打开,这样才能交互。- 退出容器:输入
exit或按Ctrl+D(不会影响容器本身的运行,因为exec只是附加了一个新进程)。
3. 查看容器
# 查看正在运行的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 查看最后创建的 5 个容器
docker ps -n 5
# 只显示容器 ID
docker ps -q
4. 停止、启动、重启、删除容器
# 停止容器(发送 SIGTERM,超时后 SIGKILL)
docker stop my-nginx
# 启动已停止的容器
docker start my-nginx
# 重启容器
docker restart my-nginx
# 删除已停止的容器
docker rm my-nginx
# 强制删除正在运行的容器(会先停止再删除)
docker rm -f my-nginx
# 删除所有已停止的容器
docker container prune
提示:
docker rm时如果容器正在运行,需要先stop或使用-f。
5. 查看容器日志
# 输出全部日志
docker logs my-nginx
# 实时跟踪日志(类似 tail -f)
docker logs -f my-nginx
# 只看最后 100 行
docker logs --tail 100 my-nginx
# 并加上时间戳
docker logs -t my-nginx
6. 查看容器内进程与资源
docker top my-nginx # 类似 ps aux,显示容器内运行的进程
docker stats my-nginx # 实时查看 CPU、内存、网络、I/O 使用情况
docker inspect my-nginx # 查看详细配置信息(IP、挂载、网络、环境变量等)
7. 在宿主机和容器之间复制文件
# 将宿主机文件复制到容器的指定路径
docker cp ./index.html my-nginx:/usr/share/nginx/html/
# 从容器的路径复制到宿主机
docker cp my-nginx:/etc/nginx/nginx.conf ./nginx.conf
- 路径可以是绝对路径或相对于当前目录。
- 对运行中或已停止的容器都有效。
8. 其他常用容器操作
| 命令 | 说明 |
|---|---|
docker logs -f my-nginx | grep "error" | 过滤日志中的错误信息 |
docker rename old-name new-name | 重命名容器 |
docker wait my-nginx | 阻塞等待容器停止,返回退出码 |
docker update --restart always my-nginx | 运行时修改重启策略等配置 |
docker container inspect --format '{{.State.Health.Status}}' my-nginx | 查看 HEALTHCHECK 健康状态 |
容器操作总结表
| 操作 | 命令 |
|---|---|
| 创建并后台运行 | docker run -d --name <name> <image> |
| 端口映射 | -p 8080:80 |
| 进入容器 | docker exec -it <container> /bin/bash |
| 查看运行容器 | docker ps |
| 停止/启动/重启 | docker stop/start/restart <container> |
| 删除容器 | docker rm <container> |
| 查看日志 | docker logs -f <container> |
| 文件复制 | docker cp <src> <dest> |
掌握这些基础命令,即可在开发或测试环境中灵活管理 Docker 容器。对于生产环境,还需结合下面的数据卷、网络等高级特性。
二、数据管理(卷与挂载)
默认情况下,容器内的数据是临时的:当容器被删除,其中产生的数据也会丢失。为了持久化数据或在多个容器之间共享数据,Docker 提供了三种挂载方式:
- 绑定挂载(Bind Mount):将宿主机上的任意目录或文件挂载到容器内。
- 卷(Volume):由 Docker 管理的数据存储区域,独立于容器生命周期。
- 临时文件(tmpfs):存储在宿主机内存中,不会写入磁盘,容器停止后即丢失。
1. 绑定挂载(Bind Mount)
将宿主机上的特定目录或文件映射到容器内。适合开发环境,因为可以直接在宿主机修改代码,容器内立即生效。
基本语法:
docker run -v /宿主机/绝对路径:/容器内路径:选项 镜像名
或使用新版 --mount 语法(更明确)。
示例:
# 将宿主机的当前目录下的 html 文件夹挂载到容器的 /usr/share/nginx/html
docker run -d -p 8080:80 -v $(pwd)/html:/usr/share/nginx/html nginx
# 只读挂载,容器内无法修改(追加 :ro)
docker run -d -v $(pwd)/html:/usr/share/nginx/html:ro nginx
特点:
- 依赖宿主机的目录结构,可移植性较差。
- 容器可以直接读写宿主机文件(权限可能受限,Linux 下注意宿主机与容器内用户 UID 是否一致)。
- 可用于配置注入、代码热加载等。
2. 卷(Volume)
完全由 Docker 管理,存放在 Docker 存储目录下(Linux 为 /var/lib/docker/volumes/)。适合生产环境,数据独立于容器,且便于备份和迁移。
创建和使用卷:
# 创建卷
docker volume create mydata
# 使用卷运行容器(-v 卷名:容器内路径)
docker run -d -v mydata:/app/data alpine
# 也可以不预先创建,在 run 时隐式创建
docker run -d -v mydata2:/app/data alpine
管理卷:
docker volume ls # 列出所有卷
docker volume inspect mydata # 查看卷详细信息(包括挂载点)
docker volume rm mydata # 删除指定卷
docker volume prune # 删除所有未被任何容器使用的卷
备份与恢复示例(借助临时容器打包卷内容):
# 备份:将 mydata 卷内容打包为宿主机当前目录下的 backup.tar.gz
docker run --rm -v mydata:/data -v $(pwd):/backup alpine \
tar czf /backup/backup.tar.gz -C /data .
# 恢复:将 backup.tar.gz 解压回一个新卷
docker run --rm -v mydata_restored:/data -v $(pwd):/backup alpine \
tar xzf /backup/backup.tar.gz -C /data
特点:
- 支持卷驱动(如本地、NFS、云存储)。
- 可以在多个容器之间共享。
- 备份和恢复简单(直接复制卷的目录,或如上用临时容器打包)。
3. 临时文件(tmpfs)
将数据存储在宿主机的内存中,不会写入磁盘。容器停止或删除后,数据即丢失。适合存放临时、敏感、不持久化的数据(如缓存、密钥)。
语法:
docker run -d --tmpfs /容器内路径 镜像名
示例:
docker run -d --name temp-test --tmpfs /app/temp alpine sleep 300
特点:
- 速度快(内存读写)。
- 容器重启后数据清空。
- 不占用磁盘空间。
4. 三种方式对比
| 特性 | 绑定挂载(Bind Mount) | 卷(Volume) | tmpfs |
|---|---|---|---|
| 数据存储位置 | 宿主机任意目录 | Docker 管理的路径 | 宿主机内存 |
| 持久性 | 是(宿主机文件不变则持久) | 是 | 否(容器停止即失效) |
| 管理方式 | 用户手动管理 | Docker 命令管理 | 仅运行时挂载 |
| 适用环境 | 开发环境 | 生产环境 | 临时缓存/敏感数据 |
| 可移植性 | 低(依赖具体路径) | 高(卷可命名、备份) | 不适用跨容器持久化 |
| 性能 | 接近原生文件系统 | 接近原生文件系统 | 内存速度,但受限内存大小 |
5. 使用 --mount 语法(推荐)
--mount 比 -v 更明确、可读性更高,语法错误时会直接报错(而 -v 在路径不存在时可能被静默当作卷名创建)。
绑定挂载示例:
docker run -d --mount type=bind,source="$(pwd)/html",target=/usr/share/nginx/html nginx
卷示例:
docker run -d --mount source=mydata,target=/app/data alpine
tmpfs 示例:
docker run -d --mount type=tmpfs,target=/app/temp alpine
数据管理小结
- 开发调试:使用绑定挂载,实时同步代码。
- 生产持久化:使用卷,数据独立、易备份。
- 临时数据:使用 tmpfs,避免磁盘写入,提高性能。
三、网络基础
Docker 提供了多种网络驱动,使容器之间、容器与宿主机之间能够通信。默认安装后 Docker 会自动创建三种网络:bridge(默认)、host、none。
1. 查看网络
docker network ls
输出示例:
NETWORK ID NAME DRIVER SCOPE
abc123def456 bridge bridge local
789ghi012jkl host host local
345mno678pqr none null local
- bridge:默认网络,容器启动时不指定网络则加入此网络。同一 bridge 网络内的容器可以通过 IP 互相访问,但不能通过容器名直接访问(自定义桥接网络才支持容器名解析)。
- host:容器直接使用宿主机的网络栈,没有网络隔离,性能好但端口易冲突(Windows/macOS 上的 Docker Desktop 因运行在虚拟机内,
host网络行为与 Linux 有差异)。 - none:容器没有网络接口(仅 loopback),完全隔离,适合无需联网的批处理任务。
2. 创建自定义桥接网络(推荐)
docker network create mynet
- 自定义网络支持内置 DNS 解析:同一网络中的容器可以通过容器名互相 ping 通,无需使用
--link。 - 可以指定子网、网关等:
docker network create --subnet=172.20.0.0/24 mynet。
3. 在自定义网络中运行容器(通过容器名通信)
# 启动两个容器,都连接到 mynet
docker run -d --name app1 --network mynet nginx
docker run -d --name app2 --network mynet nginx
# 进入 app1 容器测试能否使用 app2 名称 ping 通
docker exec -it app1 bash
apt update && apt install iputils-ping -y # 如果镜像有 ping 命令可忽略
ping app2 # 成功解析并通信
- 不需要使用
--link或手动配置/etc/hosts。 - 也可以使用
docker run --network mynet --name app3 ...直接加入。
4. 将已有容器连接到网络
# 将已运行的 app1 容器连接到 mynet(可以同时连接多个网络)
docker network connect mynet app1
# 断开连接
docker network disconnect mynet app1
- 容器可以同时属于多个网络,实现网络隔离和桥接(例如一个容器同时对外提供服务、又能访问内部数据库网络)。
5. 端口映射(公开服务到宿主机)
端口映射使宿主机外的客户端能够访问容器内的服务。
# 将宿主机 8080 端口映射到容器的 80 端口(TCP)
docker run -d -p 8080:80 nginx
# 指定协议(默认 TCP,可显式声明)
docker run -d -p 8080:80/tcp nginx
# UDP 映射
docker run -d -p 8080:80/udp nginx
# 同时映射 TCP 和 UDP
docker run -d -p 8080:80/tcp -p 8080:80/udp nginx
# 随机映射容器暴露的所有端口(主机端口从 32768 开始)
docker run -d -P nginx # 注意是大写 -P
-p可以多次使用,映射多个端口。- 查看映射情况:
docker port <容器名>。
6. 常用网络管理命令
| 命令 | 说明 |
|---|---|
docker network ls | 列出所有网络 |
docker network inspect <网络名> | 查看网络详情(包括连接的容器) |
docker network create <名称> | 创建自定义桥接网络 |
docker network rm <网络名> | 删除网络(需先断开所有容器) |
docker network prune | 删除所有未被使用的网络 |
docker run --network <网络名> | 启动时指定网络 |
docker network connect <网络名> <容器名> | 将容器连接到网络 |
docker network disconnect <网络名> <容器名> | 断开容器与网络的连接 |
7. 最佳实践建议
- 生产环境:为不同应用栈创建独立的自定义桥接网络,避免默认
bridge网络的限制(无 DNS 解析)。 - 微服务架构:使用自定义网络,通过容器名作为服务发现;跨主机场景可考虑 overlay 网络(需 Swarm 模式)或服务网格方案。
- 端口映射:仅在需要对外暴露的服务上使用
-p;内部容器间通信无需映射端口,减少攻击面。 - 宿主机网络:除非对性能有极致要求(且能解决端口冲突),一般不推荐使用
host网络。
掌握 Docker 容器管理、数据持久化与网络基础,可以灵活构建容器间的通信拓扑,并为生产部署打下基础;多容器协同的编排方式见 Docker Compose。
参考文献
| 资料 | 说明 |
|---|---|
| Docker 文档 | 官方 |
| Volumes 官方指南 | 数据卷 |
| Networking 官方指南 | 网络 |
| 运维导读 | 学习路径 |
相关文章
Docker Compose 编排
Docker Compose 是定义和运行多容器 Docker 应用的工具,通过一个 compose.yml 文件即可管理 Web、数据库、缓存等多个服务。本文覆盖安装、完整字段说明、多服务示例、常用指令与常见排错。
镜像与 Dockerfile
镜像(Image)是 Docker 容器的只读模板,Dockerfile 则是构建镜像的蓝图。本文完整覆盖镜像的搜索、拉取、查看、删除、打标签、推送,以及 Dockerfile 常用指令、多阶段构建与体积优化技巧。
Docker 基础概念、安装与命令速查
Docker 是一个开源的容器化平台,能将应用程序及其所有依赖打包成轻量级、可移植的容器。本文介绍核心概念、底层原理、跨平台安装配置,并附完整的命令速查表,是学习 Docker 的第一篇。
运维与协作导读
本目录覆盖日常开发运维中的 Git 版本控制、Docker 容器化与 Nginx 服务网关,与 工程化 · Git、部署相关 等章节互补,提供完整的十阶段学习路径。
后端入门概览
本目录覆盖 JavaScript/TypeScript 服务端运行时与框架、数据存储,以及 Rust 系统编程入门,提供从零到部署的完整学习路径。前置建议:JavaScript 基础、工程化 · 环境变量。
Bun 基础与核心命令
Bun 是用 Zig 编写的 JavaScript 运行时,内置包管理(bun install)、打包(bun build)、测试(bun test)等,并持续兼容 Node.js API。本文介绍核心特点、安装方式,以及日常最常用的命令与包管理功能。见 运行时对比。
Series
docker
4 / 4