How to Deploy a Claude Code Project to Production
You built something with Claude Code. It runs locally. Now what?
This is the question thousands of indie developers are hitting in 2026. Claude Code is exceptional at generating working code fast — but once your app exists, you still need to containerize it, configure environment variables, set up a database, and get it running on a server that isn't your laptop.
This guide covers the complete path from a Claude Code project to a live production deployment, using Docker and sota.io (EU-native PaaS). No CloudFormation, no Kubernetes, no ops team required.
What Claude Code Projects Typically Look Like
Claude Code outputs runnable code — usually a Node.js/Next.js app, a Python FastAPI or Flask service, or a full-stack project with a database dependency. Common patterns:
- Next.js — the default for web apps; expects
npm run build && npm start - FastAPI / Flask — Python backends;
uvicorn main:apporgunicorn - Express / Hono — Node.js APIs;
node server.jsor similar
In all cases, Claude Code writes the code but does not configure production infrastructure. That gap — from "runs locally" to "runs in production" — is what we'll close here.
Step 1: Add a Dockerfile
Claude Code can write a Dockerfile if you ask it, but the generated output is often a single-stage development Dockerfile. For production, use a multi-stage build. Here is a production-ready template for a Next.js project:
# Stage 1: install dependencies
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
# Stage 2: build
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Stage 3: production image
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
# Non-root user for security
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]
For a Python FastAPI project:
FROM python:3.12-slim
WORKDIR /app
# System deps
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc libpq-dev && rm -rf /var/lib/apt/lists/*
# Non-root user
RUN useradd --system --create-home appuser
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY --chown=appuser:appuser . .
USER appuser
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
The key production requirements are: multi-stage builds to minimize image size, a non-root user, and no secrets baked into the image (we handle those via environment variables next).
Step 2: Add a docker-compose.yml
If your app needs a database (and most do), docker-compose.yml defines the full stack:
version: "3.9"
services:
app:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: ${DATABASE_URL}
NODE_ENV: production
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
postgres_data:
Environment variables live in a .env file (never committed to Git) or are injected by your hosting platform. Add .env to .gitignore now if it isn't already there.
Step 3: Handle Environment Variables
Claude Code projects often have hardcoded values in local dev. Before deploying, identify every secret and config value that changes between environments:
# .env.example — commit this, not .env
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
NEXTAUTH_SECRET=your-secret-here
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
On sota.io, you set these through the dashboard or CLI at deploy time — they are injected as environment variables and never stored in your image.
Step 4: Deploy to sota.io
sota.io is an EU-native PaaS designed for exactly this workflow: you have a Docker project, you want it live in minutes, and you need GDPR-compliant EU infrastructure.
Install the CLI:
npm install -g @sota/cli
Log in and deploy:
sota login
sota deploy --name my-claude-app
sota.io detects your Dockerfile and docker-compose.yml automatically. For the database, you can provision a managed PostgreSQL instance in the same command:
sota deploy --name my-claude-app --postgres
This creates a managed PostgreSQL instance in Germany, injects DATABASE_URL into your environment, and gives you a live HTTPS endpoint — typically in under 2 minutes.
Set environment variables via CLI:
sota env set ANTHROPIC_API_KEY=sk-ant-...
sota env set NEXTAUTH_SECRET=your-production-secret
Or via the dashboard under Project → Environment Variables.
Step 5: Configure the Claude Code MCP Server (Optional)
If your app uses Claude Code as an ongoing development tool — not just to generate initial code, but to iterate in production — sota.io ships a native MCP server. This means you can deploy updates from within Claude Code without leaving your editor:
# Add sota.io MCP server to Claude Code
claude mcp add sota
Once configured, you can say things like "deploy the latest changes to my-claude-app on sota.io" from within a Claude Code session and it executes the deploy without switching context.
This is the key advantage for vibe coders: you build with Claude Code, you deploy with Claude Code, and the whole workflow stays in one place.
Why EU Hosting Matters for Claude Code Projects
Most Claude Code projects eventually handle user data. If those users are in Europe — and if you're reading this, they probably are — GDPR applies from day one.
The relevant requirements for your hosting infrastructure:
- Data residency: personal data must be stored within the EU (or transferred under appropriate safeguards)
- Processor contracts: your hosting provider must sign a Data Processing Agreement (DPA)
- CLOUD Act exposure: US-parent hosting providers (AWS, Azure, GCP, Vercel, Railway) carry structural legal uncertainty even when data centers are in the EU
sota.io is incorporated and operated in Germany. No US parent company, no CLOUD Act exposure, no sovereignty surcharge. DPA available on request. For a Claude Code project that handles EU user data, this is the lowest-friction path to compliance.
The EU AI Act's Annex III enforcement deadline is 2 August 2026. If your Claude Code project involves AI features — recommendations, classification, CV screening, credit scoring — the infrastructure jurisdiction question will be on your compliance checklist.
Common Issues and Fixes
Build fails: Cannot find module
Your Dockerfile COPY context is wrong. Make sure your docker build context includes all required source files. If you use a monorepo, specify the context path: docker build -f apps/web/Dockerfile .
Database connection refused
Your app is starting before the database is ready. Add a depends_on with condition: service_healthy and a healthcheck to your compose file (as shown above).
Environment variable undefined in production
You likely have it in .env locally but haven't set it on sota.io. Run sota env list to audit what's set.
Image too large (>1GB) You're using a single-stage Dockerfile with dev dependencies included. Switch to the multi-stage build shown above. A production Next.js image should be under 200MB.
The Full Workflow in One View
Claude Code generates app
↓
Add Dockerfile (multi-stage, non-root)
↓
Add docker-compose.yml (app + db + healthchecks)
↓
Move secrets to .env (never commit)
↓
sota deploy --name my-app --postgres
↓
sota env set KEY=value
↓
Live HTTPS endpoint, EU-native, GDPR-compliant
From Claude Code output to a live EU production deploy: roughly 20 minutes the first time, under 2 minutes for subsequent deploys.
Summary
Claude Code accelerates the build phase dramatically, but the deployment gap is real. The key steps are: add a production Dockerfile (multi-stage, non-root), add a docker-compose.yml for the full stack, extract secrets to environment variables, and deploy to EU-native infrastructure that handles TLS, scaling, and GDPR compliance without additional configuration.
sota.io is built for this exact workflow. Free tier available — deploy your Claude Code project now.
Further reading: Railway Alternative: EU Hosting · Render Alternative: EU Hosting · AWS European Sovereign Cloud — Developer Analysis