文章目录
- 前言
- 准备工作
- 步骤一:创建示例Python应用
- 步骤二:创建Dockerfile
- 步骤三:创建docker-compose.yml
- 步骤四:修改应用以使用Docker环境
- 步骤五:构建和运行容器
- 步骤六:验证环境一致性
- 步骤七:常用Docker命令
- 总结
前言
在软件开发中,最令人头疼的问题之一就是"在我机器上能跑"的环境不一致问题。Docker通过容器化技术完美解决了这一痛点。本教程将通过一个实际的Python项目,手把手教你如何使用Docker确保开发、测试和生产环境的一致性。
准备工作
- 确保已按照上一篇博客在Windows上安装好Docker Desktop
- 创建一个项目文件夹,例如
my-docker-app
步骤一:创建示例Python应用
首先,我们创建一个简单的Flask应用来演示环境问题。
- 在项目文件夹中创建
app.py文件:
python
from flask import Flask
import mysql.connector
import redis
app = Flask(__name__)
# 尝试连接MySQL(这是一个会失败的操作,因为我们没有MySQL)
@app.route('/')
def hello():
try:
# 这些连接参数在实际环境中需要根据配置变化
mysql_conn = mysql.connector.connect(
host="localhost",
user="root",
password="secret",
database="testdb"
)
mysql_status = "MySQL连接成功"
except Exception as e:
mysql_status = f"MySQL连接失败: {str(e)}"
try:
# 尝试连接Redis(同样会失败)
r = redis.Redis(host='localhost', port=6379, db=0)
redis_status = "Redis连接成功"
except Exception as e:
redis_status = f"Redis连接失败: {str(e)}"
return f"应用状态:<br/>- {mysql_status}<br/>- {redis_status}"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
-
创建
requirements.txt文件,列出项目依赖:flask==2.3.3
mysql-connector-python==8.1.0
redis==4.6.0
步骤二:创建Dockerfile
Dockerfile是定义如何构建Docker镜像的蓝图。在项目根目录创建Dockerfile文件(无扩展名):
dockerfile
# 使用官方Python运行时作为基础镜像
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 将当前目录内容复制到容器的/app目录
COPY . /app
# 安装requirements.txt中指定的包
RUN pip install --no-cache-dir -r requirements.txt
# 让容器监听5000端口
EXPOSE 5000
# 定义环境变量(在实际项目中可能会有所不同)
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
# 容器启动时运行app.py
CMD ["flask", "run"]
步骤三:创建docker-compose.yml
为了模拟真实环境,我们将使用Docker Compose来定义多容器应用。创建docker-compose.yml文件:
yaml
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
depends_on:
- db
- redis
environment:
- MYSQL_HOST=db
- MYSQL_USER=root
- MYSQL_PASSWORD=secret
- MYSQL_DB=testdb
- REDIS_HOST=redis
- REDIS_PORT=6379
db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=testdb
volumes:
- db_data:/var/lib/mysql
redis:
image: redis:7-alpine
volumes:
db_data:
步骤四:修改应用以使用Docker环境
更新app.py,使其使用环境变量而不是硬编码的连接信息:
python
from flask import Flask
import mysql.connector
import redis
import os
app = Flask(__name__)
@app.route('/')
def hello():
# 从环境变量获取配置
mysql_host = os.getenv('MYSQL_HOST', 'localhost')
mysql_user = os.getenv('MYSQL_USER', 'root')
mysql_password = os.getenv('MYSQL_PASSWORD', 'secret')
mysql_db = os.getenv('MYSQL_DB', 'testdb')
redis_host = os.getenv('REDIS_HOST', 'localhost')
redis_port = int(os.getenv('REDIS_PORT', 6379))
try:
mysql_conn = mysql.connector.connect(
host=mysql_host,
user=mysql_user,
password=mysql_password,
database=mysql_db
)
mysql_status = "MySQL连接成功"
mysql_conn.close()
except Exception as e:
mysql_status = f"MySQL连接失败: {str(e)}"
try:
r = redis.Redis(host=redis_host, port=redis_port, db=0)
r.ping() # 测试连接
redis_status = "Redis连接成功"
except Exception as e:
redis_status = f"Redis连接失败: {str(e)}"
return f"应用状态:<br/>- {mysql_status}<br/>- {redis_status}"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
步骤五:构建和运行容器
现在,让我们构建并运行整个应用栈:
- 打开 PowerShell 或命令提示符,导航到项目目录
- 运行以下命令启动所有服务:
bash
docker-compose up --build
-
Docker将执行以下操作:
- 为Web服务构建镜像
- 拉取MySQL和Redis镜像
- 启动所有容器并连接它们
-
在浏览器中访问
http://localhost:5000,你应该看到:应用状态: - MySQL连接成功 - Redis连接成功
步骤六:验证环境一致性
现在我们来证明Docker如何确保环境一致性:
-
在其他机器上测试:
- 将整个项目文件夹复制到另一台已安装Docker的电脑上
- 运行
docker-compose up --build - 应用将以完全相同的方式运行
-
在生产环境部署:
- 使用相同的Docker配置,你可以在生产服务器上部署完全相同的环境
- 无需担心操作系统差异、依赖冲突或配置问题
-
团队协作:
- 将Dockerfile和docker-compose.yml纳入版本控制
- 任何团队成员都可以使用完全相同的环境进行开发
步骤七:常用Docker命令
bash
# 查看运行中的容器
docker ps
# 查看所有容器(包括停止的)
docker ps -a
# 查看容器日志
docker logs <容器名或ID>
# 进入容器内部(调试用途)
docker exec -it <容器名或ID> /bin/bash
# 停止所有运行中的容器
docker-compose down
# 停止并删除所有容器、网络和卷
docker-compose down -v
# 在后台运行容器
docker-compose up -d
# 只构建不运行
docker-compose build
总结
通过本教程,你已经学会了如何使用Docker解决环境一致性问题:
- 环境标准化:Dockerfile定义了应用的完整运行环境,确保在任何地方构建的镜像都是相同的
- 依赖管理:所有依赖项都被明确列出并包含在镜像中,消除了"隐性依赖"问题
- 配置管理:通过环境变量管理配置,使应用能够适应不同环境而不需要修改代码
- 多服务协调:Docker Compose允许你定义和运行多容器应用,模拟复杂的生产环境
- 团队协作:Docker配置文件可以纳入版本控制,确保整个团队使用相同的开发环境
Docker的核心价值在于它提供了一种可重复、可移植的环境定义方式。无论你是在Windows、Mac还是Linux上开发,无论你的生产环境使用哪种云服务提供商,Docker都能确保你的应用以完全相同的方式运行。