简介《Docker基础入门指南》面向具备一定计算机基础、希望从零掌握容器技术的开发者尤其适合想借助Docker提升开发效率、实现快速部署与环境一致性的初学者。文档围绕镜像、容器、仓库三大核心概念展开覆盖Windows、macOS与Ubuntu平台的安装配置并系统讲解拉取镜像、运行与查看容器、进入容器内部、停止删除容器等基础操作。实战部分以Nginx服务器部署Web应用为例演示端口映射与目录挂载同时通过Dockerfile构建Python应用镜像帮助读者理解自定义镜像的完整流程。此外还整理了权限配置、国内镜像加速、数据持久化等常见问题解决方案及后续学习资源。资源包为1个PDF文件约696KB结构清晰、章节递进便于按序阅读与动手实践。目前已有126人学习适合作为容器技术入门的第一份系统参考。1. 从一份 Docker 基础入门指南说起为什么很多人卡在第一步如果你最近在搜 docker安装教程、docker常用命令或者 docker镜像下载慢大概率已经翻到过一堆零散帖子有人让你先装 WSL2有人让你换镜像源有人贴了一长串命令却没解释参数。这份《Docker基础入门指南.pdf》的价值在于它把「概念—安装—基础操作—实战部署—自定义镜像—常见问题」串成了一条完整链路而不是只给你一个 hello-world 截图。它适合两类人一是刚接触容器技术、想在自己机器上把 Nginx 或 Python 应用跑起来的开发者二是已经会敲docker run但说不清镜像、容器、仓库三者关系遇到权限或网络问题只能重启的人。下面我按这份指南的骨架把每一步拆到能直接抄作业的程度同时补上原文没展开的选型理由和踩坑点。2. 镜像、容器与仓库先把三个核心概念钉死2.1 镜像不是「安装包」容器也不是「轻量虚拟机」很多新手第一次看 Docker 介绍会把镜像理解成 ISO把容器理解成 VMware 里的虚拟机。这个类比在「能装东西」这一点上没错但在资源模型上会带偏。镜像Image是只读模板分层存储每一层对应 Dockerfile 里的一条指令容器Container是镜像之上加了一个可写层所有运行时产生的文件变化都落在这个可写层里。容器共享宿主机内核所以启动一个 Nginx 容器通常不到一秒而开一台虚拟机要等完整操作系统引导。仓库Registry则是存放镜像的地方Docker Hub 是默认公共仓库但国内直接拉取经常遇到 docker镜像下载慢的问题。这里要区分「镜像源」和「仓库」镜像源是仓库的加速地址配置在/etc/docker/daemon.json里不改镜像本身的内容只改拉取路径。常见做法是配阿里云或网易云的加速地址但注意加速地址通常只对 Docker Hub 官方镜像生效私有仓库或第三方 registry 不一定走这个通道。提示镜像分层意味着多个容器可以共享同一个基础镜像层磁盘占用远小于「每个容器一份完整系统」。但可写层不会自动清理长期运行的容器如果频繁写文件体积会膨胀。2.2 从拉取到运行一条命令背后的参数逻辑原文给出的基础操作顺序是拉取、运行、查看、进入、停止删除。这个顺序是对的但每一步都有容易忽略的细节。先看拉取# 拉取最新版 Nginx 镜像 docker pull nginx:latest # 拉取指定版本生产环境更推荐 docker pull nginx:1.25.3nginx:latest里的latest是标签tag不是「最新稳定版」的保证。很多镜像的 latest 会跟随主分支变动今天拉的和下周拉的可能不是同一个东西。生产环境我一般会锁定具体版本号比如nginx:1.25.3这样构建和部署才可复现。拉取完成后可以用docker images查看本地镜像列表注意 IMAGE ID 是镜像内容的哈希同一镜像不同标签可能指向同一个 ID。运行容器是参数最密集的一步# 后台运行 Nginx映射宿主机 80 端口到容器 80 端口 docker run -d -p 80:80 --name my-nginx nginx # -d后台运行不占用当前终端 # -p 宿主机端口:容器端口把容器服务暴露出来 # --name给容器起一个固定名字方便后续操作这里-p 80:80的前后顺序是「宿主机:容器」写反了就会变成容器监听 80 但宿主机映射到别的端口。如果宿主机 80 已经被占用Docker 会直接报错port is already allocated不会自动换端口。常见做法是改成-p 8080:80然后访问http://localhost:8080。另外--name不是必须的但不加名字 Docker 会随机生成一个后续docker stop和docker exec就得先查 ID容易出错。查看容器状态时docker ps只看运行中的docker ps -a看所有包括已退出的。很多人跑完docker run发现docker ps里没有就以为容器没起来其实可能是启动后立刻退出了用-a才能看到退出状态码。进入容器内部用docker exec -it my-nginx /bin/bash-it是交互式终端缺了-t就没有提示符缺了-i就没法输入。注意exec是在运行中的容器里开新进程如果容器已经停止这条命令会报错得先docker start。停止和删除是两件事docker stop只是发信号让容器优雅退出容器还在可写层还在docker rm才是删除容器但镜像还在docker rmi删镜像如果有容器还在用这个镜像会提示冲突得先删容器。这个顺序不能反血泪经验是先docker stop再docker rm最后docker rmi否则就得加-f强制删除容易留下悬空层。3. 安装与权限Ubuntu 和 Windows 两条路的分叉点3.1 Ubuntu 下用官方仓库装 Docker Engine原文给的是 Ubuntu 的 apt 安装流程这套流程的核心是「加官方 GPG 密钥 加官方仓库 装 docker-ce」。为什么要这么绕因为 Ubuntu 自带仓库里的docker.io版本通常偏旧而且包名和官方不一致。官方仓库能保证你装到的是 Docker 官方维护的引擎后续升级也走同一条通道。# 更新软件包列表 sudo apt update # 安装依赖让 apt 支持 https 仓库 sudo apt install apt-transport-https ca-certificates curl software-properties-common # 添加 Docker 官方 GPG 密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # 添加 Docker 官方仓库 echo deb [archamd64 signed-by/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 再次更新并安装 Docker 引擎 sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io # 验证安装 sudo docker run hello-world$(lsb_release -cs)会自动取当前 Ubuntu 的代号比如jammy或focal这样仓库地址不用手改。signed-by指定密钥文件路径是较新 apt 版本的要求老教程里直接apt-key add的做法在新系统上会报警告。装完后sudo docker run hello-world能跑通说明引擎和客户端都正常。如果这一步报Cannot connect to the Docker daemon通常是服务没启动用sudo systemctl start docker拉起来再sudo systemctl enable docker设成开机自启。3.2 权限问题为什么每次都要加 sudoLinux 下 Docker 守护进程默认监听 Unix socket而这个 socket 属于docker组。普通用户不在这个组里就只能用sudo。原文给的解法是sudo usermod -aG docker $USER把当前用户加进 docker 组。这条命令本身没问题但有两个坑一是执行完必须重新登录或newgrp docker才生效直接开新终端不一定行二是把用户加进 docker 组等同于给了该用户 root 级权限因为容器可以挂载宿主机目录、改文件权限。所以生产机器上是否这么做要看安全边界个人开发机图方便可以加多人共用的服务器我一般还是保留 sudo。Windows 和 macOS 走的是 Docker Desktop 这条路安装包直接下Windows 需要启用 WSL2。这里常见的翻车是virtualization support not detected或docker desktop failed to start because virtualization support not detected原因通常是 BIOS 里虚拟化没开或者 Hyper-V 和 WSL2 冲突。解决顺序是先在任务管理器「性能」页确认虚拟化已启用没启用就进 BIOS 开然后确认 WSL2 已安装并设为默认版本用wsl --set-default-version 2。如果之前装过旧版 Docker Desktop最好先卸载再装新版残留的 WSL 发行版会干扰启动。注意Docker Desktop 在 Windows 上默认把镜像和容器存在 WSL2 的虚拟磁盘里这个磁盘会随着镜像增多而膨胀且不会自动收缩。定期docker system prune清理无用镜像和容器能避免 C 盘被悄悄吃满。4. 实战部署 Nginx 与自定义 Python 镜像4.1 挂载本地目录跑 Nginx验证「环境一致性」原文的实战案例是跑一个 Nginx 服务器并挂载本地 html 目录。这个案例看似简单但它验证了 Docker 最核心的价值容器里的 Nginx 配置和版本是固定的你换一台机器只要镜像一样行为就一样。挂载命令如下# 拉取 Nginx 镜像 docker pull nginx # 运行容器把本地 html 目录挂载到容器默认站点目录 docker run -d -p 8080:80 \ -v /path/to/your/html:/usr/share/nginx/html \ --name my-web \ nginx # 访问 http://localhost:8080 查看效果-v /path/to/your/html:/usr/share/nginx/html是绑定挂载bind mount冒号前是宿主机路径冒号后是容器内路径。这里要求宿主机路径必须存在否则 Docker 会把它当成一个空目录创建而不是报错。常见做法是先用mkdir -p /path/to/your/html建好再放一个index.html进去。如果访问 8080 返回 403先检查宿主机目录权限Nginx 容器内默认以 nginx 用户运行对宿主机目录没有读权限就会 403。另一个容易忽略的点是 SELinux 或 AppArmor 可能拦截挂载Ubuntu 上一般不用管CentOS 上可能需要在挂载参数后加:z或:Z。4.2 写 Dockerfile 构建 Python 应用镜像原文给的 Dockerfile 示例是 Python 应用结构是FROM、WORKDIR、COPY、RUN、EXPOSE、CMD。这个顺序有讲究COPY . .放在RUN pip install之前会导致每次改代码都重新装依赖构建缓存失效。更合理的做法是先复制requirements.txt装完依赖再复制代码# 基础镜像slim 版本体积更小 FROM python:3.9-slim # 设置工作目录后续命令都在这个目录下执行 WORKDIR /app # 先复制依赖文件利用 Docker 层缓存 COPY requirements.txt . # 安装依赖--no-cache-dir 避免在镜像里留 pip 缓存 RUN pip install --no-cache-dir -r requirements.txt # 再复制应用代码 COPY . . # 声明容器监听端口只是文档作用不实际开放 EXPOSE 5000 # 启动命令容器运行时执行 CMD [python, app.py]FROM python:3.9-slim里的slim是精简版去掉了文档和部分编译工具体积比完整版小很多但如果你要装需要编译的 Python 包可能得先补build-essential。WORKDIR /app如果目录不存在会自动创建后续的COPY和RUN都相对这个目录。COPY requirements.txt .里的.是当前工作目录也就是/app。RUN pip install --no-cache-dir能减少镜像层大小因为 pip 默认会把下载的包缓存到/root/.cache/pip不清理就白占空间。EXPOSE 5000只是声明真正让外部访问还得在docker run时加-p 5000:5000。CMD用 JSON 数组形式避免 shell 解析带来的信号传递问题。构建和运行# 在当前目录构建镜像-t 指定镜像名和标签 docker build -t my-python-app . # 运行容器映射 5000 端口 docker run -p 5000:5000 my-python-appdocker build最后的.是构建上下文路径Docker 会把该目录下的文件发给守护进程。如果目录里有大文件或虚拟环境最好写.dockerignore排除否则构建会变慢。构建失败时先看报错在哪一层如果是pip install失败常见原因是网络问题或依赖版本冲突可以进容器手动跑一遍命令排查。5. 避坑与排查镜像慢、权限错、端口冲突怎么解5.1 镜像下载慢配镜像源不是万能药现象docker pull卡在Waiting或进度条几乎不动。原因默认走 Docker Hub国内网络到 Docker Hub 的链路不稳定。解决编辑/etc/docker/daemon.json加入镜像加速地址然后重启 Docker。{ registry-mirrors: [https://your-mirror.mirror.aliyuncs.com] }改完后sudo systemctl restart docker。注意加速地址只对 Docker Hub 官方镜像生效如果你拉的是gcr.io或私有仓库的镜像加速器不生效得另找对应仓库的镜像同步方案。另外daemon.json是 JSON 格式不能写注释多一个逗号都会导致 Docker 启动失败改完先用sudo dockerd --validate或直接看systemctl status docker的报错。5.2 权限错误permission denied的三种来源现象docker ps报Got permission denied while trying to connect to the Docker daemon socket。原因当前用户不在 docker 组。解决sudo usermod -aG docker $USER后重新登录。如果已经加了组还报错检查 socket 权限ls -l /var/run/docker.sock正常应该是srw-rw---- root docker。另一种权限错误发生在挂载目录时容器内进程对宿主机目录没有读权限表现为 Nginx 403 或应用报Permission denied解决是调整宿主机目录权限或换一个挂载路径。第三种是 SELinux 拦截CentOS 上常见挂载时加:z标签。5.3 端口冲突与容器名冲突现象docker run报Bind for 0.0.0.0:80 failed: port is already allocated。原因宿主机 80 端口已被其他进程占用可能是另一个容器也可能是宿主机上的 Nginx 或 Apache。解决sudo lsof -i :80查占用进程或者直接换宿主机端口比如-p 8080:80。容器名冲突则是Conflict. The container name /my-nginx is already in use说明之前有个同名容器没删干净用docker rm my-nginx删掉如果容器还在运行就先docker stop。注意docker rm默认只能删已停止的容器运行中的要加-f但强制删除可能留下未清理的卷。5.4 容器启动后立刻退出现象docker run -d后docker ps看不到容器docker ps -a显示Exited (0)或Exited (1)。原因容器的主进程执行完就退出了Docker 认为容器生命周期结束。比如你docker run一个ubuntu镜像但不给命令它会立刻退出。解决运行交互式容器加-it和bash或者让主进程保持前台运行。对于自己构建的 Python 应用检查CMD里的启动命令是否能在前台持续运行如果应用是后台守护进程模式容器会立刻退出常见做法是让应用跑在前台或者用tail -f占住。5.5 数据持久化删容器不等于删数据现象删掉容器后之前写入的数据没了。原因容器可写层随容器删除而消失。解决用-v挂载数据卷或绑定宿主机目录。数据卷volume由 Docker 管理存在/var/lib/docker/volumes/下适合数据库这类需要持久化的场景绑定挂载bind mount直接映射宿主机目录适合开发时同步代码。注意docker rm -v会同时删除匿名卷如果不想丢数据删容器时别加-v或者提前把数据卷挂到固定名字上。6. 进阶技巧用 Compose 编排多容器与验证清单单容器跑通之后下一步通常是 MySQL、Redis 这类有状态服务或者多容器协作。原文提到可以学 Docker Compose这里给一个最小可用的 Compose 文件把 Nginx 和 Python 应用串起来version: 3.8 services: web: build: . ports: - 5000:5000 depends_on: - redis redis: image: redis:7-alpine volumes: - redis-data:/data volumes: redis-data:build: .表示用当前目录的 Dockerfile 构建镜像depends_on只保证启动顺序不保证 redis 完全就绪应用里最好加重试逻辑。volumes声明了一个命名卷redis-data这样docker compose down删容器时数据还在除非加-v。启动用docker compose up -d看日志用docker compose logs -f web进容器用docker compose exec web bash。这套编排比手敲一长串docker run更容易维护尤其是环境变量和网络配置多的时候。验证一个 Docker 环境是否健康我一般走一遍这个清单docker version看客户端和服务端是否都通docker info看存储驱动和镜像源是否生效docker run --rm hello-world确认能拉镜像能跑容器docker compose version确认 Compose 插件可用。如果docker info里Registry Mirrors为空说明 daemon.json 没被加载检查文件路径和 JSON 格式。从那以后我每次在新机器上装完 Docker都强制走一遍这个清单避免后面部署时才发现镜像拉不动。希望帮到你。本文还有配套的精品资源点击获取