保姆级教程:用Docker Compose一键部署你的第一个Web应用(附常见错误排查)
保姆级教程:用Docker Compose一键部署你的第一个Web应用(附常见错误排查)
当你第一次听说Docker时,可能觉得它像某种魔法——把应用和它的运行环境打包在一起,无论在哪都能一键运行。但真正动手部署时,那些晦涩的命令行参数和突如其来的报错信息,往往让初学者望而却步。本文将带你用最直观的方式,从零开始部署一个真实的Web应用,过程中遇到的每个坑我都替你踩过一遍了。
1. 环境准备:从零搭建Docker游乐场
在开始之前,确保你的开发机已经安装好以下工具。如果是Windows/macOS用户,建议直接安装Docker Desktop,它会自动包含我们需要的所有组件:
# 检查Docker和Compose版本
docker --version
docker-compose --version
常见安装问题解决方案:
- 如果遇到权限问题,记得将当前用户加入docker组:
sudo usermod -aG docker $USER - 国内用户推荐配置镜像加速器,在
/etc/docker/daemon.json中添加:{ "registry-mirrors": ["https://registry.docker-cn.com"] }
提示:所有命令行操作建议在项目根目录下进行,本文示例代码都假设你已创建专用项目文件夹。
2. 构建第一个容器化的Web应用
我们从最简单的Python Flask应用开始,这个微型应用只包含一个显示欢迎页面的路由。创建app.py文件:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "<h1>我的第一个Docker应用正在运行!</h1>"
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)
接着编写Dockerfile,这是构建容器镜像的配方文件:
# 使用官方Python轻量级镜像
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 先复制依赖声明文件(利用Docker缓存层)
COPY requirements.txt .
RUN pip install -r requirements.txt
# 再复制应用代码
COPY . .
# 声明暴露端口
EXPOSE 5000
# 启动命令
CMD ["python", "app.py"]
创建requirements.txt文件只需一行内容:
Flask==2.0.1
现在可以构建镜像了:
docker build -t my-webapp .
3. 使用Compose编排多容器服务
真实的Web应用通常需要多个服务协同工作。我们通过docker-compose.yml文件定义整个应用栈:
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
environment:
- FLASK_ENV=development
volumes:
- .:/app
depends_on:
- redis
redis:
image: "redis:alpine"
ports:
- "6379:6379"
这个配置定义了两个服务:
- web服务:基于我们刚构建的Flask应用
- redis服务:使用官方Redis镜像作为缓存层
关键参数解析:
| 参数 | 作用 | 典型值示例 |
|---|---|---|
| build | 指定构建上下文 | . (当前目录) |
| ports | 端口映射 | 主机端口:容器端口 |
| volumes | 目录挂载 | 主机路径:容器路径 |
| depends_on | 服务依赖 | 依赖的服务名 |
启动整个应用栈只需一行命令:
docker-compose up -d
4. 实战问题排查手册
即使按照教程操作,仍可能遇到各种环境问题。以下是经过验证的解决方案:
问题1:端口已被占用
ERROR: for web Cannot start service web: driver failed programming external connectivity on endpoint web (...): Error starting userland proxy: listen tcp4 0.0.0.0:5000: bind: address already in use
解决方案:
- 查找占用端口的进程:
sudo lsof -i :5000 - 终止该进程或修改compose文件中的端口映射
问题2:镜像拉取失败
ERROR: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
解决方案:
- 检查DNS设置:
nslookup registry-1.docker.io - 临时使用国内镜像源:
docker pull registry.docker-cn.com/library/redis:alpine
问题3:容器权限问题
redis: Can't open the append-only file: Permission denied
解决方案:
- 在compose文件中添加用户声明:
redis: user: "1000:1000" volumes: - redis_data:/data
问题4:修改代码后变化未生效 解决方案:
- 确保compose中配置了volume挂载
- 重启服务:
docker-compose restart web - 或者完全重建:
docker-compose up -d --build
5. 进阶技巧:提升开发体验
热重载配置: 修改compose文件中web服务的配置:
web:
environment:
- FLASK_ENV=development
volumes:
- .:/app
command: ["flask", "run", "--host=0.0.0.0", "--port=5000", "--reload"]
日志查看技巧:
- 跟踪实时日志:
docker-compose logs -f web - 过滤错误日志:
docker-compose logs web | grep -i error - 查看特定时间段的日志:
docker-compose logs --since 10m web
资源监控:
# 查看容器资源占用
docker stats
# 进入容器内部
docker-compose exec web bash
清理命令备忘:
# 停止并删除所有容器
docker-compose down
# 删除未使用的镜像
docker image prune
# 彻底清理所有缓存
docker system prune -a
在实际项目中使用这套配置几个月后,我发现最实用的功能是docker-compose up -d --build这条命令——它能在保持服务运行的同时重建更新的镜像。当需要调试时,docker-compose exec web bash让我能像操作普通服务器一样进入容器内部检查运行状态。
更多推荐



所有评论(0)