Docker 解决了什么问题
经典场景:你本地跑得好好的项目,发给同事,同事说 ” 跑不起来 ”。原因是 环境不一致——Node 版本不同、系统库缺失、配置文件路径不一样。
Docker 的解决方案:把应用和它依赖的一切打包成一个 ” 容器 ”,到处运行。
核心概念(用比喻理解)
| Docker 概念 | 比喻 | 说明 |
|---|---|---|
| 镜像(Image) | 安装包 /ISO 文件 | 只读的模板,包含运行程序需要的一切 |
| 容器(Container) | 正在运行的程序 | 镜像的运行实例,互相隔离 |
| Dockerfile | 菜谱 | 描述如何构建镜像的脚本 |
| Docker Hub | 应用商店 | 公开镜像仓库,可以下载现成的镜像 |
安装 Docker
- Windows:下载 Docker Desktop(需要 WSL2 支持)
- macOS:下载 Docker Desktop
- Linux:
sudo apt install docker.io(Ubuntu)
安装完成后,终端运行:
docker --version
# 输出:Docker version 26.x.x, build xxxxx
第一个容器:Hello World
docker run hello-world
这个命令做了什么:
- 本地查找
hello-world镜像 - 没找到,去 Docker Hub 下载
- 用这个镜像启动一个容器
- 容器运行完毕后自动退出
实战:用 Docker 运行一个 Node.js 应用
步骤 1:创建 Dockerfile
# 使用官方 Node.js 镜像作为基础
FROM node:20-alpine
# 设置工作目录
WORKDIR /app
# 复制 package.json 并安装依赖
COPY package*.json ./
RUN npm install
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动命令
CMD ["node", "index.js"]
步骤 2:构建镜像
docker build -t my-node-app:1.0 .
# -t:给镜像打标签
# .:Dockerfile 所在目录
步骤 3:运行容器
docker run -d -p 3000:3000 --name my-app my-node-app:1.0
# -d:后台运行
# -p:端口映射(主机端口: 容器端口)# --name:给容器起名字
常用命令速查
# 查看运行中的容器
docker ps
# 查看所有容器(包括已停止的)docker ps -a
# 停止容器
docker stop my-app
# 启动已停止的容器
docker start my-app
# 进入容器内部(调试用)docker exec -it my-app /bin/sh
# 查看容器日志
docker logs my-app
# 删除容器
docker rm my-app
# 删除镜像
docker rmi my-node-app:1.0
# 清理所有已停止的容器
docker container prune
Docker Compose:管理多个容器
实际项目中,你往往需要同时运行:Web 应用 + 数据库 + Redis。用 Docker Compose 可以一键启动所有服务。
创建docker-compose.yml:
version: '3'
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: mypassword
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
然后一键启动:
docker-compose up -d
最佳实践
- 使用.dockerignore:类似.gitignore,避免把 node_modules 打包进镜像
- 多阶段构建:先用完整镜像构建,再用精简镜像运行,减小镜像体积
- 不要在容器中存数据:容器停止后数据会丢失,用 volume 持久化数据
- 一个容器只跑一个进程:不要在容器里同时跑 Web 服务和数据库
总结
Docker 的核心价值是 消除环境差异。学会了 Docker,你再也不用说 ” 在我机器上能跑 ” 这句话了——因为 ” 机器 ” 已经被打包进容器里了。
正文完
发表至: 技术
2026年6月6日