Docker 入门:从概念到安装,带你跨过第一道坎

说实话,我第一次接触 Docker 是在一个深夜。公司线上环境出了个奇怪的 BUG,本地怎么都复现不了。折腾了三个小时,最后发现是操作系统版本差了那么一点点。那会儿我就想,要是能把整个运行环境打包带走就好了。后来遇到 Docker,我知道,就是它了。

这章咱们不扯太多虚的。我把 Docker 拆成三块来讲:它到底是什么、那几个绕不开的核心概念、以及怎么在你的机器上把它跑起来。

1.1 Docker 到底是什么?

Docker 是一个开源的容器化平台。说白了,它能把你的应用和它依赖的运行环境,一起打包到一个“箱子”里。这个箱子,不管扔到哪台机器上,都能直接打开运行。

你想想看,传统的部署流程是什么样的?

  • 开发环境:Windows + Python 3.8 + 本地 MySQL
  • 测试环境:CentOS + Python 3.6 + Docker MySQL
  • 生产环境:Ubuntu + Python 3.10 + 云数据库

三个环境,三个样。每次部署都像是在拆盲盒。而 Docker 要做的,就是让这三套环境变得完全一致。

它的核心原理,是利用 Linux 内核的命名空间(Namespace)和控制组(Cgroups)技术。Namespace 让每个容器都以为自己是一台独立的机器,Cgroups 则限制这台“机器”能用多少 CPU 和内存。我在项目中遇到过,有人把容器和虚拟机搞混了——虚拟机是模拟一整套硬件,而容器只是把进程“关”在隔离环境里。说白了,容器跑起来就是宿主机上的一个进程,启动速度当然比虚拟机快得多。

什么时候该用 Docker? 只要你的应用需要一致的环境、想快速交付、或者需要隔离运行多个服务,Docker 都是好选择。我自己的经验是:但凡要部署的项目,第一步就是写 Dockerfile。

1.2 三个核心概念:镜像、容器、仓库

这三个词你以后每天都会见到。我换种说法来解释它们的关系——镜像就是菜谱,容器就是做好的菜,仓库就是存菜谱的书架。

镜像(Image)

镜像是只读的模板。它包含了运行一个应用所需的一切:代码、运行时、系统工具、库文件、环境变量。你用同一个镜像启动十次,得到的环境一模一样。

举个例子,一个 Python Web 应用的镜像大概是这样一层层叠起来的:

FROM python:3.9-slim          # 基础层:操作系统 + Python
WORKDIR /app                  # 设置工作目录
COPY requirements.txt .       # 复制依赖文件
RUN pip install -r requirements.txt  # 安装依赖
COPY . .                      # 复制代码
CMD ["python", "app.py"]      # 启动命令

每一行指令都会生成一层,Docker 会缓存这些层。你改了代码,只需要重新跑最后几层,前面那些层直接用缓存。这就是为什么 Docker 构建速度快——我在项目里经常利用这个特性,把安装依赖和复制代码分开写,大大加速了 CI 流程。

容器(Container)

容器是镜像的运行实例。你可以把它看作一个轻量级的、可运行的沙箱。每个容器都有自己独立的文件系统、网络和进程空间。

从镜像启动一个容器很简单:

docker run -d --name my-app -p 8080:80 nginx:latest

这条命令背后的过程,我来拆解给你看:

  1. Docker 在本地找 nginx:latest 这个镜像
  2. 找不到?去仓库拉取
  3. 在镜像上加一层可写层,创建容器
  4. 分配独立的网络、PID、挂载点等命名空间
  5. 运行 nginx 进程

你运行 docker ps 就能看到这个容器。想停掉就 docker stop my-app,想删掉就 docker rm my-app。

避坑指南: 容器是有状态的吗?不要想当然。容器停掉或删除后,它里面写的数据也会丢。我曾经在这上面栽过跟头——数据库容器一删,数据全没了。解决方案是用数据卷(Volume)把数据持久化到宿主机。

仓库(Registry)

仓库是用来存放镜像的地方。最常用的是 Docker Hub,你可以把它想象成镜像的 GitHub。你可以在上面拉取别人做好的镜像,也可以上传自己的镜像。

拉取镜像的命令:

docker pull ubuntu:22.04
docker pull python:3.10-slim
docker pull nginx:1.25-alpine

上传镜像:

docker push yourname/your-image:tag

镜像的命名规则是 仓库名/镜像名:标签。标签通常用来区分版本。我用 alpine 版本比较多,因为它特别小,只有几兆,功能却不缩水。

快速对比:镜像 vs 容器

对比项 镜像 容器
本质 只读模板文件 运行的进程 + 文件系统
生命周期 长期存在,可复用 启动、运行、停止、删除
数据 不可修改 可读写,但重启后丢失
类比 程序文件(.exe) 运行中的程序

记住这个原则: 镜像就是代码,容器就是进程。别在容器里改东西,要改就改镜像。

Docker 核心知识体系 开发 → 打包 → 分发 → 运行 镜像 Image 只读模板 包含环境 + 代码 + 依赖 分层构建 可缓存 类比:菜谱 / .exe文件 docker run 容器 Container 运行中的镜像实例 独立文件系统 独立网络 进程隔离 类比:做好的菜 / 运行的进程 docker push 仓库 Registry 存储与分发 Docker Hub / 私有仓 版本管理 协作共享 类比:书架 / GitHub docker pull docker build 核心工作流 编写 Dockerfile → docker build → docker push → docker pull → docker run 安装配置要点 选择平台 ❯ 安装引擎 ❯ 添加用户组 ❯ 配置镜像加速 ❯ 验证安装 学习流程 理解概念 动手安装

1.3 安装与配置

安装 Docker 其实不复杂,但不同平台有些细节要注意。我把三个主流平台分开来讲。

Linux(以 Ubuntu 为例)

这是 Docker 的老家,体验最好。我个人建议用官方提供的安装脚本,干净利落:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

装完之后,你可以做两件事:

第一,把当前用户加到 docker 组里,省得每次敲 sudo:

sudo usermod -aG docker $USER
# 注销重新登录后生效

第二,配置镜像加速器。因为 Docker Hub 在国内访问有时候很慢,换成国内镜像源能快不少。编辑 /etc/docker/daemon.json:

{
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://dockerproxy.com"
  ]
}

改完后重启 Docker:

sudo systemctl daemon-reload
sudo systemctl restart docker
注意: daemon.json 这个文件如果不存在,你自己新建一个就行。别搞错路径,我曾经在 /etc/docker/ 下放错了位置,Docker 半天没反应。

macOS

macOS 上不能用原生的 Docker,需要装一个虚拟机来跑。Docker Desktop 是最方便的选择。

  1. 去 Docker 官网下 Docker Desktop for Mac
  2. 双击安装,拖到 Applications 文件夹
  3. 启动后,状态栏会出现小鲸鱼图标

安装完成后,在设置里同样可以配置镜像加速器,和 Linux 一样,找到 Docker Engine 选项卡,把上面那段 JSON 贴进去就行。

Windows

Windows 上有两种模式:Hyper-V 模式和 WSL 2 模式。我强烈推荐 WSL 2 模式,因为它启动更快,资源占用也更小。

步骤是这样的:

  1. 打开 PowerShell(管理员),运行 wsl --install 安装 WSL 2
  2. 下载 Docker Desktop for Windows 并安装
  3. 安装时勾选“Use WSL 2 based engine”
  4. 启动 Docker Desktop,在设置里开启 WSL 2 集成
小技巧: 装完 Docker Desktop 后,你可以直接在你常用的 Linux 发行版(比如 Ubuntu on WSL)里面敲 docker 命令,体验和 Linux 上几乎一样。

验证安装

不管哪个平台,装完之后跑一下这个命令,看到版本信息就算成功了:

docker --version
# 输出示例:Docker version 24.0.7, build afdd53b

然后再跑一个经典测试:

docker run hello-world

这个命令会从 Docker Hub 拉取一个 hello-world 镜像,然后启动容器。如果看到一串欢迎信息,说明你的 Docker 已经可以正常工作了。整个过程的感觉就像——你写了第一行 "Hello World",只不过这次,是整个环境的 "Hello World"。

嗯,到这里,Docker 的基本概念和安装就齐活了。你可能会觉得,就这些?对,就这些。Docker 本身不复杂,复杂的是后面那些编排、网络、存储的东西。但别急,我们一章一章来。先把脚下的路踩实了,后面才会走得稳。