mirror of
https://github.com/fastapi/full-stack-fastapi-template.git
synced 2026-09-23 22:22:23 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84c5a9e11a | ||
|
|
98fb606b57 | ||
|
|
de2ed05b10 | ||
|
|
ec86250a21 | ||
|
|
7f11815e43 | ||
|
|
a2d2d18108 | ||
|
|
2d8fb3e4de |
@@ -1,7 +1,6 @@
|
|||||||
.git
|
.git
|
||||||
**/__pycache__
|
**/__pycache__
|
||||||
**/.venv
|
**/.venv
|
||||||
backend/app/frontend
|
|
||||||
backend/htmlcov
|
backend/htmlcov
|
||||||
frontend/blob-report
|
frontend/blob-report
|
||||||
frontend/dist
|
frontend/dist
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
.env
|
||||||
|
!backend/app/frontend/
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
docs:
|
|
||||||
- all:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file:
|
|
||||||
- '**/*.md'
|
|
||||||
- all-globs-to-all-files:
|
|
||||||
- '!frontend/**'
|
|
||||||
- '!backend/**'
|
|
||||||
- '!.github/**'
|
|
||||||
- '!scripts/**'
|
|
||||||
- '!.gitignore'
|
|
||||||
- '!.pre-commit-config.yaml'
|
|
||||||
|
|
||||||
internal:
|
|
||||||
- all:
|
|
||||||
- changed-files:
|
|
||||||
- any-glob-to-any-file:
|
|
||||||
- .github/**
|
|
||||||
- scripts/**
|
|
||||||
- .gitignore
|
|
||||||
- .pre-commit-config.yaml
|
|
||||||
- all-globs-to-all-files:
|
|
||||||
- '!./**/*.md'
|
|
||||||
- '!frontend/**'
|
|
||||||
- '!backend/**'
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
auto-labels:
|
||||||
|
docs:
|
||||||
|
- exclude: frontend/**
|
||||||
|
- exclude: backend/**
|
||||||
|
- exclude: .github/**
|
||||||
|
- exclude: scripts/**
|
||||||
|
- '**/*.md'
|
||||||
|
internal:
|
||||||
|
- .github/**
|
||||||
|
- scripts/**
|
||||||
|
- .gitignore
|
||||||
|
- .pre-commit-config.yaml
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
name: Deploy with Docker Compose
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: deploy-docker-compose
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
# Do not deploy the template repository, only projects created from it
|
||||||
|
if: github.repository != 'fastapi/full-stack-fastapi-template'
|
||||||
|
runs-on: self-hosted
|
||||||
|
timeout-minutes: 30
|
||||||
|
env:
|
||||||
|
DOMAIN: ${{ vars.DOMAIN }}
|
||||||
|
PROJECT_NAME: ${{ vars.PROJECT_NAME }}
|
||||||
|
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||||
|
FIRST_SUPERUSER: ${{ vars.FIRST_SUPERUSER }}
|
||||||
|
FIRST_SUPERUSER_PASSWORD: ${{ secrets.FIRST_SUPERUSER_PASSWORD }}
|
||||||
|
SMTP_HOST: ${{ vars.SMTP_HOST }}
|
||||||
|
SMTP_USER: ${{ vars.SMTP_USER }}
|
||||||
|
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
|
||||||
|
EMAILS_FROM_EMAIL: ${{ vars.EMAILS_FROM_EMAIL }}
|
||||||
|
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
|
||||||
|
SENTRY_DSN: ${{ vars.SENTRY_DSN }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
- name: Build
|
||||||
|
run: docker compose -f compose.yml -f compose.deploy.yml build
|
||||||
|
- name: Prepare database
|
||||||
|
run: docker compose -f compose.yml -f compose.deploy.yml run --rm backend bash scripts/prestart.sh
|
||||||
|
- name: Start application
|
||||||
|
run: docker compose -f compose.yml -f compose.deploy.yml up -d
|
||||||
@@ -6,31 +6,49 @@ on:
|
|||||||
- master
|
- master
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- release-notes.md
|
- release-notes.md
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
# Do not deploy in the main repository, only in user projects
|
# Do not deploy the template repository, only projects created from it
|
||||||
if: github.repository_owner != 'fastapi'
|
if: github.repository != 'fastapi/full-stack-fastapi-template'
|
||||||
runs-on: self-hosted
|
runs-on: ubuntu-latest
|
||||||
env:
|
timeout-minutes: 15
|
||||||
DOMAIN: ${{ secrets.DOMAIN }}
|
|
||||||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
|
||||||
FIRST_SUPERUSER: ${{ secrets.FIRST_SUPERUSER }}
|
|
||||||
FIRST_SUPERUSER_PASSWORD: ${{ secrets.FIRST_SUPERUSER_PASSWORD }}
|
|
||||||
SMTP_HOST: ${{ secrets.SMTP_HOST }}
|
|
||||||
SMTP_USER: ${{ secrets.SMTP_USER }}
|
|
||||||
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
|
|
||||||
EMAILS_FROM_EMAIL: ${{ secrets.EMAILS_FROM_EMAIL }}
|
|
||||||
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
|
|
||||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
with:
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- run: docker compose -f compose.yml -f compose.deploy.yml build
|
- name: Set up Bun
|
||||||
- run: docker compose -f compose.yml -f compose.deploy.yml run --rm backend bash scripts/prestart.sh
|
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||||
- run: docker compose -f compose.yml -f compose.deploy.yml up -d
|
with:
|
||||||
|
bun-version: 1.3.12
|
||||||
|
- name: Install frontend dependencies
|
||||||
|
run: bun ci
|
||||||
|
- name: Build frontend
|
||||||
|
run: bun run --filter frontend build
|
||||||
|
env:
|
||||||
|
# Override frontend/.env so the deployed frontend uses the same origin as the API
|
||||||
|
VITE_API_URL: ""
|
||||||
|
- name: Set up uv
|
||||||
|
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
||||||
|
with:
|
||||||
|
version: "0.11.18"
|
||||||
|
- name: Prepare database
|
||||||
|
run: uv run bash scripts/prestart.sh
|
||||||
|
working-directory: backend
|
||||||
|
env:
|
||||||
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||||
|
PROJECT_NAME: ${{ vars.PROJECT_NAME }}
|
||||||
|
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||||
|
FIRST_SUPERUSER: ${{ vars.FIRST_SUPERUSER }}
|
||||||
|
FIRST_SUPERUSER_PASSWORD: ${{ secrets.FIRST_SUPERUSER_PASSWORD }}
|
||||||
|
- name: Deploy to FastAPI Cloud
|
||||||
|
run: uv run fastapi deploy
|
||||||
|
env:
|
||||||
|
FASTAPI_CLOUD_TOKEN: ${{ secrets.FASTAPI_CLOUD_TOKEN }}
|
||||||
|
FASTAPI_CLOUD_APP_ID: ${{ secrets.FASTAPI_CLOUD_APP_ID }}
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
name: Labels
|
|
||||||
on:
|
|
||||||
pull_request_target: # zizmor: ignore[dangerous-triggers]
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- synchronize
|
|
||||||
- reopened
|
|
||||||
|
|
||||||
permissions: {}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
labeler:
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 5
|
|
||||||
steps:
|
|
||||||
- uses: actions/labeler@bf12e9b00b37c5c0ca2b87b79b2daf7891dbda13 # v7.0.0
|
|
||||||
- run: echo "Done adding labels"
|
|
||||||
@@ -11,20 +11,21 @@
|
|||||||
- 🔍 [Pydantic](https://docs.pydantic.dev), used by FastAPI, for the data validation and settings management.
|
- 🔍 [Pydantic](https://docs.pydantic.dev), used by FastAPI, for the data validation and settings management.
|
||||||
- 💾 [PostgreSQL](https://www.postgresql.org) as the SQL database.
|
- 💾 [PostgreSQL](https://www.postgresql.org) as the SQL database.
|
||||||
- 🚀 [React](https://react.dev) for the frontend.
|
- 🚀 [React](https://react.dev) for the frontend.
|
||||||
- 🧩 Built into the backend image and served by FastAPI on the same domain as the API.
|
- 🧩 Built into the backend application and served by FastAPI on the same domain as the API.
|
||||||
- 💃 Using TypeScript, hooks, [Vite](https://vitejs.dev), and other parts of a modern frontend stack.
|
- 💃 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.
|
- 🎨 [Tailwind CSS](https://tailwindcss.com) and [shadcn/ui](https://ui.shadcn.com) for the frontend components.
|
||||||
- 🤖 An automatically generated frontend client.
|
- 🤖 An automatically generated frontend client.
|
||||||
- 🧪 [Playwright](https://playwright.dev) for End-to-End testing.
|
- 🧪 [Playwright](https://playwright.dev) for End-to-End testing.
|
||||||
- 🦇 Dark mode support.
|
- 🦇 Dark mode support.
|
||||||
- 🐋 [Docker Compose](https://www.docker.com) for local services and deployment.
|
- ☁️ [FastAPI Cloud](https://fastapicloud.com) for deployment.
|
||||||
|
- 🐋 [Docker Compose](https://www.docker.com) for local services and self-hosted deployment.
|
||||||
|
- 📞 [Traefik](https://traefik.io) as a reverse proxy with automatic HTTPS.
|
||||||
- 🔒 Secure password hashing by default.
|
- 🔒 Secure password hashing by default.
|
||||||
- 🔑 JWT (JSON Web Token) authentication.
|
- 🔑 JWT (JSON Web Token) authentication.
|
||||||
- 📫 Email based password recovery.
|
- 📫 Email based password recovery.
|
||||||
- 📬 [Mailcatcher](https://mailcatcher.me) for local email testing during development.
|
- 📬 [Mailcatcher](https://mailcatcher.me) for local email testing during development.
|
||||||
- ✅ Tests with [Pytest](https://pytest.org).
|
- ✅ Tests with [Pytest](https://pytest.org).
|
||||||
- 📞 [Traefik](https://traefik.io) as a reverse proxy / load balancer.
|
- 🚢 Deployment with FastAPI Cloud or self-hosting with Docker Compose and Traefik.
|
||||||
- 🚢 Deployment instructions using Docker Compose with automatic HTTPS provided by Traefik.
|
|
||||||
- 🏭 CI (continuous integration) and CD (continuous deployment) based on GitHub Actions.
|
- 🏭 CI (continuous integration) and CD (continuous deployment) based on GitHub Actions.
|
||||||
|
|
||||||
### Dashboard Login
|
### Dashboard Login
|
||||||
@@ -123,17 +124,7 @@ git merge --continue
|
|||||||
|
|
||||||
### Configure
|
### Configure
|
||||||
|
|
||||||
You can then update configs in the `.env` files to customize your configurations.
|
You can update the local settings in the `.env` file. Before deploying, configure the environment variables and secrets described in the [FastAPI Cloud deployment guide](./deployment.md) or the [Docker Compose deployment guide](./deployment-docker-compose.md). Never deploy with the default `changethis` values.
|
||||||
|
|
||||||
Before deploying it, make sure you change at least the values for:
|
|
||||||
|
|
||||||
- `SECRET_KEY`
|
|
||||||
- `FIRST_SUPERUSER_PASSWORD`
|
|
||||||
- `POSTGRES_PASSWORD`
|
|
||||||
|
|
||||||
You can (and should) pass these as environment variables from secrets.
|
|
||||||
|
|
||||||
Read the [deployment.md](./deployment.md) docs for more details.
|
|
||||||
|
|
||||||
### Generate Secret Keys
|
### Generate Secret Keys
|
||||||
|
|
||||||
@@ -159,11 +150,13 @@ Frontend docs: [frontend/README.md](./frontend/README.md).
|
|||||||
|
|
||||||
Deployment docs: [deployment.md](./deployment.md).
|
Deployment docs: [deployment.md](./deployment.md).
|
||||||
|
|
||||||
|
Docker Compose deployment: [deployment-docker-compose.md](./deployment-docker-compose.md).
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
General development docs: [development.md](./development.md).
|
General development docs: [development.md](./development.md).
|
||||||
|
|
||||||
This includes the local FastAPI and Vite workflow, Docker Compose services, custom local domains, `.env` configuration, and more.
|
This includes the local FastAPI and Vite workflow, Docker Compose services, `.env` configuration, and more.
|
||||||
|
|
||||||
## Release Notes
|
## Release Notes
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
# FastAPI Project - Docker Compose Deployment
|
||||||
|
|
||||||
|
You can deploy the project to your own remote server with Docker Compose. The deployment configuration includes Traefik to handle HTTPS and route incoming traffic to the application.
|
||||||
|
|
||||||
|
## Preparation
|
||||||
|
|
||||||
|
* Have a remote server ready and available.
|
||||||
|
* Configure DNS records pointing to the server for the application domain and any supporting service subdomains you want to expose, such as `fastapi-project.example.com` and `adminer.fastapi-project.example.com`.
|
||||||
|
* Install and configure [Docker](https://docs.docker.com/engine/install/) on the remote server (Docker Engine, not Docker Desktop).
|
||||||
|
|
||||||
|
## Copy the Code
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rsync -av --exclude=".git/" --filter=":- .gitignore" ./ root@your-server.example.com:/root/code/app/
|
||||||
|
```
|
||||||
|
|
||||||
|
The `--filter=":- .gitignore"` option tells `rsync` to use the same ignore rules as Git, excluding files such as the Python virtual environment.
|
||||||
|
|
||||||
|
## Configure the Application
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
Set the application domain, project name, and first superuser email:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export DOMAIN=fastapi-project.example.com
|
||||||
|
export PROJECT_NAME="Full Stack FastAPI Project"
|
||||||
|
export FIRST_SUPERUSER=admin@example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also configure these environment variables as needed:
|
||||||
|
|
||||||
|
* `SMTP_HOST`: The SMTP server host from your email provider.
|
||||||
|
* `SMTP_USER`: The SMTP server user.
|
||||||
|
* `EMAILS_FROM_EMAIL`: The email account used to send emails.
|
||||||
|
* `SENTRY_DSN`: The DSN for Sentry.
|
||||||
|
|
||||||
|
### Secrets
|
||||||
|
|
||||||
|
Generate and set secure values for the database password, token signing key, and first superuser password:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export POSTGRES_PASSWORD="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
|
||||||
|
export SECRET_KEY="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
|
||||||
|
export FIRST_SUPERUSER_PASSWORD="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
|
||||||
|
```
|
||||||
|
|
||||||
|
To use an authenticated email provider, also set `SMTP_PASSWORD`.
|
||||||
|
|
||||||
|
## Deploy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /root/code/app/
|
||||||
|
docker compose -f compose.yml -f compose.deploy.yml build
|
||||||
|
docker compose -f compose.yml -f compose.deploy.yml run --rm backend bash scripts/prestart.sh
|
||||||
|
docker compose -f compose.yml -f compose.deploy.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
The `compose.deploy.yml` file adds HTTPS and automatic certificate handling to the shared `compose.yml` configuration. Explicitly listing both files excludes the local settings from `compose.override.yml`.
|
||||||
|
|
||||||
|
The backend Docker image builds the frontend, so the server does not need Bun or prebuilt frontend files.
|
||||||
|
|
||||||
|
## Deploy with GitHub Actions
|
||||||
|
|
||||||
|
The included `.github/workflows/deploy-docker-compose.yml` workflow runs the deployment commands on the server when manually triggered from GitHub Actions.
|
||||||
|
|
||||||
|
Use a self-hosted runner only for a repository whose contributors and workflow code you trust. GitHub recommends using self-hosted runners with private repositories because workflows execute directly on the runner machine.
|
||||||
|
|
||||||
|
### Configure Repository Variables and Secrets
|
||||||
|
|
||||||
|
In the repository, go to **Settings** > **Secrets and variables** > **Actions** and add these repository variables:
|
||||||
|
|
||||||
|
* `DOMAIN`
|
||||||
|
* `PROJECT_NAME`
|
||||||
|
* `FIRST_SUPERUSER`
|
||||||
|
|
||||||
|
To enable emails, add these optional repository variables:
|
||||||
|
|
||||||
|
* `SMTP_HOST`
|
||||||
|
* `SMTP_USER`
|
||||||
|
* `EMAILS_FROM_EMAIL`
|
||||||
|
|
||||||
|
To enable Sentry, add the optional `SENTRY_DSN` repository variable.
|
||||||
|
|
||||||
|
Add these repository secrets:
|
||||||
|
|
||||||
|
* `POSTGRES_PASSWORD`
|
||||||
|
* `SECRET_KEY`
|
||||||
|
* `FIRST_SUPERUSER_PASSWORD`
|
||||||
|
|
||||||
|
To use an authenticated email provider, add the optional `SMTP_PASSWORD` repository secret.
|
||||||
|
|
||||||
|
### Install a Self-Hosted Runner
|
||||||
|
|
||||||
|
On the server, create a dedicated user and grant it access to Docker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo adduser github
|
||||||
|
sudo usermod -aG docker github
|
||||||
|
sudo su - github
|
||||||
|
```
|
||||||
|
|
||||||
|
In the GitHub repository, go to **Settings** > **Actions** > **Runners**, select **New self-hosted runner**, choose Linux, and follow the commands GitHub provides to download, configure, and register the runner. Install it in `/home/github/actions-runner`.
|
||||||
|
|
||||||
|
After registering the runner, exit the `github` user session and install the runner as a system service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
exit
|
||||||
|
cd /home/github/actions-runner
|
||||||
|
sudo ./svc.sh install github
|
||||||
|
sudo ./svc.sh start
|
||||||
|
sudo ./svc.sh status
|
||||||
|
```
|
||||||
|
|
||||||
|
See GitHub's guides for [adding a self-hosted runner](https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/add-runners) and [configuring the runner as a service](https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/configure-the-application?platform=linux).
|
||||||
|
|
||||||
|
### Run the Deployment
|
||||||
|
|
||||||
|
When the runner is online, open the repository's **Actions** tab, select **Deploy with Docker Compose**, and select **Run workflow**.
|
||||||
|
|
||||||
|
## URLs
|
||||||
|
|
||||||
|
Replace `fastapi-project.example.com` with your domain.
|
||||||
|
|
||||||
|
Application (frontend and API): `https://fastapi-project.example.com`
|
||||||
|
|
||||||
|
Interactive API docs: `https://fastapi-project.example.com/docs`
|
||||||
|
|
||||||
|
Adminer: `https://adminer.fastapi-project.example.com`
|
||||||
+51
-165
@@ -1,86 +1,90 @@
|
|||||||
# FastAPI Project - Deployment
|
# FastAPI Project - Deployment
|
||||||
|
|
||||||
You can deploy the project using Docker Compose to a remote server.
|
Deploy the project to [FastAPI Cloud](https://fastapicloud.com) with the included GitHub Actions workflow.
|
||||||
|
|
||||||
The deployment Docker Compose configuration includes Traefik to handle HTTPS and route incoming traffic to the application.
|
## Create the FastAPI Cloud Application
|
||||||
|
|
||||||
The included GitHub Actions workflow can deploy the application automatically.
|
Create an application in FastAPI Cloud and set its [Application Directory](https://fastapicloud.com/docs/builds-and-deployments/application-directory/) to `backend`.
|
||||||
|
|
||||||
But you have to configure a couple things first. 🤓
|
Connect a PostgreSQL database using the [Neon](https://fastapicloud.com/docs/integrations/neon-integration/) or [Supabase](https://fastapicloud.com/docs/integrations/supabase-integration/) integration. Both integrations configure a `DATABASE_URL` secret automatically. You can also configure `DATABASE_URL` manually for another PostgreSQL provider.
|
||||||
|
|
||||||
## Preparation
|
## Configure the Application
|
||||||
|
|
||||||
* Have a remote server ready and available.
|
### Environment Variables
|
||||||
* Configure DNS records pointing to the server for the application domain and any supporting service subdomains you want to expose, e.g. `fastapi-project.example.com` and `adminer.fastapi-project.example.com`.
|
|
||||||
* Install and configure [Docker](https://docs.docker.com/engine/install/) on the remote server (Docker Engine, not Docker Desktop).
|
|
||||||
|
|
||||||
## Deploy the FastAPI Project
|
Add these required [environment variables](https://fastapicloud.com/docs/builds-and-deployments/environment-variables/) to the FastAPI Cloud application:
|
||||||
|
|
||||||
You can deploy your FastAPI project with Docker Compose.
|
* `PROJECT_NAME`: The name of the project, used in the API documentation and emails.
|
||||||
|
* `FIRST_SUPERUSER`: The email address of the first superuser.
|
||||||
|
* `FRONTEND_HOST`: The public URL of the application, such as the generated `https://your-app.fastapicloud.dev` URL or a custom domain.
|
||||||
|
|
||||||
**Note**: You might want to jump ahead to the section about Continuous Deployment with GitHub Actions.
|
To enable emails, add these optional environment variables with values from your email provider:
|
||||||
|
|
||||||
## Copy the Code
|
* `SMTP_HOST`
|
||||||
|
* `SMTP_USER`
|
||||||
|
* `EMAILS_FROM_EMAIL`
|
||||||
|
|
||||||
```bash
|
To enable Sentry, configure `SENTRY_DSN`.
|
||||||
rsync -av --exclude=".git/" --filter=":- .gitignore" ./ root@your-server.example.com:/root/code/app/
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: `--filter=":- .gitignore"` tells `rsync` to use the same rules as git, ignore files ignored by git, like the Python virtual environment.
|
### Secrets
|
||||||
|
|
||||||
## Environment Variables
|
Add these required values and mark them as secrets:
|
||||||
|
|
||||||
You need to set some environment variables first.
|
* `SECRET_KEY`: A secret key used to sign security tokens.
|
||||||
|
* `FIRST_SUPERUSER_PASSWORD`: The password of the first superuser.
|
||||||
|
* `DATABASE_URL`: The PostgreSQL connection URL, configured automatically when using a database integration.
|
||||||
|
|
||||||
### Generate secret keys
|
To enable emails with an authenticated provider, add `SMTP_PASSWORD` as a secret.
|
||||||
|
|
||||||
Some environment variables in the `.env` file have a default value of `changethis`.
|
You can generate secure values for `SECRET_KEY` and `FIRST_SUPERUSER_PASSWORD` with:
|
||||||
|
|
||||||
You have to change them with a secret key, to generate secret keys you can run the following command:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -c "import secrets; print(secrets.token_urlsafe(32))"
|
python -c "import secrets; print(secrets.token_urlsafe(32))"
|
||||||
```
|
```
|
||||||
|
|
||||||
Copy the content and use that as password / secret key. And run that again to generate another secure key.
|
## Configure Continuous Deployment
|
||||||
|
|
||||||
### Required Environment Variables
|
The included `.github/workflows/deploy.yml` workflow builds the frontend, prepares the database, and deploys the application whenever changes are pushed to `master`. You can also run it manually from the **Actions** tab.
|
||||||
|
|
||||||
Set the `DOMAIN` to your own domain, for example:
|
Log in to FastAPI Cloud and configure the [deploy token](https://fastapicloud.com/docs/advanced-features/deploy-tokens/) and application ID as GitHub repository secrets:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export DOMAIN=fastapi-project.example.com
|
uv run fastapi login
|
||||||
|
uv run fastapi cloud setup-ci --secrets-only --app-id <your-app-id>
|
||||||
```
|
```
|
||||||
|
|
||||||
The deployment Docker Compose configuration also uses `DOMAIN` to set the public frontend URL used in links generated by the backend.
|
If the GitHub CLI is installed and authenticated, the command configures `FASTAPI_CLOUD_TOKEN` and `FASTAPI_CLOUD_APP_ID` automatically. Otherwise, it prints the values so you can add them in your repository under **Settings** > **Secrets and variables** > **Actions**.
|
||||||
|
|
||||||
Set the `POSTGRES_PASSWORD` to a secure value:
|
The workflow runs database migrations and creates the first superuser before deploying. In the repository's **Settings** > **Secrets and variables** > **Actions** page, add these repository variables:
|
||||||
|
|
||||||
```bash
|
* `PROJECT_NAME`
|
||||||
export POSTGRES_PASSWORD="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
|
* `FIRST_SUPERUSER`
|
||||||
```
|
|
||||||
|
|
||||||
Set the `SECRET_KEY`, used to sign tokens, to a secure value:
|
Add these repository secrets:
|
||||||
|
|
||||||
```bash
|
* `DATABASE_URL`
|
||||||
export SECRET_KEY="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
|
* `SECRET_KEY`
|
||||||
```
|
* `FIRST_SUPERUSER_PASSWORD`
|
||||||
|
|
||||||
Set the `FIRST_SUPERUSER_PASSWORD` to a secure value:
|
Use the same values configured in FastAPI Cloud. For `DATABASE_URL`, use the connection URL from your database provider. The database must be reachable from GitHub-hosted runners so the preparation step can connect to it.
|
||||||
|
|
||||||
```bash
|
The deployment workflow performs these steps:
|
||||||
export FIRST_SUPERUSER_PASSWORD="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
|
|
||||||
```
|
|
||||||
|
|
||||||
You can set several other environment variables:
|
1. Installs and builds the frontend into `backend/app/frontend`.
|
||||||
|
2. Runs `backend/scripts/prestart.sh` to apply database migrations and create the first superuser.
|
||||||
|
3. Deploys the project with `uv run fastapi deploy`.
|
||||||
|
|
||||||
* `PROJECT_NAME`: The name of the project, used in the API for the docs and emails.
|
## URLs
|
||||||
* `FIRST_SUPERUSER`: The email of the first superuser, this superuser will be the one that can create new users.
|
|
||||||
* `SMTP_HOST`: The SMTP server host to send emails, this would come from your email provider (E.g. Mailgun, Sparkpost, Sendgrid, etc).
|
Replace `your-app.fastapicloud.dev` with the URL of your FastAPI Cloud application.
|
||||||
* `SMTP_USER`: The SMTP server user to send emails.
|
|
||||||
* `SMTP_PASSWORD`: The SMTP server password to send emails.
|
Application (frontend and API): `https://your-app.fastapicloud.dev`
|
||||||
* `EMAILS_FROM_EMAIL`: The email account to send emails from.
|
|
||||||
* `SENTRY_DSN`: The DSN for Sentry, if you are using it.
|
Interactive API docs: `https://your-app.fastapicloud.dev/docs`
|
||||||
|
|
||||||
|
## Docker Compose
|
||||||
|
|
||||||
|
For deployment to your own server, see the [Docker Compose deployment guide](./deployment-docker-compose.md).
|
||||||
|
|
||||||
## GitHub Repository Automation
|
## GitHub Repository Automation
|
||||||
|
|
||||||
@@ -91,121 +95,3 @@ Install the following GitHub Apps to enable the included repository automation:
|
|||||||
* [PR Submit](https://github.com/apps/pr-submit) lets the **Bump pre-commit hooks** and **Prepare Release** workflows create pull requests.
|
* [PR Submit](https://github.com/apps/pr-submit) lets the **Bump pre-commit hooks** and **Prepare Release** workflows create pull requests.
|
||||||
|
|
||||||
To publish code coverage with [Smokeshow](https://github.com/samuelcolvin/smokeshow), add `SMOKESHOW_AUTH_KEY` as a repository secret.
|
To publish code coverage with [Smokeshow](https://github.com/samuelcolvin/smokeshow), add `SMOKESHOW_AUTH_KEY` as a repository secret.
|
||||||
|
|
||||||
### Deploy with Docker Compose
|
|
||||||
|
|
||||||
With the environment variables in place, you can deploy with Docker Compose:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /root/code/app/
|
|
||||||
docker compose -f compose.yml -f compose.deploy.yml build
|
|
||||||
docker compose -f compose.yml -f compose.deploy.yml run --rm backend bash scripts/prestart.sh
|
|
||||||
docker compose -f compose.yml -f compose.deploy.yml up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
The `compose.deploy.yml` file adds the deployment settings to the shared configuration in `compose.yml`, including HTTPS and automatic certificate handling. Explicitly listing these files also excludes the local development settings in `compose.override.yml`.
|
|
||||||
|
|
||||||
## Continuous Deployment (CD)
|
|
||||||
|
|
||||||
You can use GitHub Actions to deploy your project automatically. 😎
|
|
||||||
|
|
||||||
The included `deploy.yml` workflow deploys the application whenever changes are pushed to `master`, including when a pull request is merged. 🚀
|
|
||||||
|
|
||||||
### Install GitHub Actions Runner
|
|
||||||
|
|
||||||
* On your remote server, create a user for your GitHub Actions:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo adduser github
|
|
||||||
```
|
|
||||||
|
|
||||||
* Add Docker permissions to the `github` user:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo usermod -aG docker github
|
|
||||||
```
|
|
||||||
|
|
||||||
* Temporarily switch to the `github` user:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo su - github
|
|
||||||
```
|
|
||||||
|
|
||||||
* Go to the `github` user's home directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd
|
|
||||||
```
|
|
||||||
|
|
||||||
* [Install a GitHub Action self-hosted runner following the official guide](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners#adding-a-self-hosted-runner-to-a-repository).
|
|
||||||
|
|
||||||
After installing, the guide would tell you to run a command to start the runner. Nevertheless, it would stop once you terminate that process or if your local connection to your server is lost.
|
|
||||||
|
|
||||||
To make sure it runs on startup and continues running, you can install it as a service. To do that, exit the `github` user and go back to the `root` user:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
exit
|
|
||||||
```
|
|
||||||
|
|
||||||
After you do it, you will be on the previous user again. And you will be on the previous directory, belonging to that user.
|
|
||||||
|
|
||||||
Before being able to go the `github` user directory, you need to become the `root` user (you might already be):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo su
|
|
||||||
```
|
|
||||||
|
|
||||||
* As the `root` user, go to the `actions-runner` directory inside of the `github` user's home directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /home/github/actions-runner
|
|
||||||
```
|
|
||||||
|
|
||||||
* Install the self-hosted runner as a service with the user `github`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./svc.sh install github
|
|
||||||
```
|
|
||||||
|
|
||||||
* Start the service:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./svc.sh start
|
|
||||||
```
|
|
||||||
|
|
||||||
* Check the status of the service:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./svc.sh status
|
|
||||||
```
|
|
||||||
|
|
||||||
You can read more about it in the official guide: [Configuring the self-hosted runner application as a service](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service).
|
|
||||||
|
|
||||||
### Set Repository Secrets
|
|
||||||
|
|
||||||
In your repository, go to **Settings** > **Secrets and variables** > **Actions** and add the following [repository secrets](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets#creating-secrets-for-a-repository):
|
|
||||||
|
|
||||||
* `DOMAIN`
|
|
||||||
* `FIRST_SUPERUSER`
|
|
||||||
* `FIRST_SUPERUSER_PASSWORD`
|
|
||||||
* `POSTGRES_PASSWORD`
|
|
||||||
* `SECRET_KEY`
|
|
||||||
|
|
||||||
To enable emails, configure these additional secrets with the values from your email provider:
|
|
||||||
|
|
||||||
* `SMTP_HOST`
|
|
||||||
* `SMTP_USER`
|
|
||||||
* `SMTP_PASSWORD`
|
|
||||||
* `EMAILS_FROM_EMAIL`
|
|
||||||
|
|
||||||
To enable Sentry, configure the `SENTRY_DSN` secret.
|
|
||||||
|
|
||||||
## URLs
|
|
||||||
|
|
||||||
Replace `fastapi-project.example.com` with your domain.
|
|
||||||
|
|
||||||
Application (frontend and API): `https://fastapi-project.example.com`
|
|
||||||
|
|
||||||
Interactive API docs: `https://fastapi-project.example.com/docs`
|
|
||||||
|
|
||||||
Adminer: `https://adminer.fastapi-project.example.com`
|
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ If you are developing an API-only app and want to remove the frontend, you can d
|
|||||||
|
|
||||||
* In the `compose.override.yml` file, remove the `playwright` service.
|
* In the `compose.override.yml` file, remove the `playwright` service.
|
||||||
|
|
||||||
|
* In the `.github/workflows/deploy.yml` file, remove the **Set up Bun**, **Install frontend dependencies**, and **Build frontend** steps.
|
||||||
|
|
||||||
|
* In the `.fastapicloudignore` file, remove the `!backend/app/frontend/` entry.
|
||||||
|
|
||||||
Done, you have a frontend-less (api-only) app. 🤓
|
Done, you have a frontend-less (api-only) app. 🤓
|
||||||
|
|
||||||
## Generate Client
|
## Generate Client
|
||||||
|
|||||||
@@ -2,6 +2,20 @@
|
|||||||
|
|
||||||
## Latest Changes
|
## Latest Changes
|
||||||
|
|
||||||
|
## 0.12.0 (2026-08-12)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* ☁️ Add FastAPI Cloud deployment. PR [#2438](https://github.com/fastapi/full-stack-fastapi-template/pull/2438) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* 🐳 Include frontend assets in Docker build context. PR [#2440](https://github.com/fastapi/full-stack-fastapi-template/pull/2440) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
|
||||||
|
### Internal
|
||||||
|
|
||||||
|
* 👷 Migrate automatic labels to Latest Changes. PR [#2439](https://github.com/fastapi/full-stack-fastapi-template/pull/2439) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
|
||||||
## 0.11.1 (2026-08-11)
|
## 0.11.1 (2026-08-11)
|
||||||
|
|
||||||
### Refactors
|
### Refactors
|
||||||
|
|||||||
Reference in New Issue
Block a user