你有没有遇到过这种情况:在我的电脑上明明运行得好好的,一到服务器上就各种报错?环境不同、依赖缺失、版本冲突…这些问题是不是让你头秃?别担心,Docker 来拯救你了!
今天我们来聊聊 Docker——这个改变了现代软件开发和部署方式的容器技术。
Docker vs 虚拟机
在深入 Docker 之前,先来对比一下它和传统虚拟机的区别。
虚拟机(VM)
- 模拟完整的操作系统,包括内核
- 每个虚拟机都有独立的 Guest OS
- 资源占用大,启动慢(分钟级)
- 隔离性强,但重量级
Docker 容器
- 共享宿主机的内核,只包含应用和依赖
- 没有 Guest OS,轻量级
- 资源占用小,启动快(秒级)
- 隔离性适中,轻量灵活
简单来说,虚拟机是”一栋房子”,而 Docker 容器是”房间里的一个柜子”。前者完整独立,后者轻巧灵活。
安装 Docker
Ubuntu/Debian
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
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
sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io
docker --version
|
CentOS/RHEL
1 2 3 4 5 6 7 8 9 10 11 12
| sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker sudo systemctl enable docker
|
macOS / Windows
直接下载 Docker Desktop 安装即可。
镜像与容器概念
Docker 有两个核心概念:
镜像(Image)
- 只读模板,包含运行应用所需的一切(代码、运行时、库、配置等)
- 类似于面向对象中的”类”
- 可以被分享和存储
容器(Container)
- 镜像的运行实例
- 类似于面向对象中的”对象”
- 可以被启动、停止、删除
1 2 3
| 镜像 (类) → 容器 (对象) class Person → Person p1 = new Person()
|
常用命令
镜像操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| docker search nginx
docker pull nginx:latest docker pull nginx:1.24
docker images docker image ls
docker rmi nginx:latest docker image rm nginx
docker build -t myapp:v1.0 .
|
容器操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| docker run nginx:latest docker run -d nginx:latest docker run -d -p 80:80 nginx:latest docker run -d -p 8080:80 --name mynginx nginx docker run -d -v /host/path:/container/path nginx
docker ps docker ps -a
docker stop mynginx docker kill mynginx
docker start mynginx
docker restart mynginx
docker rm mynginx docker rm -f mynginx
docker logs mynginx docker logs -f mynginx
docker exec -it mynginx /bin/bash docker exec -it mynginx sh
|
Dockerfile 编写
Dockerfile 是用来构建镜像的文本文件,包含了一系列构建指令。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
ENV NODE_ENV=production
CMD ["node", "app.js"]
|
常用指令说明
| 指令 |
说明 |
FROM |
指定基础镜像 |
RUN |
执行命令(如安装软件) |
COPY |
复制文件到镜像 |
ADD |
类似 COPY,但支持 URL 和自动解压 |
WORKDIR |
设置工作目录 |
ENV |
设置环境变量 |
EXPOSE |
声明容器监听的端口 |
CMD |
容器启动时执行的命令(只有最后一个生效) |
ENTRYPOINT |
容器启动入口点(不会被 CMD 覆盖) |
构建镜像
1 2 3 4 5
| docker build -t myapp:v1.0 .
|
Docker Compose 入门
当你需要同时运行多个容器(如 Web 应用 + 数据库 + 缓存),一个个手动启动太麻烦了。Docker Compose 就是用 YAML 文件定义和运行多容器应用的工具。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| version: "3.8"
services: web: build: . ports: - "3000:3000" depends_on: - db - redis environment: - NODE_ENV=production - DB_HOST=db - REDIS_HOST=redis volumes: - ./logs:/app/logs
db: image: mysql:8.0 environment: - MYSQL_ROOT_PASSWORD=secret - MYSQL_DATABASE=myapp volumes: - db-data:/var/lib/mysql ports: - "3306:3306"
redis: image: redis:7-alpine ports: - "6379:6379" volumes: - redis-data:/data
volumes: db-data: redis-data:
|
Docker Compose 常用命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| docker-compose up -d
docker-compose ps
docker-compose logs docker-compose logs -f web docker-compose logs --tail=100
docker-compose stop
docker-compose down
docker-compose down -v
docker-compose restart
docker-compose exec web sh
docker-compose up -d --build
|
实战案例:部署 Node.js 应用
假设我们有一个简单的 Express 应用:
1 2 3 4 5 6 7 8 9 10 11
| const express = require("express"); const app = express();
app.get("/", (req, res) => { res.send("Hello from Docker!"); });
app.listen(3000, () => { console.log("Server running on port 3000"); });
|
对应的 package.json:
1 2 3 4 5 6 7 8 9 10 11
| { "name": "docker-demo", "version": "1.0.0", "main": "app.js", "scripts": { "start": "node app.js" }, "dependencies": { "express": "^4.18.0" } }
|
Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12
| FROM node:18-alpine
WORKDIR /app
COPY package*.json ./ RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
|
docker-compose.yml
1 2 3 4 5 6 7 8
| version: "3.8"
services: app: build: . ports: - "3000:3000" restart: unless-stopped
|
部署步骤
1 2 3 4 5 6 7 8
| docker-compose up -d
docker-compose logs -f
curl http://localhost:3000
|
总结
Docker 通过容器化技术解决了”在我电脑上能跑”的千古难题,它带来的好处:
- 环境一致性:开发、测试、生产环境完全一致
- 快速部署:秒级启动,快速扩缩容
- 资源高效:比虚拟机轻量得多
- 版本管理:镜像可以版本化管理
- 微服务架构:每个服务独立容器,互不影响
掌握 Docker 是现代后端开发和运维的必备技能。接下来你可以:
- 学习 Docker 网络和存储
- 了解容器编排工具 Kubernetes
- 探索 CI/CD 与 Docker 的结合
- 研究多阶段构建优化镜像大小
相信我,一旦你习惯了容器化开发,就再也回不去传统方式了!