引言:为什么需要 Docker?在现代软件开发中,我们经常面临这样的困境:“在我的机器上可以运行,为什么到服务器就不行了?” 这就是经典的“环境一致性问题”。Docker 正是为解决这一痛点而生——它将应用及其依赖打包成一个轻量级、可移植的容器,确保应用在任何环境中都能以相同的方式运行。
一、Docker 核心概念解析1.1 镜像(Image)镜像是只读的模板,包含了运行应用所需的一切:代码、运行时、库、环境变量和配置文件。可以把它理解为面向对象编程中的“类”。
1.2 容器(Container)容器是镜像的运行实例。就像根据类创建的对象,容器是轻量级、可执行的独立环境。
1.3 DockerfileDockerfile 是构建镜像的脚本文件,包含了一系列指令,告诉 Docker 如何构建镜像。
代码语言:javascript复制# 简单示例
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]二、Docker 安装与配置2.1 在不同系统中安装 DockerUbuntu/Debian:
代码语言:javascript复制# 更新包索引
sudo apt-get update
# 安装依赖
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 添加 Docker 仓库
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 安装 Docker
sudo apt-get update
sudo apt-get install docker-ce验证安装:
代码语言:javascript复制docker --version
docker run hello-world2.2 配置 Docker 加速器(国内用户)代码语言:javascript复制{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
]
}三、Docker 基础操作实战3.1 镜像管理代码语言:javascript复制# 搜索镜像
docker search nginx
# 拉取镜像
docker pull nginx:latest
# 查看本地镜像
docker images
# 删除镜像
docker rmi
# 构建镜像
docker build -t myapp:1.0 .3.2 容器操作代码语言:javascript复制# 运行容器
docker run -d -p 80:80 --name my-nginx nginx
# 查看运行中的容器
docker ps
# 查看所有容器(包括停止的)
docker ps -a
# 停止容器
docker stop my-nginx
# 启动已停止的容器
docker start my-nginx
# 进入容器
docker exec -it my-nginx /bin/bash
# 查看容器日志
docker logs my-nginx
# 删除容器
docker rm my-nginx3.3 数据持久化代码语言:javascript复制# 使用数据卷
docker run -d -p 80:80 -v nginx-data:/usr/share/nginx/html nginx
# 绑定挂载(主机目录映射)
docker run -d -p 80:80 -v /host/path:/container/path nginx四、Dockerfile 最佳实践4.1 高效 Dockerfile 编写技巧代码语言:javascript复制# 多阶段构建示例 - 显著减小镜像大小
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# 生产阶段
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]4.2 安全建议代码语言:javascript复制# 使用非 root 用户
RUN addgroup -g 1001 -S appgroup && \
adduser -S appuser -u 1001 -G appgroup
USER appuser
# 定期更新基础镜像
# 最小化镜像层数
# 扫描镜像五、Docker Compose:多容器编排5.1 docker-compose.yml 示例代码语言:javascript复制version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
environment:
- NODE_ENV=production
depends_on:
- redis
volumes:
- ./app:/app
redis:
image: "redis:alpine"
volumes:
- redis-data:/data
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- web
volumes:
redis-data:5.2 Compose 常用命令代码语言:javascript复制# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 停止服务
docker-compose down
# 重新构建镜像
docker-compose build六、生产环境部署策略6.1 容器监控代码语言:javascript复制# 查看容器资源使用情况
docker stats
# 使用 cAdvisor 监控
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:ro \
--publish=8080:8080 \
--detach=true \
--name=cadvisor \
google/cadvisor:latest6.2 日志管理代码语言:javascript复制# 配置日志驱动
docker run --log-driver=json-file --log-opt max-size=10m nginx
# 使用 ELK 栈收集日志6.3 网络配置代码语言:javascript复制# 创建自定义网络
docker network create my-network
# 连接容器到网络
docker network connect my-network my-container七、常见问题排查7.1 性能问题代码语言:javascript复制# 检查容器资源限制
docker inspect
# 监控容器性能
docker stats
docker exec
# 检查端口映射
docker port
docker volume ls
# 清理无用数据
docker system prune -a八、进阶话题8.1 Docker Swarm 集群部署代码语言:javascript复制# 初始化 Swarm
docker swarm init
# 添加节点
docker swarm join --token
# 部署服务
docker service create --replicas 3 --name web nginx:latest8.2 与 Kubernetes 集成代码语言:javascript复制# 使用 kubectl 部署
kubectl create deployment nginx --image=nginx:latest
kubectl expose deployment nginx --port=80 --type=LoadBalancer九、安全最佳实践定期更新基础镜像使用最小化基础镜像(Alpine)扫描镜像(使用 Trivy、Clair 等工具)限制容器权限(避免使用 --privileged)使用只读文件系统实施网络策略结语Docker 已经彻底改变了应用部署和运维的方式。通过容器化技术,我们实现了开发与生产环境的一致性、资源的有效隔离、部署的快速可重复性。从简单的单容器应用到复杂的微服务架构,Docker 都能提供强大的支持。
记住:容器不是虚拟机,它们更轻量、启动更快、资源占用更少。正确理解和使用 Docker,将显著提升你的开发效率和系统稳定性。