> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sevalla.com/llms.txt
> Use this file to discover all available pages before exploring further.

# FastAPI - Deployment

> Find out how to configure and deploy your FastAPI application.

## Example app

FastAPI apps can be structured in many ways. For demonstration purposes, this example provides a simple, deployable FastAPI app on Sevalla. The concepts shown here can be applied to any FastAPI application.

What’s included in the example app:

### Database models

This app uses SQLModel as its ORM. All database models should inherit from the `SQLModel` class, which is imported in `models.py`. This ensures consistency and smooth integration with the app’s database layer.

```python theme={null}
# app/models.py
from sqlmodel import SQLModel
```

SQLModel needs a connection to your database, which requires creating an engine. The database URL is provided via the `SQLALCHEMY_DATABASE_URI` setting, which will be defined in `config.py` later.

```python theme={null}
# app/core/db.py
from sqlmodel import create_engine

from app.core.config import settings

engine = create_engine(str(settings.SQLALCHEMY_DATABASE_URI))
```

You need to create a session and a session dependency so your routes can create, read, and modify SQLModel objects.

```python theme={null}
# app/api/deps.py
from fastapi import Depends
from sqlmodel import Session
from typing import Annotated

from app.core.db import engine

def get_session():
    with Session(engine) as session:
        yield session


SessionDep = Annotated[Session, Depends(get_session)]
```

Alembic is used for database migrations.

The `alembic` directory and its files were generated by the `alembic init app/alembic` command. Inside that directory, the `app/alembic/env.py` and `app/alembic/script.py.mako` files need to be updated to work with your app.

For `alembic.env.py`, the `SQLModel` class needs to be imported from `models.py`, and the database URL needs to be referenced when migrations are run.

```python theme={null}
# app/alembic.env.py
...

target_metadata = None # [!code --]
from app.models import SQLModel # [!code ++:3]
from app.core.config import settings
target_metadata = SQLModel.metadata

...

def get_url(): # [!code ++:2]
    return str(settings.SQLALCHEMY_DATABASE_URI)

...

def run_migrations_offline() -> None:
    url = config.get_main_option("sqlalchemy.url") # [!code --]
    url = get_url() # [!code ++]

...

def run_migrations_online() -> None:
    configuration = config.get_section(config.config_ini_section) # [!code ++]
    configuration["sqlalchemy.url"] = get_url() # [!code ++]
    connectable = engine_from_config(
        config.get_section(config.config_ini_section, {}), # [!code --]
        configuration, # [!code ++]
        prefix="sqlalchemy.",
        poolclass=pool.NullPool,
    )
```

Update `app/alembic/script.py.mako` to include an import for `sqlmodel`.

```python theme={null}
# app/alembic/script.py.mako
from alembic import op
import sqlalchemy as sa
import sqlmodel # [!code ++]
```

### App settings

The `pydantic-settings` package manages all configuration values for the app. If a `.env` file is present, its values will be loaded automatically. Otherwise, the app will fall back to the environment variables defined on the system.

The only required setting for this example is `SQLALCHEMY_DATABASE_URI`, which specifies the connection string used to connect to your database.

```python theme={null}
# app/core/config.py
from pydantic_settings import BaseSettings, SettingsConfigDict

class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_file=".env")

    SQLALCHEMY_DATABASE_URI: str = ""

settings = Settings()
```

In a development environment, you can create a `.env` file to store configuration values that will be loaded when the app starts. When deploying to Sevalla, these [environment variables](https://docs.sevalla.com/applications/environment-variables) can be configured directly through Sevalla instead.

```shellsession theme={null}
# .env
SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://<user>:<password>@<hostname>:<port>/<db_name>
```

### Main file

The app’s entry point is `main.py`, where you need to instantiate the FastAPI app object.

```python theme={null}
# app/main.py
from fastapi import FastAPI
from app.core.config import settings

app = FastAPI()
```

### Requirements

The following installs all the requirements for this example app:

```shellsession theme={null}
pip install fastapi[all] sqlmodel
pip install alembic psycopg2-binary
pip freeze > requirements.txt
```

## Add a hosted database

The filesystem used for your app will be recreated on each deploy, so an SQLite database isn't suitable for production. Instead, you can use a hosted database on Sevalla for your app.

[Create a database](https://docs.sevalla.com/databases/get-started/add-a-database) in Sevalla and select either Postgres, MySQL, or MariaDB.

You also need to install a database driver if you haven't already done so. For example, with Postgres, you can use `psycopg2-binary`.

```shellsession theme={null}
pip install psycopg2-binary
```

## Nixpacks

By default, Sevalla uses Nixpacks to build your application.

After you add the application, you need to add custom commands that will both start your app and run migrations before every deploy.

To [update the start command](https://docs.sevalla.com/applications/processes#edit-the-web-process), go to **Processes** > **Web process** > **Update process** and add `fastapi run app/main.py` as your custom start command.

For migrations, you can [create a job](https://docs.sevalla.com/applications/processes#job-process) to run the migrate command before the container is started. To do this, after you add your application, go to **Processes** > **Create job** > **Job**. For the start command, add `alembic upgrade head`. The start policy should be **before deployment**, and the smallest instance size should be sufficient for migrations.

## Dockerfile

To build your application using a Dockerfile, ensure it ends with your FastAPI app being started by the app server.

Below is a sample Dockerfile that sets up a Python environment, installs dependencies, and launches the server.

```docker theme={null}
FROM python:latest  

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1 
 
RUN mkdir /app
WORKDIR /app
 
RUN pip install --upgrade pip 
COPY requirements.txt  .
RUN pip install --no-cache-dir -r requirements.txt
 
COPY . .
 
CMD ["fastapi", "run", "app/main.py"]
```

The command to start FastAPI must reference the name of the file containing your FastAPI app object.

The rest of the Dockerfile can be customized according to your project's specific needs.

### Migrations

For migrations, you can [create a job](https://docs.sevalla.com/applications/processes#job-process) to run the migrate command before the container is started. To do this, after you add your application, go to **Processes** > **Create job** > **Job**. For the start command, add `alembic upgrade head`. The start policy should be **before deployment**, and the smallest instance size should be sufficient for migrations.

### Build settings

By default, Sevalla builds applications using Nixpacks, so the [build strategy](https://docs.sevalla.com/applications/settings#build-strategy) must be updated before your Dockerfile can be used.

To update the build strategy, after you add your application, go to **Settings** > **Update build strategy** and change the build strategy from **Nixpacks** to **Dockerfile**.

## Deploy on Sevalla

To deploy your app to [Sevalla using Git](https://docs.sevalla.com/applications/git/overview), your code must be hosted in a Git repository. Sevalla supports any public Git repository or private repositories from GitHub, Bitbucket, and GitLab. You'll need to connect your repo host account with Sevalla if you are using a private repo.

Your repo should have a `.gitignore` that ignores SQLite files, `.env` files, virtual environments, `__pycache__/`, any other files that either have sensitive information or don't need to be tracked in git.

Here is an example .gitignore file:

```text theme={null}
__pycache__/ 
.env
.venv/
env/
venv/
*.sqlite3
```

You can now [add your application](https://docs.sevalla.com/applications/get-started/add-an-application) in Sevalla and choose the branch and repository for your project. Ensure that you set the location for your application to match the location of your database, allowing them to communicate over an internal network.  If your app requires more resources than the defaults of 0.3 GB RAM and 0.3 CPU, then switch to a larger instance size.

After adding your application, you can configure the environment variables it requires. For this example, only `SQLALCHEMY_DATABASE_URI` is needed.

Since this variable holds your database URL,  go to **Networking** and click **Add internal connection**. Select the database you created earlier, and then select **Add environment variables to the application**. Rename `DB_URL` to `SQLALCHEMY_DATABASE_URI` and click **Add internal connection**.

<Info>
  If you are using PostgreSQL, make sure the connection string starts with `postgresql://` (not `postgres://`) so SQLModel can connect properly.
</Info>
