NOTE · Engineering Systems
Docker 镜像、容器与 Compose 操作备忘
整理 Docker 镜像、容器、存储、网络与 Compose 的日常操作。
Docker 基本命令
查看 Docker 版本:
docker --version查看正在运行的容器:
sudo docker ps查看所有容器(包括停止的):
sudo docker ps -a重启容器(包括停止的):
sudo docker restart 容器ID或名称查看下载的镜像:
sudo docker images查看卷:
sudo docker volume ls停止容器:
sudo docker stop 容器ID或名称删除容器:
sudo docker rm 容器ID或名称
说明
docker rm删除的是容器,不会删除命名卷。docker volume rm接受的是卷名,不是容器 ID 或容器名。只有确认卷内数据不再需要时才应单独删除;docker rm -v <容器>只会一并删除该容器关联的匿名卷,命名卷仍会保留。
删除镜像:
sudo docker rmi 镜像ID或名称删除仅有
<none>标签的镜像(又称dangling images):sudo docker image prune删除所有不再使用的镜像(即使有名称或标签,也会被删除):
sudo docker image prune -a-a会删除所有未被任何容器引用的镜像,不只是<none>镜像。先用docker system df、docker images和docker ps -a确认范围;以后还要使用的镜像可能需要重新下载。删除卷
sudo docker volume rm 卷的名称删除所有不再使用(悬空)的匿名卷:
sudo docker volume prune删除所有不再使用的卷:
sudo docker volume prune -a数据删除警告:卷可能保存数据库、配置或上传文件。
volume prune默认只清理未被容器引用的匿名卷;加-a后也会清理未被引用的命名卷。先执行docker volume ls和docker volume inspect <卷名>,并确认备份可恢复。彻底删除:
sudo docker system prune -a --volumes这条命令将会移除
- 所有停止的容器
- 没有被任何容器使用的网络
- 没有被任何容器使用的匿名卷(
--volumes) - 没有被任何容器关联的镜像(
-a) - 未使用的构建缓存
高风险命令:
docker system prune -a --volumes会扩大镜像删除范围,并额外删除未使用的匿名卷,不适合作为日常“顺手清理”。它不会替代docker volume prune -a去删除命名卷。先用docker system df -v盘点,并分别检查容器、镜像和卷;重要数据先做可恢复性验证。
创建和运行 Docker 容器
运行第一个容器
拉取镜像:(可选)
可以从 Docker Hub 拉取官方的 Nginx 镜像:
sudo docker pull nginx运行容器:
sudo docker run -d -p 80:80 --name mynginx nginx-d:以守护进程(后台)模式运行容器。-p 80:80:将主机的 80 端口映射到容器的 80 端口。--name mynginx:为容器指定名称为mynginx。nginx:使用的镜像名称。
访问服务:
在浏览器中访问
http://localhost,应该能看到 Nginx 的默认欢迎页面。停止和删除容器:
sudo docker stop mynginx sudo docker rm mynginx
运行带交互模式的容器
运行一个 Ubuntu 容器,并进入交互式终端:
docker run -it ubuntu /bin/bash
-it:组合了-i(交互式)和-t(分配一个伪终端)。ubuntu:镜像名称。/bin/bash:要运行的命令,这里是 Bash 终端。
在容器内,可以执行各种命令。输入 exit 或按 Ctrl+D 可以退出容器。
Docker 运行 Home Assistant 容器示例
现有以下示例代码
sudo docker run -d \
--name homeassistant \
--restart=unless-stopped \
-e TZ=Asia/Shanghai \
-v /PATH_TO_YOUR_CONFIG:/config \
-v /etc/localtime:/etc/localtime:ro \
--network=host \
ghcr.io/home-assistant/home-assistant:stable
docker run -d
这是运行容器的命令,-d参数表示容器将以 后台模式 运行--name homeassistant
为容器指定名称,方便以后引用。在这里,容器的名称是homeassistant,可通过这个名称来管理容器(如停止、删除容器)--restart=unless-stopped
这个选项定义了容器的重启策略。在这里,unless-stopped表示当容器退出时,Docker 会自动重启容器,除非用户手动停止容器。这有助于确保容器在意外崩溃后能自动恢复-e TZ=Asia/Shanghai
这个选项为容器内的环境设置一个名为TZ的环境变量,其值为Asia/Shanghai,即设置容器的时区为 上海时区,这样容器内的时间和宿主机保持一致-v /PATH_TO_YOUR_CONFIG:/config
这是一个 绑定挂载 (bind mount) 命令。/PATH_TO_YOUR_CONFIG:替换为宿主机上用于保存 Home Assistant 配置和数据的绝对路径。/config:这是容器内部应用程序的配置目录,Home Assistant 会在这里存储所有的配置和数据库文件。
通过这个挂载,宿主机上的/docker/appdata/homeassistant目录将与容器内的/config目录同步。即使容器被删除或重启,所有配置和数据仍然会保留在宿主机上
--network=host
使用宿主机的网络模式。容器将直接使用宿主机的 IP 地址和端口,这样容器内的服务就能直接通过宿主机的网络进行访问。通常,使用host网络模式可以提高网络性能,但会减少容器的隔离性ghcr.io/home-assistant/home-assistant:stable
Home Assistant 官方文档使用的稳定版容器镜像。需要访问 USB 等设备时,应按设备精确添加--device等参数;不要无条件授予--privileged。
使用 Dockerfile 构建镜像
Dockerfile 是用于构建 Docker 镜像的脚本,包含了构建镜像的所有指令。
创建一个简单的应用
创建工作目录:
mkdir myapp cd myapp创建应用文件:
创建一个简单的 Python 应用,文件名为
app.py:print("Hello, Docker!")编写 Dockerfile:
在
myapp目录下创建一个名为Dockerfile的文件,内容如下:# 使用官方 Python 3 镜像作为基础镜像 FROM python:3 # 将当前目录的内容复制到容器的 /app 目录 COPY . /app # 设置工作目录为 /app WORKDIR /app # 指定容器启动时运行的命令 CMD ["python", "app.py"]
构建镜像
在 myapp 目录下运行:
docker build -t mypythonapp .
-t mypythonapp:为镜像指定名称为mypythonapp。.:Dockerfile 所在的目录。
运行镜像
docker run mypythonapp
应该会在终端看到输出:
Hello, Docker!
Docker 更新镜像
手工重建容器前,必须保留原容器的挂载、端口、环境变量、网络、设备和重启策略。仅重新执行一个简化的 docker run 会让这些配置丢失。优先把配置写入 Compose;如果暂时只能手工管理,至少先检查并留存当前配置:
sudo docker inspect 容器ID或名称
sudo docker pull 镜像名:<tag>
# 确认数据已备份、且能够用完整的原始参数重建后再执行:
sudo docker stop 容器ID或名称
sudo docker rm 容器ID或名称
# 必须复用原有的 -v/--mount、-p、-e、--network、--device、--restart 等参数
sudo docker run -d --name 新容器名 [原有全部运行参数] 镜像名:<tag>
升级后先检查:
sudo docker ps --filter name=新容器名
sudo docker logs --tail 100 新容器名
确认新容器工作正常且回滚镜像不再需要后,再考虑删除旧镜像。docker inspect 可能含环境变量中的敏感值,不要把输出直接发布到公网。
Docker Compose 更新镜像
当前 Compose CLI 使用 docker compose(中间为空格)。Compose 文件顶层的 version 字段已经过时,不必填写。以下 compose.yaml 使用明确镜像标签:
services:
web:
image: nginx:PINNED_TAG
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
将 PINNED_TAG 替换为已经核对并计划使用的明确版本标签。修改并保存目标标签后,先备份持久化数据,再让 Compose 拉取并重建服务:
sudo docker compose config
sudo docker compose pull
sudo docker compose up -d
sudo docker compose ps
sudo docker compose logs --tail 100
docker compose up -d 会按 Compose 文件保留声明过的挂载、端口、环境和网络配置。不要依赖隐式的 latest:固定并主动更新标签更便于复现和回滚。docker compose config 可能展开环境变量或其他敏感配置,不要把输出直接发布。删除卷的 docker compose down -v 会清除 Compose 声明的命名卷与匿名卷,除非明确要删数据,否则不要加 -v。
Docker 容器管理
查看容器日志
sudo docker logs 容器ID或名称进入正在运行的容器
sudo docker exec -it 容器ID或名称 /bin/bash重启容器
sudo docker restart 容器ID或名称查看容器资源使用情况
sudo docker stats
Docker 的重启策略
no默认值。容器退出后不会自动重启
on-failure仅当容器以非零状态码退出(意味着发生错误)时重启;若容器手动
docker stop或容器以正常状态码退出,则不会重启always- 无论什么原因导致容器退出,都始终尝试重启。如果 Docker 或宿主机重启后,容器也会随 Docker 一起启动
- 只有在停止容器(如
docker stop)且 Docker 没有重启的情况下,容器才会保持停止状态
unless-stopped- 和
always很相似,但当容器是被手动停止之后,如果宿主机/ Docker 再重启,就不会自动把这个容器再拉起来 - 换句话说,如果容器是“运行时崩溃”导致退出,或宿主机/docker 重启会自动重启该容器;但如果手动
docker stop过它,下次 Docker daemon 重启时它就不会被自动拉起
- 和
容器、镜像与卷的关系
- 镜像是只读模板;
- 容器是在镜像基础上增加可写层和运行配置;
- 绑定挂载直接引用宿主机路径;
- 命名卷由 Docker 管理并以卷名引用;
- 删除容器不会自动等于删除绑定目录或命名卷。
先查看容器实际挂载:
sudo docker inspect --format '{{json .Mounts}}' 容器ID或名称
sudo docker volume ls
sudo docker volume inspect 卷名
docker inspect 的完整输出可能含环境变量、内部地址和凭据,公开排错时只提取需要字段。重要数据的“备份”应包含一致性策略和恢复测试:数据库运行期间直接 cp -r 数据目录未必得到可恢复快照。
端口、环境与设备映射
sudo docker run --rm \
-p 127.0.0.1:8080:80 \
-e APP_MODE=development \
--mount type=bind,src=/HOST_DATA,dst=/app/data,readonly \
IMAGE_NAME:PINNED_TAG
127.0.0.1:8080:80只在宿主机回环地址监听;省略 IP 通常会扩大监听范围;- 环境变量可能出现在 inspect、进程环境或部署配置中,不适合承载长期密钥;
readonly只限制该挂载在容器中的写入,不会让整个容器只读;/HOST_DATA、镜像和标签都是占位符。
硬件访问优先授予具体设备:
sudo docker run --device /dev/DEVICE_NODE:/dev/DEVICE_NODE IMAGE_NAME:PINNED_TAG
仍要结合设备权限、用户组和容器内用户检查。--privileged 会显著扩大权限,不作为“设备打不开”的通用修复。
Compose v1 历史命令对照
Docker Compose v1 使用独立的 docker-compose 可执行文件;当前 Compose v2 已集成到 Docker CLI:
| 历史写法 | 当前写法 |
|---|---|
docker-compose config | docker compose config |
docker-compose pull | docker compose pull |
docker-compose up -d | docker compose up -d |
docker-compose logs | docker compose logs |
维护老主机时先执行 docker compose version 和 docker-compose version 查看实际安装,不要在同一项目里混用两套命令。顶层 version: 字段属于历史 Compose 文件格式标记;现代 Compose Specification 不再需要它。
清理前盘点
sudo docker system df -v
sudo docker ps -a --size
sudo docker images --digests
sudo docker volume ls
先分别判断停止容器、缓存、未引用镜像和卷是否仍需回滚/恢复,再选择最小范围的删除命令。不要把 system prune -a --volumes 当作固定维护步骤。
其他
在多数基于 systemd 的 Linux 发行版上,可使用以下命令来重启 Docker 服务 (Docker Daemon):
sudo systemctl restart docker
Docker 官方文档:https://docs.docker.com/
Docker Engine 官方安装文档:https://docs.docker.com/engine/install/
Home Assistant Container 官方文档:https://www.home-assistant.io/installation/linux/
Docker Hub:https://hub.docker.com/