【容器化】Docker实战:从入门到生产环境部署
引言
Docker已经成为现代软件开发和部署的核心工具,它通过容器化技术实现了应用的快速交付和一致性运行。本文将详细介绍Docker的核心概念、使用方法以及在生产环境中的最佳实践。
一、Docker基础概念
1.1 容器化 vs 虚拟化
| 特性 |
Docker容器 |
传统虚拟机 |
| 隔离级别 |
进程级隔离 |
系统级隔离 |
| 资源开销 |
低(共享内核) |
高(独立内核) |
| 启动速度 |
秒级 |
分钟级 |
| 镜像大小 |
小(MB级) |
大(GB级) |
| 可移植性 |
高 |
低 |
1.2 Docker核心组件
复制代码
┌─────────────────────────────────────────────────────────────┐
│ Docker架构 │
├─────────────────────────────────────────────────────────────┤
│ Docker Client Docker Host │
│ │ │ │
│ │ REST API ▼ │
│ │────────────────► Docker Daemon │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ ▼ ▼ ▼ │
│ Images Containers Networks │
│ (只读模板) (运行实例) (网络配置) │
│ │
│ ┌──────────────────┴──────────────────┐ │
│ ▼ ▼ │
│ Docker Hub Volumes │
│ (镜像仓库) (数据持久化) │
└─────────────────────────────────────────────────────────────┘
1.3 基本命令速查
bash
复制代码
# 查看Docker版本
docker --version
# 搜索镜像
docker search nginx
# 拉取镜像
docker pull nginx:latest
# 运行容器
docker run -d -p 80:80 --name my-nginx nginx
# 查看运行中的容器
docker ps
# 查看所有容器
docker ps -a
# 停止容器
docker stop my-nginx
# 删除容器
docker rm my-nginx
# 删除镜像
docker rmi nginx:latest
# 查看容器日志
docker logs -f my-nginx
二、Dockerfile编写
2.1 Dockerfile基础结构
dockerfile
复制代码
# 指定基础镜像
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY requirements.txt .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 8000
# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# 启动命令
CMD ["python", "app.py"]
2.2 多阶段构建
dockerfile
复制代码
# 第一阶段:构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# 第二阶段:生产阶段
FROM nginx:stable-alpine
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制Nginx配置
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
2.3 最佳实践
dockerfile
复制代码
# 1. 使用多阶段构建减小镜像大小
# 2. 避免RUN命令过多(合并命令)
# 3. 使用.gitignore或.dockerignore
# 4. 选择合适的基础镜像(alpine版本更小)
# 5. 设置非root用户运行容器
FROM python:3.9-alpine
# 创建非root用户
RUN adduser -D appuser
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt && \
rm -rf /root/.cache/pip
COPY --chown=appuser:appuser . .
USER appuser
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
三、Docker Compose
3.1 docker-compose.yml示例
yaml
复制代码
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgres://db:5432/myapp
- REDIS_URL=redis://redis:6379/0
depends_on:
- db
- redis
restart: unless-stopped
db:
image: postgres:14-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=secret
restart: unless-stopped
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
restart: unless-stopped
volumes:
postgres_data:
redis_data:
3.2 常用命令
bash
复制代码
# 启动服务
docker-compose up -d
# 查看日志
docker-compose logs -f
# 停止服务
docker-compose down
# 重新构建
docker-compose up -d --build
# 查看服务状态
docker-compose ps
# 执行命令
docker-compose exec web python manage.py migrate
四、网络配置
4.1 网络模式
bash
复制代码
# 创建自定义网络
docker network create --driver bridge my-network
# 查看网络
docker network ls
# 连接容器到网络
docker network connect my-network my-container
# 断开连接
docker network disconnect my-network my-container
4.2 网络类型对比
| 网络类型 |
说明 |
适用场景 |
| bridge |
默认桥接网络 |
单机容器通信 |
| host |
使用宿主机网络 |
需要高性能网络 |
| overlay |
跨主机网络 |
Swarm集群 |
| macvlan |
虚拟MAC地址 |
需要独立IP |
五、数据持久化
5.1 数据卷
bash
复制代码
# 创建数据卷
docker volume create my-volume
# 查看数据卷
docker volume ls
# 挂载数据卷
docker run -v my-volume:/app/data nginx
# 查看数据卷详情
docker volume inspect my-volume
5.2 绑定挂载
bash
复制代码
# 挂载宿主机目录
docker run -v /host/path:/container/path nginx
# 只读挂载
docker run -v /host/path:/container/path:ro nginx
六、镜像管理
6.1 镜像构建
bash
复制代码
# 构建镜像
docker build -t my-app:1.0.0 .
# 构建时指定Dockerfile
docker build -f Dockerfile.prod -t my-app:prod .
# 多平台构建
docker buildx build --platform linux/amd64,linux/arm64 -t my-app:latest .
6.2 镜像推送
bash
复制代码
# 登录Docker Hub
docker login
# 打标签
docker tag my-app:1.0.0 username/my-app:1.0.0
# 推送镜像
docker push username/my-app:1.0.0
七、生产环境部署
7.1 安全加固
bash
复制代码
# 扫描镜像漏洞
docker scan my-app
# 使用非root用户
RUN useradd -m appuser
USER appuser
# 限制容器资源
docker run --cpus="1" --memory="512m" my-app
# 只读文件系统
docker run --read-only my-app
7.2 健康检查
dockerfile
复制代码
FROM nginx
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/health || exit 1
7.3 日志管理
bash
复制代码
# 配置日志驱动
docker run --log-driver=json-file --log-opt max-size=10m --log-opt max-file=3 my-app
八、实战案例:部署Django应用
8.1 Dockerfile
dockerfile
复制代码
FROM python:3.9-slim
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
WORKDIR /app
RUN apt-get update && apt-get install -y \
gcc \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN adduser --disabled-password --gecos '' appuser
USER appuser
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "myproject.wsgi"]
8.2 docker-compose.yml
yaml
复制代码
version: '3.8'
services:
web:
build: .
command: gunicorn myproject.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/app/staticfiles
- media_volume:/app/mediafiles
expose:
- 8000
env_file:
- .env
depends_on:
- db
db:
image: postgres:14-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- .env
nginx:
image: nginx:stable-alpine
volumes:
- static_volume:/app/staticfiles
- media_volume:/app/mediafiles
- ./nginx/conf.d:/etc/nginx/conf.d
ports:
- 80:80
depends_on:
- web
volumes:
postgres_data:
static_volume:
media_volume:
九、常见问题与解决方案
9.1 网络问题
| 问题 |
解决方案 |
| 容器无法访问外网 |
检查DNS配置,尝试--dns参数 |
| 容器间无法通信 |
使用自定义网络,确保在同一网络 |
| 端口冲突 |
使用不同端口或检查端口占用 |
9.2 存储问题
| 问题 |
解决方案 |
| 数据丢失 |
使用数据卷或绑定挂载 |
| 磁盘空间不足 |
清理无用镜像和容器 |
| 权限问题 |
使用--user参数或调整挂载权限 |
9.3 性能问题
| 问题 |
解决方案 |
| 容器启动慢 |
优化镜像大小,使用多阶段构建 |
| CPU占用高 |
限制CPU资源,优化应用代码 |
| 内存不足 |
限制内存资源,检查内存泄漏 |
十、结语
Docker容器化技术已经成为现代DevOps的基石,掌握Docker对于提高开发效率和部署一致性至关重要。本文介绍了Docker的核心概念、实践技巧和生产环境部署方案,希望能帮助你更好地使用Docker。
#Docker #容器化 #DevOps #部署