Docker 是什么,为什么开发人员应该学习它?
Docker 实战指南:容器与虚拟机的对比、核心命令、Dockerfile 以及如何在真实项目中使用它。
Docker 不断出现在招聘信息和设置指南中,如果你从未接触过容器,它可能会让你感到像是在写真正的代码之前必须跨越的一堵墙。一旦你理解了术语,就没那么复杂了。
容器实际上是什么
容器将你的应用程序与它运行所需的一切打包在一起:代码、运行时、系统库和配置文件。它不是虚拟机。虚拟机虚拟化整个操作系统,包括内核,这意味着启动一个虚拟机可能需要一分钟并消耗几个 GB 的 RAM。容器共享主机的内核,仅隔离进程,所以它在不到一秒内启动,通常只使用数十 MB 而不是 GB 的内存。
这种差异正是 Docker 为什么能那么快地占领本地开发和 CI 管道。你可以在一台笔记本电脑上启动 Postgres 数据库、Redis 缓存和应用服务器,而无需在操作系统上直接安装它们。
你需要知道的核心概念
有四个术语涵盖了你日常处理的大部分内容:
- Image(镜像):从 Dockerfile 构建的只读模板。可以把它看作是文件系统的快照加上关于如何运行它的元数据。
- Container(容器):镜像的一个运行中的实例。你可以启动、停止和删除容器,而不影响它们来自的镜像。
- Dockerfile:一个文本文件,包含逐行构建镜像的指令。
- Registry(仓库):存储和拉取镜像的地方,最常见的是 Docker Hub。
Node.js 应用的最小化 Dockerfile 看起来是这样的:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
使用 docker build -t my-app . 构建它,然后用 docker run -p 3000:3000 my-app 运行它。-p 标志将你机器上的一个端口映射到容器内的一个端口,这是你从浏览器中实际访问应用的方式。
你会不断使用的命令
少数几个命令涵盖了大部分日常工作:
docker ps— 列出正在运行的容器docker ps -a— 列出所有容器,包括已停止的docker images— 列出你机器上的镜像docker logs <container>— 查看运行中或已崩溃的容器的输出docker exec -it <container> sh— 在运行中的容器内打开一个 shelldocker rm/docker rmi— 清理不再需要的容器和镜像
最后这一对比人们想象的更重要。Docker 会乐于看着磁盘空间消失在旧镜像和已停止的容器中。偶尔运行 docker system prune 可以回收大量磁盘空间。
为什么 docker-compose 改变了工作流程
大多数真实项目需要不止一个容器:应用服务器、数据库,也许还有缓存。为每个容器写出 docker run 命令会很快变得乏味。docker-compose.yml 让你在一个文件中定义整个栈:
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: devpassword
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
运行 docker compose up,两个服务会一起启动,并进行网络连接,所以 web 可以通过服务名称访问 db。这是你在几乎每个开源仓库的 README 中看到的设置,理解它意味着你可以在几分钟内克隆一个项目并让它运行,而不是手动安装 Postgres、Redis 和应用需要的其他任何东西。
初期容易踩的坑
卷(volumes)一开始会让几乎所有人感到困惑。没有卷的情况下,在容器内写入的任何东西在容器被移除时都会消失,这对数据库来说是个问题。上面 compose 文件中的 volumes 部分将一个命名卷映射到容器内的一个路径,所以数据在重启后仍然存在。
另一个常见的错误是因为没有 .dockerignore 文件就把 node_modules 或 .git 复制到镜像中。添加一个,就像 .gitignore 一样:
node_modules
.git
.env
这可以让构建更快,镜像更小,一旦你开始将镜像推送到仓库或部署到 Kubernetes,这就变得很重要。
掌握基础后的下一步
一旦构建和运行容器感觉正常了,下一个有用的技能是用于构建更小生产镜像的多阶段构建、理解 Docker 网络模式,以及当某些东西无法连接时读懂 docker inspect 输出。这些都不难,只是第一次接触时不太熟悉。
如果想了解更多关于容器化真实应用以及将它们连接到云部署管道的内容,请查看 Korra Studio 上的 DevOps 和 Cloud 部分。
本文由人工智能协助撰写,经 Michal Pilch(CISSP)审核并发布,Korra Studio。
这是来自 Korra Studio 知识库的笔记之一——该平台将每个主题与一对一指导相结合。
免费开始arrow_forward