☁️ Add FastAPI Cloud deployment (#2438)

This commit is contained in:
Sebastián Ramírez
2026-08-11 23:16:35 +02:00
committed by GitHub
parent ddb3c34f19
commit 2d8fb3e4de
7 changed files with 271 additions and 198 deletions
+51 -165
View File
@@ -1,86 +1,90 @@
# 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.
* 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).
### Environment Variables
## 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
rsync -av --exclude=".git/" --filter=":- .gitignore" ./ root@your-server.example.com:/root/code/app/
```
To enable Sentry, configure `SENTRY_DSN`.
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 have to change them with a secret key, to generate secret keys you can run the following command:
You can generate secure values for `SECRET_KEY` and `FIRST_SUPERUSER_PASSWORD` with:
```bash
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
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
export POSTGRES_PASSWORD="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
```
* `PROJECT_NAME`
* `FIRST_SUPERUSER`
Set the `SECRET_KEY`, used to sign tokens, to a secure value:
Add these repository secrets:
```bash
export SECRET_KEY="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
```
* `DATABASE_URL`
* `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
export FIRST_SUPERUSER_PASSWORD="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
```
The deployment workflow performs these steps:
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.
* `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).
* `SMTP_USER`: The SMTP server user to send emails.
* `SMTP_PASSWORD`: The SMTP server password to send emails.
* `EMAILS_FROM_EMAIL`: The email account to send emails from.
* `SENTRY_DSN`: The DSN for Sentry, if you are using it.
## URLs
Replace `your-app.fastapicloud.dev` with the URL of your FastAPI Cloud application.
Application (frontend and API): `https://your-app.fastapicloud.dev`
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
@@ -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.
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`