← Blog

Claude API Docker: Containerized Deployment Guide

2026-11-08 · 5 min read · SubToAPI Team

Containerizing an application that calls the Claude API is straightforward: you package your app code into a Docker image, inject your API key as a runtime secret (never baked into the image), and let the container make outbound HTTPS calls to the Anthropic API or a gateway in front of it. There is no "Claude API container" to pull from a registry — Claude is a hosted HTTPS service — so the Docker work is entirely about your application layer, not about running Claude itself locally.

This guide walks through a practical, production-ready pattern for containerizing a Node.js or Python service that talks to Claude: image structure, secret handling, health checks, horizontal scaling, and a docker-compose setup you can copy directly.

Why containerize a Claude API client at all

Teams containerize Claude-calling services for the same reasons they containerize anything else:

The container itself never stores Claude's model weights or does inference — it just makes HTTPS requests. Keep that mental model and the Dockerfile stays simple.

A minimal Dockerfile for a Node.js Claude client

FROM node:20-alpine AS base
WORKDIR /app

COPY package*.json ./
RUN npm ci --omit=dev

COPY . .

ENV NODE_ENV=production
EXPOSE 3000

HEALTHCHECK --interval=30s --timeout=5s \
  CMD wget -qO- http://localhost:3000/health || exit 1

CMD ["node", "server.js"]

The Anthropic/Claude API key is never copied into the image. It's injected at runtime:

docker run -d \
  -p 3000:3000 \
  -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  --name claude-service \
  my-claude-app:latest

If you're building a thinner app that only needs HTTP calls, not the full Node toolchain, a multi-stage build keeps the final image small:

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/server.js"]

A minimal Dockerfile for a Python Claude client

FROM python:3.12-slim
WORKDIR /app

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

COPY . .

ENV PYTHONUNBUFFERED=1
EXPOSE 8000

CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

Same rule applies: ANTHROPIC_API_KEY (or your provider's key env var) is passed in via -e or --env-file, never committed.

Handling secrets correctly

The most common mistake in containerized Claude deployments is leaking the API key into the image layer history. Avoid these:

Instead, use one of:

# .env file excluded from git, loaded at runtime only
docker run --env-file .env.production my-claude-app

# or Docker secrets in swarm/Kubernetes
docker secret create anthropic_key ./key.txt

In Kubernetes, mount the key as a Secret and reference it via envFrom or valueFrom.secretKeyRef rather than a ConfigMap.

docker-compose for local development

version: "3.9"
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - NODE_ENV=development
    volumes:
      - ./:/app
      - /app/node_modules
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3

Run docker compose up and the container picks up ANTHROPIC_API_KEY from your shell or a .env file sitting next to docker-compose.yml.

Scaling containers that call Claude

Once the container is running in production, the operational questions shift from "how do I build the image" to "how do I manage concurrency and retries across replicas." A few patterns that work well:

This is also where a managed gateway layer helps. Instead of having every container manage raw Anthropic credentials, retry logic, and streaming parsing itself, you can route containers through SubToAPI, which turns your existing Claude access into a standard HTTPS API with its own sub_live_... application keys, built-in streaming and tool-use support, and per-key usage metadata. Each container just gets a SUBTOAPI_KEY env var instead of raw provider credentials:

docker run -d \
  -e SUBTOAPI_KEY=$SUBTOAPI_KEY \
  -p 3000:3000 \
  my-claude-app:latest
const response = await fetch("https://api.subtoapi.app/v1/messages", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "claude-sonnet-4-5",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Summarize this deployment log" }],
  }),
});

That means key rotation, per-container quota, and team seat management happen in one dashboard rather than being scattered across every container's secret store. See the quickstart and messages docs for the full request/response shape, and pricing for plan details if you're running this across a team.

Health checks and graceful shutdown

Containers calling an external API should fail fast and report health accurately:

app.get("/health", (req, res) => {
  res.status(200).json({ status: "ok", uptime: process.uptime() });
});

Keep the health check lightweight — don't ping Claude on every health probe, since that burns quota and adds latency to Kubernetes liveness checks. A simple "process is up and responsive" check is enough; let your application-level logging and the streaming or tools endpoints handle deeper diagnostics.

questions

Do I need a special Docker image to run Claude itself? No. Claude is a hosted model accessed over HTTPS — there's no local inference container to run. You only containerize your application code that makes API calls to Claude.

Where should I store the Anthropic API key in a containerized setup? Pass it at runtime via environment variables, an --env-file, or a secrets manager (Docker secrets, Kubernetes Secret). Never hardcode it in the Dockerfile or copy a .env file containing the real key into the image.

Can multiple containers share one Claude API key safely? Yes, but you lose per-container usage visibility and risk hitting rate limits collectively. A gateway like SubToAPI with distinct application keys per service gives each container its own key and usage tracking without duplicating provider credentials everywhere.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →