Docker 从零入门:镜像、容器、数据卷与常用命令实战

举报
yd_228838069 发表于 2026/11/11 10:45:42 2026/11/11
【摘要】 一、什么是 Docker?Docker 是一个开源的容器化平台,可以将应用程序及其运行所需的依赖、配置和环境打包成镜像,然后通过镜像创建容器,在不同服务器或开发环境中运行。传统部署应用时,通常需要手动安装运行环境、配置依赖、调整系统参数。不同服务器之间可能存在环境差异,导致应用出现兼容性问题。Docker 通过容器技术解决了这类问题。例如,一个 Python Web 项目可能需要:Pytho...

一、什么是 Docker?

Docker 是一个开源的容器化平台,可以将应用程序及其运行所需的依赖、配置和环境打包成镜像,然后通过镜像创建容器,在不同服务器或开发环境中运行。

传统部署应用时,通常需要手动安装运行环境、配置依赖、调整系统参数。不同服务器之间可能存在环境差异,导致应用出现兼容性问题。

Docker 通过容器技术解决了这类问题。

例如,一个 Python Web 项目可能需要:

  • Python 3.12

  • FastAPI

  • Uvicorn

  • MySQL

  • Redis

  • 相关系统依赖

使用 Docker,可以将应用运行环境打包到镜像中,部署时只需要运行对应容器即可。

1. Docker 的核心概念

Docker 入门需要理解四个核心概念:

概念 说明
镜像(Image) 容器的模板,包含应用及运行环境
容器(Container) 镜像运行后的实例
数据卷(Volume) 用于持久化保存容器数据
仓库(Registry) 存储和分发 Docker 镜像的服务

它们之间的关系:

Docker 镜像
    |
    | docker run
    v
Docker 容器
    |
    | 挂载数据卷
    v
持久化数据

一个镜像可以创建多个容器,一个容器也可以挂载多个数据卷。

2. Docker 与虚拟机有什么区别?

Docker 容器与传统虚拟机都可以隔离运行环境,但底层实现不同。

对比项目 Docker 容器 虚拟机
系统内核 共享宿主机内核 通常拥有独立内核
启动速度 通常较快 通常较慢
资源占用 相对较少 相对较多
隔离方式 Namespace、Cgroups 等 Hypervisor 虚拟化
适用场景 应用部署、微服务 完整操作系统环境

需要注意:Docker 容器不是完整的虚拟机,容器内部看到的进程和文件系统虽然具有隔离性,但它仍然依赖宿主机内核。

二、安装 Docker

本教程以 Debian 12/13 为例,使用 Docker 官方软件仓库安装 Docker Engine。

1. 更新系统软件包

sudo apt update
sudo apt upgrade -y

2. 安装必要依赖

sudo apt install -y ca-certificates curl

3. 添加 Docker 官方 GPG 密钥

创建密钥目录:

sudo install -m 0755 -d /etc/apt/keyrings

下载 Docker 官方 GPG 密钥:

sudo curl -fsSL https://download.docker.com/linux/debian/gpg \
  -o /etc/apt/keyrings/docker.asc

设置读取权限:

sudo chmod a+r /etc/apt/keyrings/docker.asc

4. 添加 Docker 软件仓库

sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

更新软件包索引:

sudo apt update

5. 安装 Docker Engine

sudo apt install -y \
  docker-ce \
  docker-ce-cli \
  containerd.io \
  docker-buildx-plugin \
  docker-compose-plugin

安装完成后,Docker 服务通常会自动启动。

6. 检查 Docker 是否正常运行

查看版本:

docker --version

查看服务状态:

sudo systemctl status docker

如果 Docker 没有启动:

sudo systemctl enable --now docker

查看 Docker 运行信息:

sudo docker info

7. 运行测试容器

sudo docker run hello-world

如果安装正常,Docker 会:

  1. 检查本地是否存在 hello-world 镜像。

  2. 如果不存在,从镜像仓库下载。

  3. 根据镜像创建容器。

  4. 运行容器并显示测试信息。

  5. 容器执行完成后退出。

至此,Docker 已经安装成功。

三、Docker 镜像管理

镜像是创建容器的基础。一个镜像可以包含操作系统基础文件、运行环境、应用程序和依赖。

1. 搜索 Docker 镜像

例如搜索 Nginx:

docker search nginx

2. 下载镜像

下载 Nginx 官方镜像:

sudo docker pull nginx

指定版本:

sudo docker pull nginx:1.28

这里的 1.28 是镜像标签(Tag),用于区分不同版本。

生产环境建议使用明确版本标签,避免直接依赖可能变化的 latest 标签。

3. 查看本地镜像

sudo docker images

也可以使用:

sudo docker image ls

常见输出:

REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    xxxxxxxx       2 weeks ago    190MB
hello-world  latest    xxxxxxxx       1 year ago     10kB

4. 查看镜像详细信息

sudo docker image inspect nginx

查看镜像的构建历史:

sudo docker history nginx

5. 删除镜像

sudo docker rmi nginx

如果镜像正在被容器使用,Docker 可能拒绝删除。

可以先检查相关容器:

sudo docker ps -a

删除不再需要的容器后,再删除镜像。

注意: 不要随意执行 docker system prune -a。该命令可能清理大量未使用镜像和构建缓存,影响后续部署及镜像复用。

四、Docker 容器管理

容器是 Docker 最核心的运行单位。

下载镜像之后,可以通过 docker run 创建并运行容器。

1. 创建并运行 Nginx 容器

sudo docker run -d \
  --name my-nginx \
  -p 8080:80 \
  nginx

参数说明:

参数 作用
-d 后台运行容器
--name 指定容器名称
-p 映射宿主机端口与容器端口
nginx 使用的镜像名称

这里:

宿主机端口:8080
容器内部端口:80

访问:

http://服务器IP:8080

即可看到 Nginx 默认欢迎页面。

如果使用云服务器,还需要确认云安全组和系统防火墙是否允许访问 8080 端口。

2. 查看正在运行的容器

sudo docker ps

查看所有容器,包括已经停止的容器:

sudo docker ps -a

3. 停止容器

sudo docker stop my-nginx

4. 启动已经停止的容器

sudo docker start my-nginx

5. 重启容器

sudo docker restart my-nginx

6. 删除容器

先停止容器:

sudo docker stop my-nginx

再删除:

sudo docker rm my-nginx

如果容器正在运行,可以使用:

sudo docker rm -f my-nginx

注意:删除容器不等于删除镜像。容器中未持久化保存的数据可能随容器删除而丢失。

7. 查看容器日志

sudo docker logs my-nginx

实时查看日志:

sudo docker logs -f my-nginx

只查看最后 100 行:

sudo docker logs --tail 100 my-nginx

8. 进入容器内部

sudo docker exec -it my-nginx bash

如果容器没有安装 Bash,可以尝试:

sudo docker exec -it my-nginx sh

退出容器:

exit

9. 查看容器资源占用

sudo docker stats

查看指定容器:

sudo docker stats my-nginx

可以观察 CPU、内存、网络和磁盘读写情况。

五、Docker 端口映射

Docker 容器通常拥有独立的网络环境,外部设备不能直接访问容器内部端口。

通过 -p 参数可以将宿主机端口映射到容器端口。

1. 基本端口映射

sudo docker run -d \
  --name nginx-demo \
  -p 8080:80 \
  nginx

映射关系:

宿主机 8080  --->  容器 80

2. 指定宿主机监听地址

sudo docker run -d \
  --name nginx-local \
  -p 127.0.0.1:8081:80 \
  nginx

这种方式只允许宿主机本地访问映射端口,外部网络不能直接通过服务器公网 IP 访问该端口。

适合让 Nginx 反向代理访问内部应用。

3. 查看端口映射

sudo docker port nginx-demo

查看详细网络信息:

sudo docker inspect nginx-demo

4. 查看宿主机监听端口

sudo ss -lntp

安全提醒: Docker 发布端口可能通过 Docker 自己管理的网络规则实现转发,不应假设 UFW 中的普通规则一定能够拦截所有发布端口。对外开放端口前,应检查 Docker 网络规则、系统防火墙和云安全组。

六、Docker 数据卷管理

数据卷(Volume)用于保存容器运行产生的数据。

例如:

  • MySQL 数据库文件

  • Redis 持久化文件

  • 用户上传的文件

  • 应用日志

  • 配置文件

如果数据只保存在容器可写层中,删除容器后数据可能丢失。

因此,重要数据应该使用数据卷或绑定挂载。

1. 创建数据卷

sudo docker volume create nginx-data

2. 查看数据卷

sudo docker volume ls

3. 查看数据卷详细信息

sudo docker volume inspect nginx-data

Docker 会显示数据卷在宿主机上的实际存储位置。

不要直接修改 Docker 管理目录中的数据文件,优先通过容器或 Docker 数据卷接口管理数据。

4. 将数据卷挂载到容器

sudo docker run -d \
  --name nginx-volume \
  -p 8082:80 \
  -v nginx-data:/usr/share/nginx/html \
  nginx

这里:

nginx-data
    |
    v
容器内 /usr/share/nginx/html

容器访问该目录时,实际使用的是 Docker 数据卷中的内容。

5. 验证数据持久化

进入容器:

sudo docker exec -it nginx-volume sh

创建测试文件:

echo "Docker Volume Test" > /usr/share/nginx/html/test.txt

退出容器:

exit

删除容器:

sudo docker rm -f nginx-volume

使用相同数据卷重新创建容器:

sudo docker run -d \
  --name nginx-volume \
  -p 8082:80 \
  -v nginx-data:/usr/share/nginx/html \
  nginx

访问:

http://服务器IP:8082/test.txt

如果能够看到:

Docker Volume Test

说明数据卷已经成功保存数据。

6. 删除数据卷

sudo docker volume rm nginx-data

重要: 删除数据卷可能造成永久性数据丢失。删除前必须确认其中没有需要保留的数据,并做好备份。

7. 清理未使用的数据卷

sudo docker volume prune

该命令会删除没有被容器引用的数据卷。执行前必须检查数据卷是否仍有备份或恢复价值。

七、绑定挂载:将宿主机目录映射到容器

除了 Docker 管理的数据卷,还可以直接将宿主机目录挂载到容器。

这种方式称为 Bind Mount。

例如,宿主机有一个目录:

/opt/docker/nginx/html

希望将它映射到容器的 Nginx 网站目录。

1. 创建宿主机目录

sudo mkdir -p /opt/docker/nginx/html

2. 创建测试网页

echo "<h1>Hello Docker</h1>" | sudo tee /opt/docker/nginx/html/index.html

3. 启动容器并挂载目录

sudo docker run -d \
  --name nginx-bind \
  -p 8083:80 \
  -v /opt/docker/nginx/html:/usr/share/nginx/html \
  nginx

访问:

http://服务器IP:8083

就能看到测试网页。

4. 数据卷与绑定挂载的区别

对比项目 Docker Volume Bind Mount
存储位置 Docker 管理 用户指定目录
创建方式 docker volume create mkdir
管理方式 Docker 命令 Linux 文件系统
适用场景 数据库、持久化数据 网站文件、配置文件
迁移方式 备份和恢复卷数据 直接备份宿主机目录

对于数据库数据,通常优先考虑使用 Docker Volume;对于需要直接编辑的网页文件、配置文件,Bind Mount 更方便。

注意:挂载目录时,容器进程必须拥有对应的读写权限。另外,挂载到容器中已有内容的目录,通常会遮蔽镜像原本该目录中的文件。

八、Docker 网络基础

Docker 提供网络功能,使不同容器之间能够相互通信。

1. 查看 Docker 网络

sudo docker network ls

默认情况下通常可以看到:

  • bridge

  • host

  • none

2. 查看 bridge 网络信息

sudo docker network inspect bridge

3. 创建自定义网络

sudo docker network create app-network

4. 将容器加入自定义网络

sudo docker run -d \
  --name nginx-app \
  --network app-network \
  nginx

5. 容器之间通过名称通信

在同一个自定义网络中,容器通常可以通过容器名称进行 DNS 解析。

例如,另一个容器连接 Nginx:

http://nginx-app:80

这比在应用配置中固定容器 IP 更方便。

6. 删除网络

sudo docker network rm app-network

删除网络前,需要确保没有容器正在使用它。

九、Dockerfile:构建自己的镜像

前面使用的 Nginx 镜像是从镜像仓库下载的。

实际开发中,通常需要把自己的应用程序打包成镜像。

Dockerfile 就是用于描述镜像构建过程的文件。

下面以一个简单的 Python Web 应用为例。

1. 创建项目目录

mkdir -p ~/docker-demo
cd ~/docker-demo

创建 app.py:

from http.server import BaseHTTPRequestHandler, HTTPServer


class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-Type", "text/plain; charset=utf-8")
        self.end_headers()
        self.wfile.write("Hello Docker".encode("utf-8"))


server = HTTPServer(("0.0.0.0", 8000), Handler)
server.serve_forever()

2. 创建 Dockerfile

FROM python:3.12-slim

WORKDIR /app

COPY app.py .

EXPOSE 8000

CMD ["python", "app.py"]

说明:

指令 作用
FROM 指定基础镜像
WORKDIR 设置工作目录
COPY 复制文件到镜像
EXPOSE 声明应用使用的端口
CMD 指定容器默认启动命令

EXPOSE 只是声明容器使用的端口,并不会自动向宿主机发布端口。

3. 构建镜像

sudo docker build -t python-demo:1.0 .

参数说明:

  • -t:指定镜像名称和标签。

  • .:指定当前目录为构建上下文。

4. 查看构建结果

sudo docker images

应该能够看到:

python-demo   1.0

5. 运行 Python 容器

sudo docker run -d \
  --name python-demo \
  -p 8000:8000 \
  python-demo:1.0

访问:

http://服务器IP:8000

页面应该返回:

Hello Docker

6. 修改代码后重新构建

修改 app.py 后,重新构建镜像:

sudo docker build -t python-demo:1.1 .

停止并删除旧容器:

sudo docker rm -f python-demo

使用新镜像启动:

sudo docker run -d \
  --name python-demo \
  -p 8000:8000 \
  python-demo:1.1

注意:镜像更新不会自动替换已经运行的容器。重新构建后,需要使用新镜像创建容器。

十、Docker 常用命令汇总

镜像管理

docker pull nginx          # 下载镜像
docker images              # 查看镜像
docker image inspect nginx # 查看镜像信息
docker rmi nginx           # 删除镜像
docker history nginx       # 查看镜像构建历史

容器管理

docker run nginx           # 创建并运行容器
docker ps                  # 查看运行中的容器
docker ps -a               # 查看所有容器
docker start 容器名        # 启动容器
docker stop 容器名         # 停止容器
docker restart 容器名      # 重启容器
docker rm 容器名           # 删除容器
docker logs 容器名         # 查看日志
docker exec -it 容器名 sh  # 进入容器
docker inspect 容器名      # 查看容器信息

数据卷管理

docker volume create 数据卷名
docker volume ls
docker volume inspect 数据卷名
docker volume rm 数据卷名
docker volume prune

网络管理

docker network ls
docker network create 网络名
docker network inspect 网络名
docker network rm 网络名

系统管理

docker info
docker stats
docker system df
docker system prune

执行清理命令之前,应先确认待清理对象。不要为了释放磁盘空间而盲目清理生产环境数据卷或镜像。

十一、Docker 常见问题排查

1. Docker 服务无法启动

检查状态:

sudo systemctl status docker

查看详细日志:

sudo journalctl -u docker -n 100 --no-pager

尝试重新启动:

sudo systemctl restart docker

如果仍然无法启动,应先根据日志定位配置、存储驱动、磁盘空间或网络问题,不要直接删除 Docker 数据目录。

2. 端口已经被占用

例如启动容器时出现端口冲突。

检查端口:

sudo ss -lntp | grep 8080

更换宿主机端口:

sudo docker run -d \
  --name nginx-new \
  -p 8084:80 \
  nginx

3. 容器启动后立即退出

查看容器:

sudo docker ps -a

查看日志:

sudo docker logs 容器名

常见原因:

  • 启动命令执行失败。

  • 应用配置错误。

  • 依赖文件缺失。

  • 应用进程执行完成后退出。

  • 端口或文件权限配置错误。

Docker 容器通常会在主进程退出后结束运行。

4. 容器无法访问外部网络

检查容器网络:

sudo docker network ls

检查容器内部网络:

sudo docker exec -it 容器名 sh

进入后测试 DNS 和网络连接:

cat /etc/resolv.conf

如果系统中安装了相应工具,还可以测试:

getent hosts example.com

重点检查宿主机 DNS、路由、防火墙和 Docker 网络配置。

5. Docker 占用磁盘空间过大

查看 Docker 磁盘使用情况:

sudo docker system df

查看镜像:

sudo docker images

查看容器:

sudo docker ps -a

查看数据卷:

sudo docker volume ls

确认无用对象后,再逐项清理。数据库卷、上传文件卷等业务数据不能当作普通缓存删除。

十二、Docker 生产环境使用建议

Docker 能简化应用部署,但并不意味着容器可以完全不做安全和运维管理。

1. 不要随意使用 root 权限运行应用

容器内应用尽量使用非 root 用户运行,减少应用漏洞被利用后的影响。

2. 不要随意暴露数据库端口

例如 MySQL 通常不需要直接对公网开放。

如果只供其他容器使用,可以让它们加入同一个自定义网络,不发布 MySQL 的宿主机端口。

3. 重要数据必须持久化

数据库、上传文件、业务数据应使用 Volume 或 Bind Mount,并建立独立备份策略。

数据卷不是备份。宿主机磁盘损坏、误删除或勒索软件攻击仍然可能导致数据丢失。

4. 合理设置容器资源限制

例如:

sudo docker run -d \
  --name nginx-limit \
  --memory=512m \
  --cpus=1 \
  -p 8085:80 \
  nginx

这里将容器内存限制为 512 MB,CPU 使用上限设置为 1 个 CPU 核心。

实际限制应根据应用负载合理调整。

5. 使用明确的镜像版本

生产环境建议指定稳定版本,避免镜像标签发生变化造成部署结果不一致。

对于要求更高的场景,可以固定镜像 Digest,并建立镜像更新和漏洞修复流程。

6. 做好日志与备份

需要定期检查:

  • 容器运行状态。

  • Docker 服务日志。

  • 容器应用日志。

  • 磁盘使用情况。

  • 数据库备份是否成功。

  • 数据恢复流程是否经过验证。

7. 谨慎开放 Docker 管理权限

Docker Socket 通常具有很高的宿主机控制能力。不要将 /var/run/docker.sock 随意挂载给普通容器,也不要将未经保护的 Docker Remote API 暴露到公网。

将普通用户加入 docker 用户组也通常相当于授予其很高的宿主机管理权限,不能把它当作普通的无风险权限设置。

十三、总结

通过本教程,我们了解了 Docker 的基本架构,并完成了从安装到运行容器的完整入门操作。

本篇重点掌握:

  1. Docker 的基本概念和工作原理。

  2. Debian 系统安装 Docker Engine。

  3. 下载、查看和删除 Docker 镜像。

  4. 创建、启动、停止和删除容器。

  5. 容器端口映射与网络管理。

  6. 使用 Docker Volume 保存数据。

  7. 使用 Bind Mount 映射宿主机目录。

  8. 编写 Dockerfile 并构建自己的镜像。

  9. Docker 常用命令与故障排查。

  10. 生产环境中的数据、安全和资源管理。

Docker 是现代 Web 应用部署的重要工具。掌握镜像、容器和数据卷之后,就可以进一步学习多容器协作、应用编排和自动化部署。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。