Docker 入门:为什么容器化已成为现代开发标配?
你有没有遇到过这种情况:"在我电脑上明明能跑,怎么部署到服务器就报错?" 这是每个开发者都经历过的经典问题。Docker 就是为了解决这个问题而生的。
本文从零开始讲解 Docker,带你完成第一个容器化应用的部署,无需任何基础。
什么是 Docker?3 分钟理解核心概念
容器 vs 虚拟机
想象你要搬家:
- 虚拟机 = 整栋新房子,从地基到屋顶都要重建(几 GB 的操作系统)
- Docker 容器 = 打包好的集装箱,把你的东西装进去就能走,轻量快速
Docker 利用 Linux 内核的 namespace 和 cgroups 技术,让多个容器共享同一个操作系统内核,但彼此完全隔离。
三个核心概念
- 镜像(Image) — 只读的模板,类比为"菜谱"或"安装包"
- 容器(Container) — 镜像运行起来的实例,类比为"正在烹饪的菜"
- 仓库(Registry) — 存放镜像的地方,最大的是 Docker Hub
安装 Docker
Windows 安装
- 下载 Docker Desktop for Windows(官网:docker.com)
- 需要启用 WSL2(Windows Subsystem for Linux 2)
- 安装完成后,在任务栏会出现 Docker 图标
- 打开终端验证安装:
docker --version
docker run hello-world
Mac 安装
下载 Docker Desktop for Mac(支持 Intel 和 Apple Silicon)安装即可,体验和 Windows 一致。
Linux 安装
Ubuntu 系统的快速安装命令:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
你的第一个 Docker 命令
安装好之后,先跑几个命令感受一下:
拉取并运行 Nginx:
docker run -d -p 8080:80 --name my-nginx nginx
这条命令做了以下事情:
-d— 后台运行(detached 模式)-p 8080:80— 将本机 8080 端口映射到容器的 80 端口--name my-nginx— 给容器起个名字nginx— 使用官方 nginx 镜像
运行后打开浏览器访问 http://localhost:8080,你会看到 Nginx 欢迎页面!
常用容器管理命令:
# 查看运行中的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 停止容器
docker stop my-nginx
# 启动容器
docker start my-nginx
# 删除容器
docker rm my-nginx
# 查看容器日志
docker logs my-nginx
# 进入容器内部
docker exec -it my-nginx bash
编写你的第一个 Dockerfile
Dockerfile 是构建自定义镜像的"菜谱"。以一个 Node.js 应用为例:
项目结构:
my-app/
├── app.js
├── package.json
└── Dockerfile
app.js(一个简单的 Express 服务器,监听 3000 端口,返回 "Hello Docker!"):
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello Docker!');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
Dockerfile:
# 基础镜像
FROM node:20-alpine
# 设置工作目录
WORKDIR /app
# 先复制 package.json,利用 Docker 层缓存加速构建
COPY package*.json ./
RUN npm install
# 复制源代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动命令
CMD ["node", "app.js"]
构建和运行:
docker build -t my-node-app .
docker run -d -p 3000:3000 my-node-app
访问 http://localhost:3000 就能看到你的应用!
Docker Compose:多服务协同编排
真实项目通常需要多个服务(应用 + 数据库 + Redis),Docker Compose 让你用一个文件管理所有服务。
docker-compose.yml 示例(Web 应用 + MySQL + Redis):
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- DB_HOST=db
- REDIS_HOST=redis
depends_on:
- db
- redis
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: myapp
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:alpine
ports:
- "6379:6379"
volumes:
mysql_data:
一键启动所有服务:
# 启动所有服务
docker-compose up -d
# 停止所有服务
docker-compose down
Docker 在 CI/CD 中的应用
现代开发流水线离不开 Docker:
GitHub Actions 示例(自动构建推送镜像):
name: Build and Push Docker Image
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build image
run: docker build -t myapp:$GITHUB_SHA .
- name: Push to registry
run: |
docker login -u $DOCKER_USER -p $DOCKER_PASS
docker push myapp:$GITHUB_SHA
生产环境最佳实践
安全注意事项
- 不要以 root 运行容器 — Dockerfile 最后加
USER node - 使用非 latest 标签 — 固定版本如
node:20.11-alpine确保可重现 - 多阶段构建减小镜像体积 — build stage 和 runtime stage 分开
- 不要在镜像里放密钥 — 使用环境变量或 Docker secrets
镜像体积优化
- 使用 Alpine 基础镜像(5MB vs 900MB 的 Ubuntu)
- 合并 RUN 命令减少层数
- 使用
.dockerignore排除不需要的文件 - 多阶段构建(编译阶段和运行阶段分离)
数据持久化
容器是无状态的,数据需要用 Volume 持久化:
docker run -v /host/path:/container/path mysql
或在 docker-compose 中声明 named volume(如上面示例的 mysql_data)。
Docker 学习路线
- 第一周: 掌握基础命令,能拉取和运行公开镜像
- 第二周: 会写 Dockerfile,构建自己的镜像
- 第三周: 学会 Docker Compose,搭建本地开发环境
- 第四周: 了解 Docker 网络、数据卷,掌握生产部署技巧
- 进阶方向: Kubernetes 容器编排、Helm 包管理、服务网格 Istio
总结
Docker 解决了软件开发中最经典的"环境问题",学会它你会获得:
- 开发环境一致性 — 再也不用说"在我机器上能跑"
- 快速部署能力 — 一行命令启动整套服务
- 微服务架构基础 — 现代云原生应用的底层能力
- CI/CD 流水线 — 自动化测试和部署的核心工具
2025 年,Docker 已经是每个后端和全栈开发者的必备技能,而不是加分项。趁早掌握,你会感谢自己的。
如果你在实践过程中遇到问题,欢迎在评论区留言,我会尽力解答!