Self-hosted AI gateway Docker Vận hành OpenAI compatible

Self-hosted LLM API gateway: kiến trúc và vận hành

Triển khai self-hosted LLM API gateway với Docker Compose, channel đa nhà cung cấp, key giới hạn phạm vi, usage log và endpoint tương thích OpenAI.

AveMujica API 10 phút đọc

Self-hosted LLM API gateway là phần mềm bạn chạy trong mạng hoặc tài khoản cloud của mình. Nó nhận request tương thích OpenAI, xác thực caller, định tuyến traffic tới một hoặc nhiều upstream model provider, đồng thời ghi lại usage để vận hành và kiểm soát chi phí. Khác với reverse proxy thuần túy, đây là một control plane: key, model alias, channel credential, quota và request history đều nằm cạnh request path. Bài viết này giải thích khi nào self-host là lựa chọn hợp lý, kiến trúc có thể kỳ vọng từ một gateway viết bằng Go như repository này, và cách vận hành mà không biến model access thành một black box không có owner.

Nếu bạn vẫn đang chọn giữa một hop mỏng và một control plane, hãy đọc LLM proxy và AI gateway trước. Trang này giả định bạn đã cần các trách nhiệm của gateway và muốn có một baseline có thể triển khai.

Khi self-host là lựa chọn mặc định phù hợp

Hãy self-host gateway khi có ít nhất hai điều sau đúng:

  • provider API key không được phân phối tới mọi application environment
  • nhiều sản phẩm hoặc team dùng chung model access với budget khác nhau
  • bạn cần request-level log nằm trong retention boundary của mình
  • quy định về data path hoặc procurement ưu tiên hạ tầng do bạn vận hành
  • bạn muốn routing đa nhà cung cấp mà không viết lại client
  • ràng buộc của SaaS gateway về data residency, network egress hoặc change control không phù hợp

Self-host không phải lựa chọn mặc định đúng khi một prototype chỉ dùng một key, một model và không có yêu cầu audit. Trong trường hợp đó, hãy gọi provider trực tiếp hoặc dùng thin proxy cho tới khi nhu cầu control plane xuất hiện.

Kiến trúc tham chiếu

Clients (apps, agents, eval jobs)
        |
        |  HTTPS + Bearer gateway key
        v
 Self-hosted AI gateway
   - OpenAI-compatible API (/v1/chat/completions, /v1/responses, ...)
   - Admin API for users, tokens, channels
   - Usage logs, dashboard, pricing context
        |
        +--> Channel: OpenAI
        +--> Channel: Anthropic / Claude (native Messages adaptation)
        +--> Channel: Gemini
        +--> Channel: Azure / Bedrock / others
        |
        v
 Your datastore (SQLite / MySQL / PostgreSQL)
 optional Redis for cache and rate limiting

Client tiếp tục dùng OpenAI SDK hoặc raw HTTP. Sự đa dạng upstream trở thành cấu hình, không phải một SDK mới cho mỗi provider. Đây cũng là giá trị của một OpenAI-compatible API gateway, cộng thêm yêu cầu bạn tự chịu trách nhiệm về uptime và backup.

Một gateway có hình dạng như repository này thường bao gồm gì

Dự án này là một Go gateway có thể self-host và một hệ thống quản lý tài sản AI. Các năng lực nhìn thấy trong repository có ý nghĩa khi lập kế hoạch gồm:

  • endpoint relay tương thích OpenAI cho chat và các surface liên quan
  • cấu hình channel cho nhiều provider
  • quản lý user và token để giới hạn phạm vi truy cập
  • usage log và dashboard vận hành
  • web admin UI được nhúng cùng service
  • SQLite cho deployment đơn giản; MySQL hoặc PostgreSQL cho production nhiều user bền vững
  • đường triển khai dựa trên Docker với image đã phát hành calciumion/new-api

Đừng tự gán compliance certification hoặc SLA chưa được công bố. Hãy xác minh feature set chính xác cần dùng trên UI và API của phiên bản đang chạy trước khi cam kết với stakeholder.

Đường Docker tối thiểu đã được xác minh

Repository cung cấp docker-compose.yml thực tế để chạy gateway cùng PostgreSQL và Redis. Đây là điểm bắt đầu ưu tiên cho staging nhiều user. Đường nhanh từ README của dự án:

docker pull calciumion/new-api:latest
# from a checkout that includes docker-compose.yml
docker compose up -d
# gateway listens on http://localhost:3000 by default

Hình dạng service cốt lõi dưới đây được rút gọn từ compose file của repository. Hãy giữ file đầy đủ cho service Redis/Postgres, healthcheck và comment:

services:
  new-api:
    image: calciumion/new-api:latest
    container_name: new-api
    restart: always
    command: --log-dir /app/logs
    ports:
      - "3000:3000"
    volumes:
      - ./data:/data
      - ./logs:/app/logs
    environment:
      # Change passwords before any shared or production use.
      - SQL_DSN=postgresql://root:123456@postgres:5432/new-api
      - REDIS_CONN_STRING=redis://:123456@redis:6379
      - TZ=Asia/Shanghai
      - ERROR_LOG_ENABLED=true
      - BATCH_UPDATE_ENABLED=true
      - NODE_NAME=new-api-node-1
    depends_on:
      - redis
      - postgres

Các lưu ý vận hành giúp ví dụ này phản ánh đúng thực tế:

  • Mật khẩu mặc định trong compose (123456) chỉ dành cho local bring-up. Hãy thay trước mọi môi trường dùng chung hoặc production.
  • Trong môi trường regulated, ưu tiên pin image digest thay cho tag :latest trôi nổi được dùng trong tài liệu.
  • Với thử nghiệm SQLite một node, README cũng mô tả cách chạy container với volume /data được mount và không có SQL_DSN; hãy xem đây là đường footprint nhỏ, không phải production nhiều writer.
  • Đặt TLS termination tại ingress như nginx, Caddy, cloud load balancer hoặc Traefik. Không expose đường dẫn admin UI ra public internet nếu chưa có access control bổ sung.
  • Provider API key phải nằm trong channel configuration hoặc secret manager sau lần đăng nhập đầu tiên, không nằm trong git.

Nếu bạn không thể dùng nguyên trạng Docker Compose vì air-gapped registry hoặc orchestration tùy chỉnh, hãy coi snippet này là một baseline đã xác minh để chuyển đổi, không phải pseudocode tùy chọn. Image name, port, volume và biến SQL_DSN ở trên khớp với tài liệu deployment đã công bố của repository này.

Checklist cấu hình trong tuần đầu

1. Identity và key

  • tạo admin user với cơ chế xác thực mạnh
  • cấp token riêng cho từng service với model scope tối thiểu
  • tách key staging và production
  • ghi rõ ai chịu trách nhiệm rotation

2. Channel

Trong phần cấu hình channel của admin UI:

  • một channel cho mỗi upstream credential boundary
  • base URL rõ ràng cho Azure hoặc regional endpoint
  • healthcheck hoặc smoke test thủ công sau khi đổi credential
  • không bao giờ dùng chung một upstream key không giới hạn giữa các tenant đối nghịch

3. Catalog và pricing context

  • công bố model alias ổn định như claude-sonnet, gemini-flash, gpt-... để ứng dụng phụ thuộc vào
  • ánh xạ alias tới upstream ID hiện tại, ví dụ model lớp Claude Sonnet 5 / Opus 4.8 và Gemini 3.5 Flash theo danh sách provider tại thời điểm cutover
  • xem lại pricing context khi default alias thay đổi

4. Observability

  • bật usage log cho các route có tính phí
  • xác nhận đường retention và export của log
  • cảnh báo theo error rate và spend velocity, không chỉ CPU

5. Backup

  • tự động hóa database backup bằng dump PostgreSQL/MySQL hoặc volume snapshot
  • test restore trên một host trống trước sự cố thực tế đầu tiên
  • lưu encryption key của backup bên ngoài gateway container

Mô hình bảo mật cho control plane self-host

Các mối đe dọa cần thiết kế để chống lại

  • gateway key bị đánh cắp và đốt provider budget
  • admin UI bị expose trên public internet
  • prompt và tool log chứa secret của khách hàng
  • channel base URL kiểu SSRF nếu operator có thể trỏ channel vào internal metadata endpoint
  • session fixation giữa nhiều node nếu SESSION_SECRET vẫn dùng giá trị mặc định trong cluster

Các control thực sự hữu ích

  • TLS tại edge; admin access riêng tư qua VPN, SSO hoặc IP allow list
  • key riêng cho mỗi application; model allow list trên batch key
  • provider secret chỉ nằm trên gateway
  • quota cho mọi key có thể kích hoạt tool hoặc long context
  • policy redaction cho usage log export
  • đặt SESSION_SECRET cho deployment nhiều node theo comment compose trong repository

Hãy xem OWASP Top 10 for LLM Applications khi agent có thể tự động gọi tool. Self-host không loại bỏ rủi ro excessive agency; nó chỉ chuyển nơi bạn thực thi control.

Routing policy dưới dạng cấu hình

Hãy viết routing policy thành cấu hình:

  1. default model alias cho từng sản phẩm
  2. backup alias cho lỗi upstream tạm thời
  3. alias được pin cho luồng regulated hoặc nhạy với eval
  4. từ chối rõ ràng các model mà một key không bao giờ được chạm tới

Kết hợp routing với chiến lược failover LLM API để không retry ngây thơ khi lỗi xảy ra giữa stream. Với tool agent, giữ schema khả chuyển như trong gọi tool khả chuyển giữa các provider.

Capacity, database và Redis

FootprintDatabaseGhi chú
Cá nhân / team nhỏSQLiteĐơn giản, mount volume bền vững
Production nhiều teamMySQL ≥ 5.7.8 hoặc PostgreSQL ≥ 9.6Concurrency và công cụ ops tốt hơn
Đường rate-limit/cache nóngRedis tùy chọnDùng khi giới hạn trong process không đủ

Hãy tính CPU và memory từ số stream đồng thời, không từ mức dùng admin UI khi idle. Streaming response giữ connection mở; load test phải bao gồm traffic kiểu SSE nếu client có stream.

Upgrade và change management

  1. Đọc release note cho thay đổi liên quan channel và billing.
  2. Deploy lên staging với channel config giống production.
  3. Chạy curl smoke test cho /v1/chat/completions và mọi luồng dùng /v1/responses.
  4. Xác minh log ingestion và hành vi wallet/quota bằng một canary key.
  5. Roll forward với một image trước đó đã biết để rollback.
  6. Sau upgrade, kiểm tra lại model alias theo các lần upstream đổi tên.

Không bao giờ kết hợp database migration, provider credential rotation và thay đổi routing policy trong cùng một cửa sổ không giám sát.

Smoke test sau mỗi lần deploy

curl -sS https://gateway.example.com/v1/models \
  -H "Authorization: Bearer $GATEWAY_API_KEY" | head

curl -sS https://gateway.example.com/v1/chat/completions \
  -H "Authorization: Bearer $GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4.1-mini",
    "messages": [{"role": "user", "content": "ping"}],
    "max_tokens": 16
  }'

Hãy thêm một alias Claude, ví dụ claude-sonnet trỏ tới Claude ID hiện tại, và một alias Gemini, gemini-flash trỏ tới gemini-3.5-flash hoặc model kế nhiệm, nếu các channel đó nằm trong scope. Xác nhận entry xuất hiện trong usage log trước khi tuyên bố deployment healthy.

Kiểm soát chi phí mà không từ bỏ self-host

Self-host không có nghĩa là không giới hạn. Hãy cấu hình:

  • quota theo key và theo group
  • model allow list chặn flagship model trên batch key
  • cảnh báo spend velocity từ log export hoặc dashboard check
  • mặc định chạy eval job trên model rẻ hơn

Xem lại public pricing context khi default alias thay đổi. Một self-hosted gateway không trả lời được câu hỏi chi phí sẽ trở thành shared liability.

Khi nào nên chọn managed hosting

Hãy giữ managed hoặc hybrid khi:

  • bạn thiếu on-call capacity cho một dependency tier-0
  • bạn không thể đáp ứng nghĩa vụ backup/restore
  • procurement ưu tiên control plane do vendor vận hành
  • team chỉ cần một secret hop tới một provider

Application client vẫn có thể giữ tương thích OpenAI trong cả hai trường hợp. Hosting mode không nên buộc viết lại client.

Nguồn chính thức và nguồn dự án

Kiểm tra lần cuối: 2026-07-15. Hãy xác minh image tag, env var và đường dẫn UI theo đúng phiên bản bạn thực sự deploy.

Câu hỏi thường gặp

Self-hosted LLM gateway có giống tự host model không?

Không. Phần lớn self-hosted gateway vẫn gọi hosted provider API. Bạn host control plane gồm auth, routing và log, không nhất thiết host model weight. Self-host model open-weight là một GPU stack bổ sung.

Tôi có thể bắt đầu bằng SQLite rồi chuyển sang PostgreSQL không?

Có với nhiều deployment, nhưng hãy lập kế hoạch migration thay vì chỉ phát hiện lock contention trong một sự cố. Dùng SQLite cho footprint nhỏ và chuyển khi concurrent writer cùng công cụ backup đòi hỏi.

Cấu hình bảo mật khả dụng tối thiểu là gì?

TLS tại edge, admin access riêng tư, key riêng cho mỗi application, provider secret chỉ trên gateway, bật usage log, và quota cho mọi key có thể kích hoạt tool hoặc long context.

Làm sao tránh gateway trở thành single point of failure?

Khi uptime quan trọng, chạy ít nhất hai app instance sau load balancer, dùng external database, test restore và ghi rõ channel failover. Gateway phải giảm blast radius của provider outage, không tạo ra một điểm lỗi tệ hơn.

Client mới nên nhắm tới endpoint nào?

Ưu tiên root /v1 tương thích OpenAI của gateway với /v1/chat/completions để hỗ trợ client rộng. Chỉ áp dụng /v1/responses khi sản phẩm chủ động phụ thuộc vào surface đó và phiên bản gateway hỗ trợ workflow bạn cần.

Cutover staging

Deploy một staging gateway bằng compose file của repository hoặc image và SQL_DSN tương đương, cấp một key giới hạn phạm vi cho một service không critical, rồi xác minh chat completions, usage log và backup restore trước khi onboard provider thứ hai hoặc production traffic. Sau khi canary đầu tiên xanh, hãy dùng channel config, model catalog và usage history làm vòng vận hành hằng ngày.