摘要: 本文系统整理了 Docker 的核心概念与常用命令,涵盖镜像管理、容器操作、数据存储、网络配置、Compose 编排以及 Dockerfile 构建等内容。通过清晰的命令示例和实用说明,帮助开发者快速上手 Docker 容器化技术,提升开发与部署效率。
关键词: Docker, 容器化, 镜像, 容器, Docker Compose, Dockerfile, 命令手册
镜像是 Docker 容器运行的基础模板。
在 Docker Hub 或其他注册中心查找镜像。
docker search nginx
下载镜像到本地仓库。推荐指定标签(如 :latest
, :alpine
)。
docker pull nginx # 拉取最新版 (latest)
docker pull nginx:latest # 显式指定最新版
docker pull nginx:alpine # 拉取 Alpine Linux 精简版
列出所有已下载的镜像。
docker images
docker image ls # 等效命令
移除不再需要的本地镜像。注意: 依赖该镜像的容器必须先删除或停止。
docker rmi nginx:latest # 通过仓库名:标签删除
docker rmi <镜像ID> # 通过唯一镜像 ID 删除 (更精确)
容器是镜像的运行实例。
启动一个新的容器实例。
docker run nginx # 前台运行 (会占用终端)
docker run -d --name mynginx nginx # 后台运行 (-d) 并命名容器 (--name)
docker run -d --name myweb -p 8080:80 nginx # 后台运行,并将容器 80 端口映射到宿主机 8080 端口 (-p)
# 常用选项:
# -d: 后台运行 (detached mode)
# --name: 为容器指定一个易记的名称
# -p <主机端口>:<容器端口>: 端口映射
# -it: 交互模式运行 (通常与 /bin/bash 结合进入容器)
# -e: 设置环境变量
# --restart=always: 容器退出时自动重启
docker ps # 查看正在运行的容器
docker ps -a # 查看所有容器 (包括已停止的)
docker ps -aq # 查看所有容器的 ID (只显示 ID, 常用于批量操作)
docker start <容器名称|容器ID> # 启动已停止的容器
docker stop <容器名称|容器ID> # 优雅停止运行中的容器 (发送 SIGTERM)
docker restart <容器名称|容器ID> # 重启容器
docker stats <容器名称|容器ID> # 实时查看容器的 CPU、内存、网络、磁盘等资源使用情况
docker logs <容器名称|容器ID> # 查看容器日志 (默认显示已产生的日志)
docker logs -f <容器名称|容器ID> # 持续跟踪 (follow) 容器日志输出 (类似 tail -f)
在运行的容器内启动一个交互式 Shell(通常是 /bin/bash
或 /bin/sh
)。
docker exec -it mynginx /bin/bash
# -i: 保持 STDIN 打开
# -t: 分配一个伪终端 (TTY)
移除不再需要的容器。注意: 正在运行的容器需要先停止或使用 -f
强制删除。
docker rm <容器名称|容器ID> # 删除已停止的容器
docker rm -f <容器名称|容器ID> # 强制删除运行中的容器
docker rm $(docker ps -aq) # 批量删除所有已停止的容器 (危险操作!)
基于一个运行中的容器的当前状态创建新的镜像层。
docker commit -m "update index.html" mynginx mynginx:v1.0
# -m: 提交信息
# mynginx: 源容器名称
# mynginx:v1.0: 新镜像名称:标签
将镜像导出为 .tar
文件,方便离线传输或备份。
docker save -o mynginx.tar mynginx:v1.0
# -o: 指定输出文件名
从 .tar
文件恢复镜像到本地仓库。
docker load -i mynginx.tar
# -i: 指定输入文件
登录:
docker login # 默认登录 Docker Hub, 提示输入用户名密码
标记镜像: 为本地镜像添加符合目标仓库规范的名称(通常是
)。
docker tag mynginx:v1.0 <你的DockerHub用户名>/mynginx:v1.0
推送镜像:
docker push <你的DockerHub用户名>/mynginx:v1.0
Docker 使用存储卷 (Volumes) 或绑定挂载 (Bind Mounts) 来持久化容器数据,避免容器删除后数据丢失。
将宿主机上的一个具体目录直接挂载到容器内指定路径。文件存在于宿主机文件系统上。
docker run -d -p 80:80 -v /宿主机/绝对路径/nginxhtml:/usr/share/nginx/html --name myapp nginx
# -v /宿主机路径:/容器路径
使用 Docker 管理的命名卷挂载到容器内路径。卷存储在 Docker 管理的区域 (/var/lib/docker/volumes/
),与容器生命周期解耦。
docker run -d -p 80:80 -v mynginxconf:/etc/nginx -v mynginxhtml:/usr/share/nginx/html --name myapp nginx
# -v 卷名:/容器路径
docker volume ls # 列出所有 Docker 管理的卷
docker volume create myvolume # 创建一个新的命名卷
docker volume inspect myvolume # 查看指定卷的详细信息 (包括其物理存储位置 Mountpoint)
docker volume rm myvolume # 删除一个不再使用的卷
# 注意:删除容器时,使用 -v 选项可以同时删除关联的匿名卷 (未命名的卷)。命名卷需要显式删除。
Docker 容器默认通过 docker0
虚拟网桥连接并相互隔离。
docker container inspect <容器名称|容器ID> # 查看容器详细信息,包括其 IP 地址、网关、网络配置等
docker0
) 的局限性自定义网络解决了 docker0
的局限性:
docker network create mynet # 创建一个名为 mynet 的自定义桥接网络
docker network ls # 列出所有 Docker 网络
docker run -d -p 8081:80 --name app1 --network mynet nginx
docker run -d -p 8082:80 --name app2 --network mynet nginx
app1
可以直接通过 ping app2
或 http://app2
访问 app2
容器,反之亦然。docker inspect app1
查看其网络配置,确认它连接到了 mynet
并获取了 IP。注意: 只能删除没有容器连接的网络。
docker network rm mynet
Docker Compose 使用 YAML 文件 (docker-compose.yml
或 compose.yml
) 定义和运行多容器 Docker 应用。
在包含 compose.yaml
文件的目录下运行:
docker compose -f compose.yaml up -d
# -f: 指定 Compose 文件 (默认为 compose.yml 或 docker-compose.yml 时可省略)
# -d: 后台运行 (detached)
# up: 创建并启动所有定义的服务、网络、卷
docker compose -f compose.yaml down # 停止并移除容器、网络 (默认保留卷和镜像)
docker compose -f compose.yaml down --rmi all -v # 停止并移除容器、网络,同时删除所有相关镜像(--rmi all)和卷(-v)
# --rmi all: 删除 Compose 文件中定义的服务所使用的所有镜像
# -v: 删除 Compose 文件中定义的匿名卷和 compose 创建时指定的命名卷 (谨慎使用!)
Dockerfile 是一个文本文件,包含构建 Docker 镜像所需的一系列指令。
指令 | 说明 | 示例 |
---|---|---|
FROM | 指定基础镜像。 所有构建都以此为基础。 | FROM openjdk:11 |
LABEL | 添加元数据 (键值对)。 如作者、描述、版本等。 | LABEL maintainer="[email protected]" |
COPY | 复制文件/目录。 从构建上下文复制到镜像内。 | COPY ./app.jar /app/app.jar |
ADD | 类似 COPY ,但功能更多 (支持 URL、自动解压 tar)。通常优先用 COPY。 |
ADD https://example.com/file.tar.gz / |
WORKDIR | 设置工作目录。 后续指令 (RUN , CMD , ENTRYPOINT , COPY , ADD ) 都在此目录下执行。 |
WORKDIR /app |
RUN | 执行命令。 在构建过程中运行命令并创建新的镜像层。常用于安装软件包。 | RUN apt-get update && apt-get install -y curl |
EXPOSE | 声明运行时容器监听的端口。 只是一个文档说明,实际映射需用 -p 。 |
EXPOSE 8080 |
ENV | 设置环境变量。 在构建阶段和运行阶段都可用。 | ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk |
CMD | 指定容器启动时的默认命令。 可以被 docker run 的命令覆盖。 |
CMD ["java", "-jar", "/app.jar"] |
ENTRYPOINT | 指定容器启动时的主命令。 CMD 的内容通常作为其参数。更不易被覆盖。 |
ENTRYPOINT ["java", "-jar"] CMD ["/app.jar"] |
# 使用 OpenJDK 11 官方镜像作为基础
FROM openjdk:11
# 添加维护者信息 (元数据)
LABEL author="liuqi" version="1.0"
# 将构建上下文中的 app.jar 复制到镜像根目录下
COPY app.jar /app.jar
# 声明应用运行时监听的端口
EXPOSE 8081
# 设置容器启动时执行的命令 (主进程)
ENTRYPOINT ["java", "-jar", "/app.jar"]
在包含 Dockerfile
和 app.jar
的目录下运行:
docker build -t myjavaapp:v1.0 .
# -t: 指定构建出的镜像名称和标签 (myjavaapp:v1.0)
# . : 指定构建上下文路径 (当前目录),Dockerfile 和 COPY 的文件都相对于此路径
Docker 镜像采用分层存储 (Layer Storage) 机制,这是其高效性和轻量化的核心:
FROM
, RUN
, COPY
, ADD
)所引入的文件系统变化。ubuntu:latest
),那么它们共享基础镜像的所有只读层,节省磁盘空间。图解:
+---------------------------------------------------+
| Container (myapp) |
| +-----------------------------------------------+ |
| | Read-Write Layer (R/W) | | (容器层 - 存储运行时修改)
| +-----------------------------------------------+ |
| +-----------------------------------------------+ |
| | Read-Only Layer (n) | | (镜像层 - 由 `RUN apt-get install` 添加)
| +-----------------------------------------------+ |
| ... |
| +-----------------------------------------------+ |
| | Read-Only Layer (2) | | (镜像层 - 由 `COPY app.jar` 添加)
| +-----------------------------------------------+ |
| +-----------------------------------------------+ |
| | Read-Only Layer (1) | | (镜像层 - 由 `FROM openjdk:11` 引入的基础层)
| +-----------------------------------------------+ |
+---------------------------------------------------+
(Union Mount Point - 呈现为单一文件系统视图)
优势: