保姆级教程:用Docker Compose一键部署你的第一个Web应用(附常见错误排查)

第一次接触Docker Compose时,我盯着屏幕上那几行YAML配置发呆了半小时——明明每个单词都认识,组合起来却像天书。直到成功用一条命令启动整个Web应用环境,才恍然大悟:原来容器编排可以如此优雅。本文将带你从零开始,用最直观的方式揭开Docker Compose的神秘面纱,避开那些教科书不会告诉你的"坑"。

1. 环境准备:构建你的第一个容器化Web应用

在开始编排之前,我们需要一个简单的Web应用作为实验对象。假设你已安装好Docker引擎(版本20.10+),让我们从创建一个基础的Flask应用开始:

# app.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello, Docker Compose!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

对应的Dockerfile应该这样写:

# Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]

注意:所有文件需放在同一目录下,requirements.txt需包含flask>=2.0依赖

2. 编写你的第一个docker-compose.yml

Compose文件就像乐高说明书,告诉Docker如何组装各个容器。新建docker-compose.yml文件:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/app
    environment:
      - FLASK_ENV=development
  redis:
    image: "redis:alpine"

这个配置定义了两个服务:

  • web服务:基于当前目录构建镜像,映射5000端口,挂载代码目录实现热更新
  • redis服务:直接使用官方Redis镜像作为缓存数据库

3. 一键启动与核心参数解析

在项目目录下执行魔法命令:

docker-compose up -d

这个简单的命令背后发生了这些关键操作:

参数/行为作用说明典型错误处理
-d后台运行容器不加此参数可查看实时日志
build自动构建缺失的镜像构建失败时检查Dockerfile语法
ports主机与容器端口映射端口冲突时修改左侧主机端口
volumes实现代码热重载确保路径格式正确
depends_on控制服务启动顺序不保证服务完全就绪

4. 高频错误排查手册

4.1 网络连接问题

当web服务无法访问redis时,Compose的网络特性会给你惊喜:

# 在web服务中ping redis
docker-compose exec web ping redis

Compose自动创建了专属网络,服务间可直接通过服务名通信。常见问题:

  • 连接超时:检查服务是否正常启动(docker-compose ps
  • 拒绝访问:确认redis配置了正确密码(通过environment传递)

4.2 权限与文件挂载

Linux系统下你可能遇到这类错误:

PermissionError: [Errno 13] Permission denied: '/app/instance/app.db'

解决方案:

  1. 在Dockerfile中添加用户权限处理:
    RUN useradd -m myuser && chown -R myuser /app
    USER myuser
    
  2. 或调整挂载权限:
    volumes:
      - .:/app:z
    

4.3 镜像拉取失败

当看到ERROR: pull access denied时,尝试以下步骤:

  1. 确认镜像是否存在:
    docker-compose config | grep image
    
  2. 检查私有仓库认证:
    docker login your-registry.com
    
  3. 临时使用替代镜像:
    image: redis:alpine
    # 改为
    image: bitnami/redis:latest
    

5. 生产环境优化技巧

当准备将原型部署到生产环境时,这些调整能让你的Compose配置更健壮:

services:
  web:
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000"]
      interval: 30s
      timeout: 10s
      retries: 3
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

关键优化点:

  • 资源限制:防止单个容器耗尽系统资源
  • 健康检查:自动监测服务可用性
  • 日志轮转:避免日志文件无限增长
  • 重启策略:配置restart: unless-stopped应对意外退出

6. 进阶:多环境配置管理

通过环境变量和扩展字段实现开发/生产配置切换:

# docker-compose.yml (基础配置)
x-common-env: &common-env
  REDIS_HOST: redis
  REDIS_PORT: 6379

services:
  web:
    environment:
      <<: *common-env
      DEBUG: ${DEBUG_MODE:-false}

# docker-compose.override.yml (开发环境)
services:
  web:
    environment:
      DEBUG: "true"
    ports:
      - "5000:5000"
    volumes:
      - .:/app

启动时指定配置文件:

# 开发环境(自动加载override)
docker-compose up

# 生产环境(使用prod配置)
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up

这种配置方式让我的团队在多个环境间切换时减少了90%的配置错误。记得把docker-compose.override.yml加入.gitignore,避免开发配置误提交到生产环境。

更多推荐