Skip to main content

id: deployment-platforms

Deployment Platforms

You've built a great API. Now you need it on the internet. There are four major options for deploying Python APIs without managing your own servers.


Platform Comparison​

PlatformFree TierBest ForCold StartGPU Support
HuggingFace Spaces✅ GenerousML demos, model APIsSlow (free)✅ Yes
Render✅ LimitedLong-running APIsYes (free tier)❌ No
Railway✅ $5 creditFull-stack apps, DBs❌ No❌ No
Vercel✅ GoodServerless functions❌ No❌ No

HuggingFace Spaces​

Best for: ML model demos, model-serving APIs, anything that needs GPU.

Step-by-Step Deployment​

1. Create a Space

huggingface.co → New Space → SDK: Docker → Name: my-api

2. Project structure

code
my-api/
├── Dockerfile
├── main.py
├── pyproject.toml
└── uv.lock

3. Dockerfile for HF Spaces

HuggingFace Spaces uses port 7860 and runs as user with UID 1000:

dockerfile
Dockerfile
FROM python:3.12-slim

RUN useradd -m -u 1000 user
WORKDIR /app

RUN pip install uv

COPY --chown=user pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev

COPY --chown=user . .

USER user

EXPOSE 7860

CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]

4. README.md (required metadata)

yaml
README.md
---
title: My TDS API
emoji: 🚀
colorFrom: blue
colorTo: purple
sdk: docker
pinned: false
---

# My API

FastAPI service deployed on HuggingFace Spaces.

5. Deploy via Git

bash
# One-time setup
git remote add space https://huggingface.co/spaces/YOUR_USERNAME/my-api

# Deploy
git push space main

Your API will be live at: https://your-username-my-api.hf.space


Render​

Best for: persistent APIs, background workers, PostgreSQL databases.

Step-by-Step​

1. Create a render.yaml (Infrastructure as Code):

yaml
render.yaml
services:
- type: web
name: tds-api
runtime: python
buildCommand: pip install uv && uv sync --frozen
startCommand: uv run uvicorn main:app --host 0.0.0.0 --port $PORT
envVars:
- key: SECRET_KEY
generateValue: true # Render auto-generates a random value
- key: DATABASE_URL
fromDatabase:
name: tds-db
property: connectionString

databases:
- name: tds-db
databaseName: myapp
user: myapp

2. Connect GitHub

  • Go to render.com → New → Web Service
  • Connect your GitHub repo
  • Render auto-deploys on every git push

3. Environment Variables Set in Render dashboard → Environment tab, or via render.yaml.

Free tier limitation: Spins down after 15 minutes of inactivity. First request takes ~30 seconds (cold start).


Railway​

Best for: full-stack apps, PostgreSQL + Redis + API all in one place, no cold starts.

Step-by-Step​

bash
# Install Railway CLI
npm install -g @railway/cli

# Login
railway login

# Create project
railway init

# Add services
railway add postgresql
railway add redis

# Deploy
railway up

Or via the dashboard at railway.app:

  1. New Project → Deploy from GitHub repo
  2. Add PostgreSQL service (auto-sets DATABASE_URL in your app)
  3. Add Redis service (auto-sets REDIS_URL)
  4. Railway auto-detects Python and runs uvicorn
python
# Railway sets DATABASE_URL automatically from the PostgreSQL service
import os
DATABASE_URL = os.getenv("DATABASE_URL")

Free tier: $5 credit/month, enough for most course projects.


Environment Variables on Each Platform​

PlatformHow to Set Env Vars
HuggingFaceSpace → Settings → Repository secrets
RenderDashboard → Service → Environment
RailwayDashboard → Variables tab or railway.toml

Never commit .env to your repo. Use the platform's secrets UI.


Health Check Endpoints​

Every deployed service should have a health check:

python
@app.get("/health")
def health():
return {"status": "ok", "version": "1.0.0"}

@app.get("/ready")
async def ready(db = Depends(get_db)):
"""Check if dependencies are ready"""
try:
await db.execute("SELECT 1")
return {"status": "ready", "db": "ok"}
except Exception as e:
raise HTTPException(503, f"Not ready: {str(e)}")

Configure health checks in render.yaml:

yaml
healthCheckPath: /health

Choosing the Right Platform​

code
Need GPU for ML model?
→ HuggingFace Spaces

Need PostgreSQL + Redis + no cold starts?
→ Railway

Need long-running background jobs?
→ Render

Just a simple API, cost-conscious?
→ Render free tier or Railway free credit

Summary​

StepHuggingFaceRenderRailway
Port7860$PORT env var$PORT env var
ConfigREADME.md metadatarender.yamlrailway.toml
Deploygit pushAuto on pushrailway up or push
Free GPU✅❌❌
Persistent disk❌✅ (paid)✅