Docker 基础:从安装到第一个容器
聊到编解码器部署,Docker 几乎是绕不开的工具。我最早接触 Docker 是在 2016 年,那时候还在用笨重的虚拟机跑 FFmpeg 转码服务。说实话,第一次用 Docker 跑起一个容器时,那种「秒级启动」的感觉确实震撼。今天我们就从零开始,把 Docker 的安装、核心概念和 Dockerfile 编写过一遍。
Docker 安装与配置
不同操作系统安装方式略有差异。我个人习惯在 Linux 上做生产部署,但开发调试用 macOS 或 Windows 也完全没问题。
Linux(Ubuntu/Debian 系)
# 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 设置稳定版仓库
echo \
"deb [arch=$(dpkg --print-architecture) 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 Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 验证安装
sudo docker run hello-world
sudo usermod -aG docker $USER。退出重新登录即可生效。
macOS 与 Windows
直接下载 Docker Desktop 就行。我建议去官网下载稳定版,别用 beta 版——曾经踩过 beta 版网络栈不稳定的坑,排查了一下午才发现是 Docker 版本问题。
| 平台 | 下载地址 | 注意事项 |
|---|---|---|
| macOS | docs.docker.com/desktop/mac/install | Apple Silicon 选 arm64 版本 |
| Windows | docs.docker.com/desktop/windows/install | 需启用 WSL2 或 Hyper-V |
配置镜像加速器
国内拉取镜像经常慢得让人抓狂。我一般用阿里云或中科大的加速器。配置方式很简单:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://你的加速器地址.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
镜像与容器:理解核心概念
很多新手搞不清镜像和容器的区别。我打个比方:镜像就像 ISO 安装盘,容器就是装好系统的电脑。镜像只读,容器可写。你可以从同一个镜像启动无数个容器,每个容器都是独立的运行环境。
核心关系:
- 镜像(Image):静态的、只读的模板,包含操作系统、依赖库、应用代码
- 容器(Container):镜像的运行实例,有独立的文件系统、网络、进程空间
- 仓库(Registry):存放镜像的地方,Docker Hub 是默认的公共仓库
下面这张图能帮你理清它们的关系:
常用命令速查
| 操作 | 命令 | 说明 |
|---|---|---|
| 拉取镜像 | docker pull nginx:latest |
从仓库拉取指定标签的镜像 |
| 查看镜像 | docker images |
列出本地所有镜像 |
| 运行容器 | docker run -d --name mynginx -p 8080:80 nginx |
后台运行,映射端口 |
| 查看容器 | docker ps -a |
列出所有容器(包括已停止的) |
| 进入容器 | docker exec -it mynginx bash |
在运行中的容器内执行命令 |
| 停止容器 | docker stop mynginx |
优雅停止 |
| 删除容器 | docker rm mynginx |
删除前需先停止 |
--name 参数命名,不然 Docker 会随机生成一个像 focused_curie 这样的名字,容器多了根本分不清谁是谁。
Dockerfile 编写入门
Dockerfile 就是镜像的「制作说明书」。你想想看,如果每次部署都要手动装依赖、配环境,那跟传统部署有什么区别?Dockerfile 把这些步骤自动化了。
一个简单的例子
假设我们要部署一个 FFmpeg 转码服务:
# 使用官方 Ubuntu 作为基础镜像
FROM ubuntu:22.04
# 设置环境变量,避免交互式安装
ENV DEBIAN_FRONTEND=noninteractive
# 安装 FFmpeg 和必要工具
RUN apt-get update && apt-get install -y \
ffmpeg \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
# 创建工作目录
WORKDIR /app
# 复制应用代码
COPY transcoder.py .
COPY requirements.txt .
# 安装 Python 依赖
RUN pip3 install -r requirements.txt
# 暴露端口
EXPOSE 8080
# 设置启动命令
CMD ["python3", "transcoder.py"]
Dockerfile 指令详解
| 指令 | 作用 | 注意事项 |
|---|---|---|
FROM |
指定基础镜像 | 尽量选官方镜像,alpine 版本体积小 |
RUN |
执行命令,创建新层 | 多个命令用 && 连接,减少层数 |
COPY |
从宿主机复制文件到镜像 | 路径相对于构建上下文 |
WORKDIR |
设置工作目录 | 后续指令都在此目录下执行 |
EXPOSE |
声明容器监听端口 | 仅作文档用途,实际映射需 -p |
CMD |
容器启动时的默认命令 | 可以被 docker run 参数覆盖 |
ENV |
设置环境变量 | 运行时可通过 -e 覆盖 |
COPY . /app 写在了 WORKDIR /app 前面,结果文件复制到了根目录下的 /app,而不是工作目录。Dockerfile 的指令顺序很重要,WORKDIR 一定要在 COPY 之前。
构建与运行
# 构建镜像,-t 指定标签
docker build -t transcoder:v1 .
# 运行容器
docker run -d --name my-transcoder \
-p 8080:8080 \
-v /data/videos:/app/videos \
transcoder:v1
这里 -v 是挂载卷,把宿主机的 /data/videos 目录映射到容器内的 /app/videos。编解码处理通常涉及大量视频文件,用卷挂载比直接复制文件高效得多。
镜像分层与缓存优化
Docker 镜像采用分层存储。每个 RUN、COPY 指令都会生成一个新层。构建时如果某层没变化,Docker 会直接使用缓存。
我有个优化技巧:把不常变动的指令放在前面。比如安装系统依赖放前面,复制代码放后面。这样改代码时不用重新下载 FFmpeg,构建速度能快不少。
# 推荐写法:依赖放前面
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y ffmpeg python3
COPY requirements.txt .
RUN pip3 install -r requirements.txt
COPY . .
CMD ["python3", "app.py"]
总结一下今天的内容:
- Docker 安装后记得配镜像加速器,不然拉取慢到怀疑人生
- 镜像是只读模板,容器是运行实例,一个镜像可以启动 N 个容器
- Dockerfile 用
FROM定基础,RUN装依赖,COPY传代码,CMD定启动 - 利用分层缓存优化构建速度,把稳定层放前面