使用Docker Compose编排Qwen3-0.6B-FP8与周边服务

如果你已经用Docker跑过几个AI模型,可能会发现一个问题:模型服务本身跑起来了,但想给它加个缓存、存点日志、或者看看性能指标,就得再手动去折腾一堆别的容器。每次启动都要敲一串命令,管理起来挺麻烦的。

今天咱们就来解决这个痛点。我手把手带你,用一份docker-compose.yml文件,把Qwen3-0.6B-FP8模型服务,连同它常用的几个“小伙伴”——Redis、PostgreSQL和Prometheus,一次性全给编排起来。目标是让你得到一个开箱即用、功能完整、还方便监控和维护的AI应用栈。以后想启动或停止整个服务,只需要两个简单的命令。

1. 开始之前:你需要准备什么

在动手写代码之前,我们先看看需要哪些准备。放心,要求不高。

首先,你手头的机器最好有8GB以上的可用内存。Qwen3-0.6B-FP8这个模型本身比较轻量,但加上几个周边服务,留点余量总没错。其次,需要安装好Docker和Docker Compose。如果你已经能用docker run命令拉取镜像和运行容器,那基础环境就没问题了。

至于知识储备,你只需要对Docker的基本概念(镜像、容器、卷)和Docker Compose的用途有个大致了解就行。本篇的重点是“编排”,也就是如何让多个服务协同工作,而不是深入每个服务的配置细节。

最后,给自己准备一个干净的目录,比如叫做qwen3-stack。我们所有的配置文件都会放在这里面。

2. 理解我们的服务蓝图

在写配置之前,我们先画个简单的蓝图,搞清楚各个服务扮演什么角色,以及它们之间怎么“对话”。

整个应用栈的核心当然是Qwen3-0.6B-FP8模型服务。它提供一个HTTP API,我们发送文本给它,它返回生成的文本结果。

为了提高响应速度,我们引入Redis作为缓存层。想象一下,如果很多用户都问“你好吗?”,模型每次都要重新计算一遍,挺浪费资源的。我们可以把第一次的问答结果存到Redis里,下次遇到相同问题,直接返回缓存的结果,又快又省力。

然后,我们需要记录日志,比如谁在什么时候调用了服务、请求内容是什么、模型响应耗时多久。这些日志如果只是打印在控制台,容器一重启就没了。所以我们用PostgreSQL数据库来持久化存储这些日志信息,方便以后查询和分析。

光有日志还不够,我们还想实时了解服务的“健康状况”:当前有多少请求?平均响应时间是多少?服务有没有崩溃?Prometheus就是干这个的,它会持续地从模型服务中“抓取”这些指标数据。而Grafana(通常和Prometheus搭配)则用来把枯燥的数据变成直观的图表仪表盘。

所以,数据流向是这样的:用户请求先到模型服务;模型服务会先问问Redis有没有缓存;处理完后,把日志写到PostgreSQL,同时把指标暴露给Prometheus采集。

3. 编写Docker Compose编排文件

现在,我们进入核心环节,创建docker-compose.yml文件。我会分块解释,你可以跟着一步步来。

3.1 定义项目与网络

首先,我们指定一下Compose的版本,并定义一个自定义网络。让所有服务都连接到同一个自定义网络里,它们之间就可以直接用服务名互相访问了,非常方便。

version: '3.8'

networks:
  ai-stack-net:
    driver: bridge

volumes:
  postgres_data:
  prometheus_data:
  grafana_data:

我们定义了三个“卷”(volumes),分别用于持久化PostgreSQL的数据、Prometheus的时序数据以及Grafana的配置和仪表盘数据。这样即使容器删除,数据也不会丢失。

3.2 配置模型服务

这是最复杂的一部分,我们仔细看看。

services:
  qwen-model:
    image: qwenllm/qwen3-0.6b-fp8:latest
    container_name: qwen3-0.6b-fp8-service
    restart: unless-stopped
    ports:
      - "8000:8000"
    volumes:
      - ./model_cache:/root/.cache/huggingface
    environment:
      - MODEL_NAME=qwen3-0.6b-fp8
      - MAX_SEQ_LENGTH=4096
      - DEVICE=cuda  # 如果你的环境支持GPU
      # - DEVICE=cpu  # 如果使用CPU
    networks:
      - ai-stack-net
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    depends_on:
      redis:
        condition: service_healthy
      postgres:
        condition: service_healthy

这里有几个关键点:

  1. 端口映射:我们把容器内的8000端口映射到了主机的8000端口,这样你就能通过http://localhost:8000访问模型API了。
  2. 数据卷挂载./model_cache:/root/.cache/huggingface 这行把宿主机的model_cache目录挂载到容器内模型缓存的位置。首次运行下载的模型文件会保存在这里,下次启动就不用重新下载了。
  3. 环境变量:我们设置了模型名称、最大序列长度和设备。如果你有NVIDIA GPU并安装了对应的Docker运行时,使用DEVICE=cuda会快很多。否则,就改成DEVICE=cpu
  4. 健康检查:我们让Docker定期检查/health端点,确保模型服务是正常运行的。这在多服务依赖时很重要。
  5. 依赖关系:通过depends_on,我们告诉Docker Compose,模型服务需要等待Redis和PostgreSQL都健康启动后,再启动自己。

3.3 配置缓存服务 (Redis)

Redis的配置相对简单。

  redis:
    image: redis:7-alpine
    container_name: ai-stack-redis
    restart: unless-stopped
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
    ports:
      - "6379:6379"
    networks:
      - ai-stack-net
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

我们使用了轻量级的Alpine版本镜像。command参数里做了几件事:开启数据持久化(appendonly yes),限制最大内存为256MB,并设置当内存满时,淘汰最近最少使用的键(allkeys-lru)。这能防止Redis占用过多内存。

3.4 配置日志存储服务 (PostgreSQL)

我们用PostgreSQL来存结构化日志。

  postgres:
    image: postgres:15-alpine
    container_name: ai-stack-postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: aiadmin
      POSTGRES_PASSWORD: aisecurepassword
      POSTGRES_DB: ailogdb
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5432:5432"
    networks:
      - ai-stack-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U aiadmin"]
      interval: 10s
      timeout: 5s
      retries: 5

这里我们预设了用户名、密码和数据库名。注意,我们把名为postgres_data的卷挂载到了数据库的数据目录,实现了数据持久化。

还有一个亮点是./init.sql:/docker-entrypoint-initdb.d/init.sql。这行配置会把宿主机当前目录下的init.sql文件,在PostgreSQL容器首次启动时自动执行。我们可以用这个文件来创建日志表。

你需要创建一个init.sql文件:

-- init.sql
CREATE TABLE IF NOT EXISTS request_logs (
    id SERIAL PRIMARY KEY,
    timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    client_ip VARCHAR(45),
    request_text TEXT,
    response_text TEXT,
    response_time_ms INTEGER,
    cache_hit BOOLEAN DEFAULT FALSE
);

这张表记录了每次请求的时间、客户端IP、请求和响应文本、耗时以及是否命中了缓存。

3.5 配置监控服务 (Prometheus & Grafana)

监控部分我们部署两个服务。

  prometheus:
    image: prom/prometheus:latest
    container_name: ai-stack-prometheus
    restart: unless-stopped
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
    ports:
      - "9090:9090"
    networks:
      - ai-stack-net

  grafana:
    image: grafana/grafana-oss:latest
    container_name: ai-stack-grafana
    restart: unless-stopped
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana
    ports:
      - "3000:3000"
    networks:
      - ai-stack-net
    depends_on:
      - prometheus

Prometheus需要一份配置文件来告诉它去哪里抓取指标。我们创建一个prometheus.yml

# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'qwen-model'
    static_configs:
      - targets: ['qwen-model:8000'] # 使用Docker服务名
    metrics_path: '/metrics' # 假设模型服务在此路径暴露指标

这样,Prometheus就会每15秒去访问qwen-model:8000/metrics来获取数据。Grafana的初始管理员密码我们设为了admin

4. 启动与验证你的完整应用栈

好了,所有配置文件都齐了。你的项目目录现在应该看起来像这样:

qwen3-stack/
├── docker-compose.yml
├── init.sql
└── prometheus.yml

打开终端,进入这个目录,执行一个魔法般的命令:

docker-compose up -d

-d参数是让服务在后台运行。Docker Compose会按照我们定义的依赖关系,依次拉取镜像、创建网络和卷,并启动所有服务。第一次运行可能会花几分钟时间下载镜像。

启动完成后,你可以用下面这个命令查看所有容器的状态:

docker-compose ps

如果一切顺利,你应该看到所有服务的状态都是“Up”。现在,我们来验证一下各个服务是否工作正常。

  1. 测试模型API:打开浏览器或使用curl命令。

    curl -X POST http://localhost:8000/v1/completions \
      -H "Content-Type: application/json" \
      -d '{
        "prompt": "你好,请介绍一下你自己。",
        "max_tokens": 100
      }'
    

    你应该能收到一段来自Qwen3-0.6B-FP8模型的自我介绍文本。

  2. 检查PostgreSQL日志表:进入PostgreSQL容器查看日志是否写入。

    docker exec -it ai-stack-postgres psql -U aiadmin -d ailogdb
    

    psql命令行中,执行:

    SELECT * FROM request_logs LIMIT 5;
    

    如果模型服务已经正确集成了日志写入功能,这里就能看到记录。

  3. 访问监控面板

    • Prometheus: 打开浏览器访问 http://localhost:9090。在“Status” -> “Targets”页面,应该能看到qwen-model的状态是“UP”。
    • Grafana: 访问 http://localhost:3000,用admin/admin登录。你需要添加Prometheus(地址填http://prometheus:9090)作为数据源,然后就可以创建漂亮的监控仪表盘了。

5. 日常管理与扩展建议

服务跑起来之后,日常管理就很简单了。

  • 停止所有服务docker-compose down
  • 停止并删除所有数据(卷)docker-compose down -v (谨慎使用!)
  • 查看实时日志docker-compose logs -f qwen-model (可以替换服务名)
  • 重启某个服务docker-compose restart qwen-model

关于扩展,这个编排文件已经为你打好了基础:

  • 增加服务:如果你想加一个消息队列(比如RabbitMQ)来做请求缓冲,只需要在docker-compose.ymlservices下新加一段配置,并把它加入到同一个网络ai-stack-net即可。
  • 配置分离:目前密码等配置是直接写在了文件里。在生产环境,你应该使用Docker的env_file功能或Docker Secrets来管理敏感信息。
  • 模型服务集成:本文假设模型服务镜像已经内置了连接Redis、PostgreSQL和暴露Prometheus指标的功能。如果你的模型服务还没有这些功能,你需要在其应用代码中集成相应的客户端库(如redis-pypsycopg2prometheus_client),并确保它连接到我们定义的服务名(如redispostgres)。

6. 总结

走完这一趟,你应该已经拥有了一个由Docker Compose统一管理的、包含模型推理、缓存、日志和监控的完整AI服务栈。它最大的好处就是“一键启停”和“统一管理”,把原本需要手动维护多个独立容器的繁琐工作,变成了对一个声明式配置文件的维护。

这种编排方式特别适合开发和测试环境,能快速搭建出一套标准化的环境。当你需要迁移到生产环境时,这份docker-compose.yml文件也是一个非常好的部署蓝图和配置参考。你可以基于它,进一步探索如何集成更复杂的网络设置、负载均衡或者使用Kubernetes进行容器编排。下次再想启动一个带生态的AI服务,就不用从头开始了,这份文件就是你的起点。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐