Example FastAPI app with a full CI/CD pipeline via GitHub Actions: separate workflows for tests, linting, Docker build/push, and deploy triggers for Render, Vercel, and Fly.io.
Simple app defined in app/main.py.
Run locally:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000Endpoints:
GET /returns greeting JSONGET /healthreturns status JSON
Workflow: .github/workflows/tests.yml runs pytest.
Manual run locally:
pip install -r requirements.txt pytest
pytestWorkflow: .github/workflows/lint.yml runs Ruff.
Add Ruff locally:
pip install ruff
ruff check .Dockerfile builds the service.
Build locally:
docker build -t ghcr.io/<owner>/<repo>:local .Run container:
docker run --rm -p 8000:8000 ghcr.io/<owner>/<repo>:localWorkflow .github/workflows/docker-build.yml builds and pushes ghcr.io/<owner>/<repo>:latest.
You can enable any provider by adding required secrets.
- Create a Render Web Service from repo or specify Docker.
- Obtain Deploy Hook URL from Render dashboard.
- Add secret
RENDER_DEPLOY_HOOK_URL. Workflow:.github/workflows/deploy-render.yml.
- Create Vercel project.
- Add secrets:
VERCEL_TOKEN,VERCEL_ORG_ID,VERCEL_PROJECT_ID. Workflow:.github/workflows/deploy-vercel.yml. For Python FastAPI on Vercel you typically wrap with serverless adapter or use edge functions; consider a separatevercel.json.
- Install flyctl locally:
brew install flyctl. - Run
flyctl launchto createfly.toml(add it to repo) and choose internal port 8000. - Set secret
FLY_API_TOKEN. Workflow:.github/workflows/deploy-fly.yml.
Example fly.toml (create this after flyctl launch):
app = "your-app-name"
[build]
image = "ghcr.io/<owner>/<repo>:latest"
[env]
PORT = "8000"
[http_service]
internal_port = 8000
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 1All workflows trigger on push to main. You can refine:
- Run tests + lint on PR only.
- Run docker build after merge.
- Run deploy workflows only on tagged releases using:
on:
push:
tags:
- 'v*'Add via repo Settings -> Secrets and variables -> Actions:
RENDER_DEPLOY_HOOK_URLVERCEL_TOKENVERCEL_ORG_IDVERCEL_PROJECT_IDFLY_API_TOKEN
- Add caching (pip cache) to speed builds.
- Add matrix strategy for multiple Python versions in tests.
- Add Snyk or Trivy scan step in Docker workflow.
- Code pushed -> tests + lint run.
- If merged to main -> docker image built/pushed.
- Deploy workflows trigger provider updates using latest image or source.
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt pytest ruff
ruff check .
pytest
uvicorn app.main:app --reload --port 8000