简介《Docker基础入门指南》面向具备一定计算机基础、希望从零掌握容器技术的开发者与运维初学者帮助解决环境搭建繁琐、部署流程不统一等入门痛点。资源包共1个PDF文件约696KB内容以图文与命令示例为主便于随时查阅与动手练习。文档从Docker概念与容器、虚拟机对比讲起梳理镜像、容器、仓库三大核心概念并覆盖Windows、macOS及Ubuntu平台的安装配置基础操作部分涵盖拉取镜像、运行与查看容器、进入容器内部、停止删除等常用命令。实战环节通过Nginx服务器部署、挂载本地目录、编写Dockerfile构建Python应用镜像等案例串联镜像管理与Web应用部署流程同时给出权限配置、镜像加速、数据持久化等常见问题解决思路及学习资源推荐。目前已有126人学习适合按章节顺序边学边练快速建立容器化开发的完整认知。1. 从一份 Docker 基础入门指南说起为什么你装完就卡在第一步很多人第一次接触容器技术是从一份 Docker 基础入门指南.pdf 开始的。照着文档敲docker run hello-world结果终端要么报Cannot connect to the Docker daemon要么在 Windows 上弹出一句virtualization support not detected docker desktop failed to start直接卡死在第一步。这不是你笨而是容器技术横跨了内核、网络、文件系统三层任何一层没对齐命令就跑不起来。这篇东西不讲概念史只解决一件事让你在一台干净的机器上把 Docker 装好、跑起来、能拉镜像、能起容器、能排错最后知道这套东西值不值得往生产环境推。适合两类人刚接手服务器、被要求「用容器部署一下」的后端和运维新手以及用过docker run但一遇到网络不通、权限报错就抓瞎的熟手。下面按「装 → 跑 → 配 → 排 → 进阶」的顺序推每一步都给能直接抄的命令和参数解释。2. 装 Docker 之前先想清楚三种安装路径怎么选2.1 为什么 Linux、Windows、macOS 的安装逻辑完全不同Docker 本质是 Linux 内核能力的封装namespace 做隔离cgroup 做资源限制UnionFS 做分层镜像。所以它在 Linux 上是原生的在 Windows 和 macOS 上必须借助一层虚拟机。这就决定了三条安装路径的差异。Linux 上装的是 Docker Engine直接跑在宿主机内核上性能损耗接近零是生产环境唯一推荐的方式。Ubuntu、CentOS、Debian 都走这条路。Windows 上装的是 Docker Desktop它内部起一个 WSL2 或 Hyper-V 虚拟机你的容器其实跑在虚拟机里所以会碰到virtualization support not detected这类问题——不是 Docker 坏了是 BIOS 里的虚拟化开关没开。macOS 同理Docker Desktop 跑在一个轻量 Linux VM 里。选型结论很直接服务器一律 Linux 原生安装本地开发用 Windows 或 macOS 的 Docker Desktop 图省事如果 Windows 上要做接近生产的验证优先开 WSL2 后端而不是 Hyper-V。2.2 Ubuntu 上装 Docker Engine 的最小命令序列下面这套是 Ubuntu 22.04/24.04 上最稳的装法用官方仓库而不是apt install docker.io因为发行版自带的版本往往落后好几个大版本。# 1. 卸载可能存在的旧版本避免冲突 sudo apt remove docker docker-engine docker.io containerd runc # 2. 装依赖ca证书、curl、gnupg sudo apt update sudo apt install -y ca-certificates curl gnupg # 3. 添加官方 GPG 密钥用于校验包来源 sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg # 4. 写入软件源注意 $(dpkg --print-architecture) 自动匹配 amd64/arm64 echo deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 5. 安装引擎、CLI、containerd 和 compose 插件 sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # 6. 验证能打印版本且守护进程在跑 sudo systemctl status docker docker version逻辑说明第 3 步的 GPG 密钥是防止你从被篡改的源拉到恶意包这一步别省。第 4 步用VERSION_CODENAME自动取jammy或noble避免手写错代号导致apt update报 404。第 5 步一次装齐五个包docker-compose-plugin让你能用docker compose注意是空格不是横杠这个新语法。参数说明-m 0755是给目录设权限--dearmor把 ASCII 密钥转成二进制格式新版 apt 要求这样。装完默认只有 root 能调 Docker普通用户要加进 docker 组见 2.3。2.3 装完必做的两件事免 sudo 和换镜像源第一件把当前用户加进 docker 组否则每条命令都要sudo脚本里会很难受sudo usermod -aG docker $USER # 退出重新登录或执行下面这行让组生效 newgrp docker # 验证不加 sudo 也能跑 docker ps第二件国内拉镜像慢是常态配一个镜像加速器。编辑/etc/docker/daemon.json{ registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com ], log-driver: json-file, log-opts: { max-size: 100m, max-file: 3 } }逻辑说明registry-mirrors是拉取镜像时的备用源Docker 会按顺序尝试。log-driver和log-opts是给容器日志做轮转不然一个话痨容器几天就能把磁盘写满这是血泪经验。改完执行sudo systemctl daemon-reload sudo systemctl restart docker生效。参数说明max-size: 100m表示单个日志文件到 100MB 就切max-file: 3表示最多留 3 个总共不超过 300MB。镜像源地址会失效用之前先确认能通别照抄一个早就挂掉的地址然后怀疑人生。3. 跑起第一个容器run、exec、网络三件套3.1 docker run 的参数到底在控制什么docker run是入门最高频也最容易用错的命令。它的参数分四类镜像与命令、端口映射、存储挂载、运行模式。看一个典型例子docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDyourpass \ -v /data/mysql:/var/lib/mysql \ --restart unless-stopped \ mysql:8.0逻辑说明-d让容器后台运行不加它你的终端会被占住。--name给容器起名方便后续docker exec和docker stop引用不然只能用随机 ID。-p 3306:3306是端口映射格式是「宿主机端口:容器端口」左边是你从外面访问的端口右边是容器内服务监听的端口写反了就连不上。-e注入环境变量MySQL 镜像靠MYSQL_ROOT_PASSWORD初始化 root 密码不设这个变量容器会直接退出。-v把宿主机目录挂进容器数据库数据必须挂出来否则容器一删数据全没。--restart unless-stopped让容器随 Docker 启动而自启除非你手动停过它。参数说明mysql:8.0里的8.0是标签不写标签默认拉latest生产环境千万别用latest因为下次拉可能就变了个大版本直接把你搞翻车。3.2 进容器排查exec 和 run 的区别容器起来了但服务没通第一反应是进去看。这里有个高频混淆点docker exec和docker run都能给你一个 shell但语义完全不同。# 进入正在运行的容器开一个交互式 bash docker exec -it mysql8 bash # 如果容器里没有 bash用 sh docker exec -it mysql8 sh # 在运行中的容器里执行单条命令不进交互 docker exec mysql8 mysql -uroot -p -e show databases; # 用一次性容器做临时任务跑完即删 docker run --rm -it alpine sh逻辑说明exec是「进入一个已经在跑的容器」前提是容器状态为 Up容器停了会报is not running。run是「用镜像新建一个容器」--rm表示退出后自动删除适合做临时调试不留垃圾。-it是-i保持标准输入加-t分配伪终端的合写少了-t你敲命令会没有回显少了-i交互程序会立刻退出。参数说明alpine是个 5MB 左右的极简镜像拿来测网络、测 DNS 特别方便比动辄几百 MB 的 ubuntu 镜像快得多。3.3 容器网络不通的三种典型场景网络是 Docker 入门最大的玄学区。容器之间、容器到宿主机、容器到外网三层的规则不一样。默认情况下 Docker 会创建bridge、host、none三个网络docker run不加--network就走 bridge。# 查看现有网络 docker network ls # 创建自定义 bridge 网络容器间可用名字互相解析 docker network create mynet # 两个容器接入同一网络直接用容器名通信 docker run -d --name app --network mynet nginx docker run -d --name db --network mynet mysql:8.0 # 此时在 app 容器里 ping db 是通的因为自定义网络自带 DNS逻辑说明默认 bridge 网络里的容器只能用 IP 互相访问不能用容器名这是很多人「明明都起来了却连不上」的根因。自定义 bridge 网络内置了 DNS 解析容器名就是主机名这是推荐做法。容器访问宿主机服务Linux 上用宿主机在 bridge 上的网关 IP通常是 172.17.0.1或者用--add-hosthost.docker.internal:host-gateway显式加一条解析。参数说明--network mynet指定网络不写就是默认 bridge。排查网络先用docker exec -it 容器名 ping 目标再docker exec -it 容器名 cat /etc/resolv.conf看 DNS 配置最后docker network inspect mynet看容器有没有真的接进去。4. 用 Compose 把多容器项目一次拉起来4.1 为什么单条 run 命令撑不住真实项目一个 Web 项目通常有应用、数据库、缓存、反向代理四五个组件每个都要配端口、挂载、环境变量、依赖顺序。用docker run一条条敲不仅长还没法版本管理换台机器就得重来。Compose 用一个 YAML 文件描述整套服务docker compose up -d一条命令全起来这是从入门到能干活的分水岭。4.2 一份能直接跑的 compose 文件下面这份描述了一个 Nginx MySQL Redis 的最小组合字段都是高频必用的services: web: image: nginx:1.27 ports: - 8080:80 volumes: - ./html:/usr/share/nginx/html:ro depends_on: - db networks: - backend db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: appdb volumes: - dbdata:/var/lib/mysql networks: - backend cache: image: redis:7-alpine command: redis-server --appendonly yes volumes: - cachedata:/data networks: - backend volumes: dbdata: cachedata: networks: backend: driver: bridge逻辑说明services下每个键就是一个容器。depends_on只保证启动顺序先起 db 再起 web不保证 db 里的 MySQL 已经初始化完成这是新手最容易误解的点真正的健康检查要用healthcheck。volumes顶层声明命名卷下面用dbdata:/var/lib/mysql引用命名卷由 Docker 管理比绑定宿主机目录更省心。networks顶层声明后各服务用networks: [backend]接入同一网络内服务名即主机名。参数说明./html:/usr/share/nginx/html:ro里的:ro表示只读挂载防止容器改宿主机文件。redis-server --appendonly yes开启 AOF 持久化不然 Redis 重启数据就没了。nginx:1.27锁版本别用 latest。4.3 compose 的常用操作和日志排查# 后台启动全部服务 docker compose up -d # 只看某个服务的日志实时跟随 docker compose logs -f web # 重新构建并重启某个服务改了配置后 docker compose up -d --build web # 停掉并删除容器、网络但保留命名卷 docker compose down # 连卷一起删慎用数据会没 docker compose down -v # 查看各服务状态 docker compose ps逻辑说明logs -f是排查启动失败的第一入口容器起不来时先看日志八成能看到端口占用、密码没设、配置文件语法错这类明确原因。down默认保留命名卷这是有意的设计防止你手滑删库。down -v才会连数据一起清执行前想清楚。参数说明-d是 detached后台运行--build强制重新构建镜像改了 Dockerfile 或代码后必须加否则用的还是旧镜像。5. 避坑与排查那些让新手卡半天的报错5.1 现象Cannot connect to the Docker daemon原因Docker 守护进程没启动或者当前用户没权限访问 socket。在 Linux 上多半是服务没起在 Windows/macOS 上多半是 Docker Desktop 没开。解决Linux 上sudo systemctl start docker并sudo systemctl enable docker设为开机自启权限问题执行sudo usermod -aG docker $USER后重新登录。Windows 上确认 Docker Desktop 托盘图标是运行状态报failed to connect to the docker api at npipe基本就是 Desktop 没起来。5.2 现象Windows 上 virtualization support not detected原因BIOS/UEFI 里的 CPU 虚拟化Intel VT-x 或 AMD-V没开或者 Hyper-V/WSL2 组件没启用。Docker Desktop 需要这层虚拟化才能跑 Linux 虚拟机。解决重启进 BIOS 打开虚拟化开关Windows 功能里勾选「虚拟机平台」和「适用于 Linux 的 Windows 子系统」命令行执行wsl --update更新 WSL2 内核。三条都做完再重启 Docker Desktop。5.3 现象docker 权限错误普通用户跑不了原因/var/run/docker.sock属主是 root:docker当前用户不在 docker 组里。解决sudo usermod -aG docker $USER后必须重新登录newgrp docker只对当前 shell 生效。注意 docker 组等价于 root 权限生产机上别随便加人。5.4 现象镜像下载慢或拉取超时原因默认从 Docker Hub 拉跨境链路不稳定。解决配daemon.json里的registry-mirrors改完重启 Docker。如果某个镜像源失效换一个再试别死磕一个地址。拉大镜像时用docker pull 镜像:标签单独拉能看到进度比run时卡住强。5.5 现象容器起来了但端口访问不通原因端口映射写反、宿主机防火墙没放行、服务在容器内只监听了 127.0.0.1。解决先docker port 容器名确认映射关系再docker exec -it 容器名 ss -tlnp看服务监听地址如果监听的是 127.0.0.1 而不是 0.0.0.0容器外就访问不到得改服务配置最后检查宿主机防火墙和云服务器安全组。6. 进阶把镜像做小、把环境做稳的几个具体技巧镜像体积直接决定部署速度和攻击面。一个常见误区是拿ubuntu当基础镜像装完依赖动辄 1GB 起。我一般用多阶段构建把编译环境和运行环境分开# 阶段一构建装全量依赖 FROM python:3.12-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir --prefix/install -r requirements.txt # 阶段二运行只拷成品 FROM python:3.12-slim WORKDIR /app COPY --frombuilder /install /usr/local COPY . . EXPOSE 8000 CMD [python, app.py]逻辑说明--prefix/install把依赖装到一个独立目录第二阶段用COPY --frombuilder只拷这个目录编译工具链全留在第一阶段被丢弃。--no-cache-dir不保留 pip 缓存能省几十到上百 MB。最终镜像通常能比单阶段小一半以上。参数说明python:3.12-slim比完整版小很多又比alpine兼容性好alpine 用 musl libc某些 C 扩展会编译失败。选基础镜像时slim 是多数场景的平衡点。再给一个验证镜像是否干净的习惯构建完执行docker history 镜像名看每层大小找出异常大的层用docker run --rm -it 镜像名 sh进去手动跑一遍启动命令确认没有隐藏的运行时依赖缺失。这套动作我每次发版前都做能挡掉大部分「本地好好的、上线就崩」的问题。最后说个习惯所有docker run里用到的端口、卷、环境变量都写进 compose 文件或脚本别留在终端历史里。容器这东西能复现才有价值靠记忆敲命令迟早翻车。希望帮到你。本文还有配套的精品资源点击获取