Docker 容器化部署实战:从零搭建你的第一个生产级环境
·
Docker 容器化部署实战:从零搭建你的第一个生产级环境
前言
“在我机器上明明能跑啊!”
这句话大概是每个开发者都说过(或听过)的经典台词。而 Docker 的出现,正是为了彻底终结这个世纪难题。
本文将从核心概念出发,带你一步步完成一个真实项目的容器化部署,涵盖 Dockerfile 编写、镜像构建、多容器编排(Docker Compose),以及生产环境中的最佳实践。
一、Docker 到底是什么?
一句话理解
Docker 是一个轻量级的虚拟化平台,它把你的应用程序和所有依赖(运行环境、系统库、配置文件)打包成一个标准化的单元——容器(Container),保证在任何机器上都能一致运行。
容器 vs 虚拟机
| 对比维度 | 虚拟机(VM) | 容器(Container) |
|---|---|---|
| 启动速度 | 分钟级 | 秒级甚至毫秒级 |
| 资源占用 | GB 级别 | MB 级别 |
| 隔离程度 | 完全隔离(含 OS) | 进程级隔离(共享内核) |
| 镜像体积 | 数 GB | 数十 ~ 数百 MB |
| 运行密度 | 一台机器跑十几个 | 一台机器跑上百个 |
💡 简单类比:虚拟机像独栋别墅(自带地基和水电),容器像集装箱公寓(共享大楼基础设施,但各自独立)。
二、核心概念速览
在动手之前,先搞懂三个核心概念:
- 镜像(Image):只读的应用模板,包含代码 + 运行时 + 依赖,相当于"安装包"
- 容器(Container):镜像的运行实例,相当于"正在运行的程序"
- 仓库(Registry):存放和分发镜像的地方,Docker Hub 是最大的公共仓库
它们的关系:仓库 → 拉取镜像 → 运行容器
# 从仓库拉取镜像并运行容器(一条命令搞定)
docker run -d -p 8080:80 nginx
这条命令做了什么?
- 检查本地是否有
nginx镜像 → 没有则从 Docker Hub 拉取 - 以后台模式(
-d)启动容器 - 将宿主机的
8080端口映射到容器的80端口
三、实战:容器化一个 Python Flask 应用
我们从一个真实场景出发:将一个 Flask API 服务容器化部署。
3.1 项目结构
flask-app/
├── app.py # Flask 应用代码
├── requirements.txt # Python 依赖
├── Dockerfile # Docker 构建文件
└── docker-compose.yml # 多容器编排文件
3.2 应用代码
app.py
from flask import Flask, jsonify
import datetime
import os
app = Flask(__name__)
@app.route("/")
def home():
return jsonify({
"message": "Hello from Docker! 🐳",
"hostname": os.uname().nodename,
"time": datetime.datetime.now().isoformat()
})
@app.route("/health")
def health():
return jsonify({"status": "healthy"}), 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
requirements.txt
flask==3.0.0
gunicorn==21.2.0
3.3 编写 Dockerfile
Dockerfile 是构建镜像的"配方",告诉 Docker 如何一步步打包你的应用:
# 1. 选择基础镜像(Python 官方镜像,slim 版本更小)
FROM python:3.11-slim
# 2. 设置工作目录
WORKDIR /app
# 3. 先复制依赖文件,利用 Docker 缓存层加速构建
COPY requirements.txt .
# 4. 安装依赖
RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 5. 复制应用代码
COPY . .
# 6. 暴露端口(仅声明,实际映射靠 docker run -p)
EXPOSE 5000
# 7. 启动命令(使用 gunicorn 作为生产级 WSGI 服务器)
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
Dockerfile 最佳实践要点
| 实践 | 说明 |
|---|---|
| 使用 slim/alpine 基础镜像 | 体积更小,攻击面更少 |
| 先 COPY 依赖再 COPY 代码 | 依赖不变时命中缓存,加速构建 |
--no-cache-dir | 不缓存 pip 下载包,减小镜像体积 |
使用 .dockerignore | 排除 .git、__pycache__、venv 等无用文件 |
| 非 root 用户运行 | 提升安全性(下面会讲) |
创建 .dockerignore 文件:
.git
__pycache__
*.pyc
venv/
.env
3.4 构建与运行
# 构建镜像(注意最后的 . 表示构建上下文)
docker build -t flask-app:1.0 .
# 运行容器
docker run -d \
--name my-flask-app \
-p 8080:5000 \
--restart unless-stopped \
flask-app:1.0
# 验证
curl http://localhost:8080/
# 输出: {"hostname":"abc123def","message":"Hello from Docker! 🐳","time":"2026-08-15T13:25:00"}
常用参数说明:
-d:后台运行--name:给容器起个名字,方便管理-p 宿主机端口:容器端口:端口映射--restart unless-stopped:异常退出时自动重启
四、进阶:Docker Compose 多容器编排
真实项目中,你的应用通常不止一个容器——还需要数据库、缓存、消息队列等。手动管理多个 docker run 命令既不优雅也不可持续。
Docker Compose 让你用一个 YAML 文件定义和运行多容器应用。
4.1 场景:Flask + Redis + Nginx
我们用 Compose 编排三个服务:
- Flask API:业务逻辑
- Redis:缓存层
- Nginx:反向代理 + 静态资源服务
4.2 docker-compose.yml
version: "3.8"
services:
# Flask API 服务
web:
build: .
container_name: flask-app
ports:
- "5000:5000"
environment:
- REDIS_HOST=redis
- FLASK_ENV=production
depends_on:
redis:
condition: service_healthy
restart: unless-stopped
networks:
- app-network
# Redis 缓存服务
redis:
image: redis:7-alpine
container_name: redis-cache
ports:
- "6379:6379"
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
restart: unless-stopped
networks:
- app-network
# Nginx 反向代理
nginx:
image: nginx:alpine
container_name: nginx-proxy
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- web
restart: unless-stopped
networks:
- app-network
# 数据卷(持久化 Redis 数据)
volumes:
redis-data:
# 自定义网络
networks:
app-network:
driver: bridge
4.3 Nginx 配置
nginx.conf
upstream flask_backend {
server web:5000;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://flask_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
4.4 一键启动
# 启动所有服务(后台运行)
docker compose up -d
# 查看运行状态
docker compose ps
# 输出示例:
# NAME IMAGE STATUS PORTS
# flask-app flask-app:1.0 Up 5 seconds 0.0.0.0:5000->5000/tcp
# redis-cache redis:7-alpine Up 6 seconds 0.0.0.0:6379->6379/tcp
# nginx-proxy nginx:alpine Up 5 seconds 0.0.0.0:80->80/tcp
# 查看日志
docker compose logs -f web
# 停止所有服务
docker compose down
# 停止并清除数据卷
docker compose down -v
🎯 只需要一个命令
docker compose up -d,三个服务全部启动,网络互通,依赖自动排序。
五、生产环境最佳实践
5.1 镜像瘦身
# ❌ 不推荐:完整 Python 镜像,约 900MB
FROM python:3.11
# ✅ 推荐:slim 版本,约 150MB
FROM python:3.11-slim
# ✅✅ 进阶:多阶段构建,最终镜像可压缩到 50MB 以下
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
FROM python:3.11-alpine
WORKDIR /app
COPY --from=builder /install /usr/local
COPY . .
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
5.2 安全性加固
# 创建非 root 用户运行应用
RUN adduser --disabled-password --gecos '' appuser
USER appuser
5.3 健康检查
# docker-compose.yml 中添加健康检查
services:
web:
build: .
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
5.4 环境变量管理
# .env 文件(不要提交到 Git!)
FLASK_ENV=production
DATABASE_URL=postgresql://user:pass@db:5432/mydb
REDIS_URL=redis://redis:6379/0
SECRET_KEY=your-super-secret-key
# docker-compose.yml 中引用
services:
web:
env_file:
- .env
六、常用命令速查表
# ========== 镜像操作 ==========
docker build -t myapp:1.0 . # 构建镜像
docker images # 列出本地镜像
docker rmi <image_id> # 删除镜像
docker tag myapp:1.0 user/myapp:1.0 # 打标签
docker push user/myapp:1.0 # 推送到仓库
docker pull nginx:latest # 拉取镜像
# ========== 容器操作 ==========
docker run -d -p 8080:80 nginx # 运行容器
docker ps # 查看运行中的容器
docker ps -a # 查看所有容器(含已停止)
docker logs -f <container> # 查看日志
docker exec -it <container> /bin/sh # 进入容器
docker stop <container> # 停止容器
docker rm <container> # 删除容器
docker stats # 查看资源使用情况
# ========== 清理 ==========
docker system prune -a # 清理所有未使用的资源(慎用!)
docker volume prune # 清理未使用的数据卷
七、总结
| 阶段 | 关键动作 |
|---|---|
| 理解概念 | 镜像 = 模板,容器 = 实例,仓库 = 商店 |
| 编写 Dockerfile | 选小基础镜像、利用缓存层、.dockerignore |
| 构建与运行 | docker build → docker run |
| 多容器编排 | Docker Compose 一键管理 |
| 生产部署 | 镜像瘦身 + 安全加固 + 健康检查 + 环境变量管理 |
Docker 的价值不仅仅是"解决环境一致性问题",它更是现代云原生架构的基石——CI/CD 流水线、微服务部署、弹性伸缩,都离不开它。
更多推荐

所有评论(0)