Docker Compose 部署微服务:从零搭建可复现的容器化环境

配图:标题:Docker Compose 部署微服务:从零搭建可复现的容器化环

环境准备:安装与验证

在开始之前,请确保你的机器上已安装 Docker 和 Docker Compose。Docker Compose 是 Docker 官方提供的多容器编排工具,它通过一个 YAML 文件定义和运行多个容器 [来源#1]。我们首先验证安装是否成功。

docker --version
# 预期输出:Docker version 24.0.7, build afdd53b

docker compose version
# 预期输出:Docker Compose version v2.23.0

验证 Docker 和 Docker Compose 安装

如果命令未找到,请根据你的操作系统安装 Docker Desktop(Windows/Mac)或 Docker Engine(Linux)[来源#2]。安装完成后,我们创建一个项目目录来存放所有文件。

mkdir my-microservices
cd my-microservices

创建项目目录

步骤拆解:编写 docker-compose.yml

现在,我们来编写核心的 `docker-compose.yml` 文件。这个文件将定义三个服务:一个简单的 Web 应用(使用 Python Flask)、一个 PostgreSQL 数据库和一个 Redis 缓存。服务之间通过 Docker 内置的网络进行通信。

version: '3.8'

services:
  webapp:
    build: .
    ports:
      - "5000:5000"
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/appdb
      - REDIS_URL=redis://redis:6379/0
    depends_on:
      - db
      - redis
    networks:
      - app-network

  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=appdb
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app-network

  redis:
    image: redis:7-alpine
    networks:
      - app-network

volumes:
  postgres_data:

networks:
  app-network:
    driver: bridge

docker-compose.yml 文件示例

这个文件定义了三个服务:`webapp`、`db` 和 `redis`。`depends_on` 确保 Web 应用在数据库和缓存启动后才启动 [来源#1]。接下来,我们为 Web 应用创建一个简单的 Flask 程序。

from flask import Flask, jsonify
import redis
import psycopg2
import os

app = Flask(__name__)

# 连接 Redis
redis_client = redis.Redis.from_url(os.environ.get('REDIS_URL', 'redis://redis:6379/0'))

# 连接 PostgreSQL
def get_db_connection():
    conn = psycopg2.connect(os.environ.get('DATABASE_URL'))
    return conn

@app.route('/')
def index():
    # 测试 Redis
    redis_client.set('test_key', 'Hello from Redis!')
    redis_value = redis_client.get('test_key').decode('utf-8')
    
    # 测试 PostgreSQL
    conn = get_db_connection()
    cur = conn.cursor()
    cur.execute("SELECT version();")
    db_version = cur.fetchone()[0]
    cur.close()
    conn.close()
    
    return jsonify({
        'message': 'Microservice is running!',
        'redis': redis_value,
        'postgres_version': db_version
    })

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

app.py - Flask Web 应用

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

EXPOSE 5000

CMD ["python", "app.py"]

Dockerfile

Flask==2.3.3
psycopg2-binary==2.9.7
redis==5.0.1

requirements.txt

结果验证:启动与测试

一切就绪,现在启动整个环境。在 `my-microservices` 目录下执行以下命令。

docker compose up --build -d

构建并启动所有服务

这个命令会构建 Web 应用镜像,并在后台启动所有服务。预期输出会显示构建和拉取镜像的日志。启动后,使用 `docker compose ps` 查看服务状态。

docker compose ps
# 预期输出示例:
# NAME                COMMAND               SERVICE   STATUS
# my-microservices-db_1    "docker-entrypoint.she…"   db        Up 2 seconds
# my-microservices-redis_1  "docker-entrypoint.she…"   redis     Up 2 seconds
# my-microservices-webapp_1 "python app.py"            webapp    Up 2 seconds

查看服务状态

现在,我们验证 Web 应用是否正常工作,并检查它是否能连接到数据库和缓存。

curl http://localhost:5000/
# 预期输出:
# {
#   "message": "Microservice is running!",
#   "redis": "Hello from Redis!",
#   "postgres_version": "PostgreSQL 15.4 on x86_64-pc-linux-musl, compiled by gcc (Alpine 12.2.1_git20220924-r4) 12.2.1 20220924, 64-bit"
# }

测试 Web 应用端点

如果看到上述 JSON 响应,说明 Web 应用、Redis 和 PostgreSQL 都已成功启动并通信。你可以通过 `docker compose logs -f webapp` 查看应用日志,或 `docker compose down` 停止所有服务。

常见错误与排查

在部署过程中,你可能会遇到一些常见问题。这里列出三个典型错误及其解决方法。

  • 错误 1:端口冲突。如果 `5000` 端口已被占用,启动会失败。排查方法:使用 `netstat -tuln | grep 5000`(Linux/Mac)或 `netstat -ano | findstr :5000`(Windows)检查端口占用。解决方法:修改 `docker-compose.yml` 中的 `ports` 映射,例如改为 `"5001:5000"`。
  • 错误 2:服务启动顺序问题。如果 Web 应用在数据库完全就绪前尝试连接,会报连接错误。排查方法:查看 Web 应用日志 `docker compose logs webapp`,寻找类似 `psycopg2.OperationalError` 的错误。解决方法:确保 `depends_on` 正确配置,并在应用代码中添加重试逻辑(例如使用 `time.sleep` 或连接池)。
  • 错误 3:镜像构建失败。通常是因为 `Dockerfile` 中的依赖缺失或网络问题。排查方法:查看构建日志 `docker compose build --no-cache`。解决方法:检查 `requirements.txt` 是否包含所有依赖,并确保 Docker 能访问互联网拉取基础镜像。

Docker Compose 的核心价值在于用一个文件定义整个应用栈,这使得环境复现变得极其简单 [来源#2]。


通过本教程,你已经成功使用 Docker Compose 部署了一个包含 Web、数据库和缓存的微服务环境。你学会了编写 `docker-compose.yml`、管理容器生命周期以及验证服务间通信。记住,保持 `docker-compose.yml` 和相关配置文件的版本控制,是确保环境一致性的关键 [来源#1]。

参考链接

阅读剩余
THE END