diff --git a/README.md b/README.md index a9049b4779..c9c37caa08 100644 --- a/README.md +++ b/README.md @@ -4,27 +4,53 @@ Test Backend Coverage +## Deploy to Render + +[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/fastapi/full-stack-fastapi-template) + +One click provisions the full stack on [Render](https://render.com) using the [`render.yaml`](./render.yaml) Blueprint at the repo root: a Dockerized FastAPI web service, a Vite/Bun static site for the frontend, a managed Postgres database, and a shared `fastapi-env` environment-variable group that both services pull from. + +### Setup after clicking the button + +1. **Fill in the secret env vars on `fastapi-backend`** (Dashboard → `fastapi-backend` → Environment): + - `FIRST_SUPERUSER` — admin email, e.g. `admin@yourdomain.com` + - `FIRST_SUPERUSER_PASSWORD` — generate one with `python -c "import secrets; print(secrets.token_urlsafe(32))"` + - Optional: `SMTP_HOST` / `SMTP_USER` / `SMTP_PASSWORD` / `EMAILS_FROM_EMAIL` (if you want password-reset emails) and `SENTRY_DSN` (if using Sentry) + + `SECRET_KEY` and all `POSTGRES_*` vars are set automatically. `ENVIRONMENT`, `PROJECT_NAME`, `STACK_NAME`, and the `SMTP_TLS/SSL/PORT` defaults come from the `fastapi-env` env group — no action needed. + + > **Note:** secrets live on the service (not the env group) because Render's env groups don't accept `sync: false` placeholders. The `fastapi-env` group only holds shared, non-secret defaults; everything secret or service-specific is set directly on `fastapi-backend` or `fastapi-frontend`. + +2. **Wait for both services to finish deploying** so they're assigned `.onrender.com` URLs. + +3. **Set the cross-service URLs on the appropriate services** (these can only be set after the first deploy, since they depend on the assigned hostnames): + - `VITE_API_URL` → set on **`fastapi-frontend`** → Environment, to the **backend** URL, e.g. `https://fastapi-backend-XXXX.onrender.com`. *Baked into the frontend bundle at build time.* + - `FRONTEND_HOST` → set on **`fastapi-backend`** → Environment, to the **frontend** URL, e.g. `https://fastapi-frontend-XXXX.onrender.com`. *Auto-appended to the backend's CORS allowlist at runtime.* + - `BACKEND_CORS_ORIGINS` → set on **`fastapi-backend`** → Environment, comma-separated list of additional allowed origins (you can usually leave this empty since `FRONTEND_HOST` already covers the frontend). + +4. **Trigger a manual rebuild of the frontend** (Dashboard → `fastapi-frontend` → Manual Deploy → Clear build cache & deploy). `VITE_API_URL` is baked into the bundle at build time, so an existing build won't pick up the new value until rebuilt. + ## Technology Stack and Features -- ⚡ [**FastAPI**](https://fastapi.tiangolo.com) for the Python backend API. - - 🧰 [SQLModel](https://sqlmodel.tiangolo.com) for the Python SQL database interactions (ORM). - - 🔍 [Pydantic](https://docs.pydantic.dev), used by FastAPI, for the data validation and settings management. - - 💾 [PostgreSQL](https://www.postgresql.org) as the SQL database. -- 🚀 [React](https://react.dev) for the frontend. - - 💃 Using TypeScript, hooks, [Vite](https://vitejs.dev), and other parts of a modern frontend stack. - - 🎨 [Tailwind CSS](https://tailwindcss.com) and [shadcn/ui](https://ui.shadcn.com) for the frontend components. - - 🤖 An automatically generated frontend client. - - 🧪 [Playwright](https://playwright.dev) for End-to-End testing. - - 🦇 Dark mode support. -- 🐋 [Docker Compose](https://www.docker.com) for development and production. -- 🔒 Secure password hashing by default. -- 🔑 JWT (JSON Web Token) authentication. -- 📫 Email based password recovery. -- 📬 [Mailcatcher](https://mailcatcher.me) for local email testing during development. -- ✅ Tests with [Pytest](https://pytest.org). -- 📞 [Traefik](https://traefik.io) as a reverse proxy / load balancer. -- 🚢 Deployment instructions using Docker Compose, including how to set up a frontend Traefik proxy to handle automatic HTTPS certificates. -- 🏭 CI (continuous integration) and CD (continuous deployment) based on GitHub Actions. +- [**FastAPI**](https://fastapi.tiangolo.com) for the Python backend API. + - [SQLModel](https://sqlmodel.tiangolo.com) for the Python SQL database interactions (ORM). + - [Pydantic](https://docs.pydantic.dev), used by FastAPI, for the data validation and settings management. + - [PostgreSQL](https://www.postgresql.org) as the SQL database. +- [React](https://react.dev) for the frontend. + - Using TypeScript, hooks, [Vite](https://vitejs.dev), and other parts of a modern frontend stack. + - [Tailwind CSS](https://tailwindcss.com) and [shadcn/ui](https://ui.shadcn.com) for the frontend components. + - An automatically generated frontend client. + - [Playwright](https://playwright.dev) for End-to-End testing. + - Dark mode support. +- [Docker Compose](https://www.docker.com) for development and production. +- Secure password hashing by default. +- JWT (JSON Web Token) authentication. +- Email based password recovery. +- [Mailcatcher](https://mailcatcher.me) for local email testing during development. +- Tests with [Pytest](https://pytest.org). +- [Traefik](https://traefik.io) as a reverse proxy / load balancer. +- Deployment instructions using Docker Compose, including how to set up a frontend Traefik proxy to handle automatic HTTPS certificates. +- CI (continuous integration) and CD (continuous deployment) based on GitHub Actions. ### Dashboard Login diff --git a/backend/scripts/start.sh b/backend/scripts/start.sh new file mode 100644 index 0000000000..4079c0c4c0 --- /dev/null +++ b/backend/scripts/start.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -e +bash scripts/prestart.sh +exec fastapi run --workers "${WEB_CONCURRENCY:-1}" --host 0.0.0.0 --port "$PORT" app/main.py diff --git a/render.yaml b/render.yaml new file mode 100644 index 0000000000..08eaaf4cd9 --- /dev/null +++ b/render.yaml @@ -0,0 +1,95 @@ +envVarGroups: + - name: fastapi-env + envVars: + - key: ENVIRONMENT + value: production + - key: PROJECT_NAME + value: "Full Stack FastAPI" + - key: STACK_NAME + value: fastapi-project + - key: SMTP_TLS + value: "true" + - key: SMTP_SSL + value: "false" + - key: SMTP_PORT + value: "587" + +projects: + - name: full-stack-fastapi-template + environments: + - name: production + services: + - type: web + name: fastapi-backend + runtime: docker + plan: free + repo: https://github.com/fastapi/full-stack-fastapi-template + branch: main + autoDeploy: true + dockerfilePath: ./backend/Dockerfile + dockerContext: . + dockerCommand: bash scripts/start.sh + healthCheckPath: /api/v1/utils/health-check/ + envVars: + - fromGroup: fastapi-env + - key: SECRET_KEY + generateValue: true + - key: POSTGRES_SERVER + fromDatabase: + name: fastapi-db + property: host + - key: POSTGRES_PORT + fromDatabase: + name: fastapi-db + property: port + - key: POSTGRES_USER + fromDatabase: + name: fastapi-db + property: user + - key: POSTGRES_PASSWORD + fromDatabase: + name: fastapi-db + property: password + - key: POSTGRES_DB + fromDatabase: + name: fastapi-db + property: database + - key: FIRST_SUPERUSER + sync: false + - key: FIRST_SUPERUSER_PASSWORD + sync: false + - key: FRONTEND_HOST + sync: false + - key: BACKEND_CORS_ORIGINS + sync: false + - key: SMTP_HOST + sync: false + - key: SMTP_USER + sync: false + - key: SMTP_PASSWORD + sync: false + - key: EMAILS_FROM_EMAIL + sync: false + - key: SENTRY_DSN + sync: false + + - type: web + name: fastapi-frontend + runtime: static + repo: https://github.com/fastapi/full-stack-fastapi-template + branch: main + autoDeploy: true + buildCommand: bun install --frozen-lockfile && bun run --filter frontend build + staticPublishPath: frontend/dist + routes: + - type: rewrite + source: /* + destination: /index.html + envVars: + - key: VITE_API_URL + sync: false + + databases: + - name: fastapi-db + databaseName: app + plan: free