For local development, run PostgreSQL and Mailcatcher with Docker Compose, and run the FastAPI and Vite development servers locally.
Start the supporting services:
docker compose up -d db mailcatcherThen, from the backend directory, install the dependencies and prepare the database:
uv sync
uv run bash scripts/prestart.shStart the FastAPI development server:
uv run fastapi devIn another terminal, from the project root, install the frontend dependencies and start the Vite development server:
bun install
bun run devNow you can open these URLs:
Frontend development server: http://localhost:5173
Backend API: http://localhost:8000
Automatic interactive API documentation with Swagger UI: http://localhost:8000/docs
Mailcatcher: http://localhost:1080
The frontend development server uses the backend at http://localhost:8000, as configured in frontend/.env.
Build the frontend from the frontend directory:
bun run buildThe build is written to backend/app/frontend and served by FastAPI at http://localhost:8000. Rebuild the frontend after making frontend changes.
To run the backend and built frontend in Docker Compose:
docker compose run --rm backend bash scripts/prestart.sh
docker compose watchNow you can open these URLs:
Application, with the frontend and API served by FastAPI: http://localhost:8000
Automatic interactive API documentation with Swagger UI: http://localhost:8000/docs
Adminer, database web administration: http://localhost:8080
Traefik UI, to see how the routes are being handled by the proxy: http://localhost:8090
Mailcatcher: http://localhost:1080
Stop a locally running FastAPI server before starting the Compose backend because both use port 8000.
Note: The first time you start the stack, it might take a minute for all the services to be ready. To monitor it, use docker compose logs, or docker compose logs backend for the backend service.
Mailcatcher captures emails sent during local development instead of delivering them. The local backend connects to it at localhost:1025, and the Compose backend connects to the mailcatcher service. Captured emails are available at http://localhost:1080.
The main compose.yml file contains the configuration shared by the whole stack. Docker Compose loads it automatically.
The compose.override.yml file adds local development settings, such as mounting the source code as a volume. Docker Compose also loads it automatically and applies it on top of compose.yml.
The compose.deploy.yml file contains the deployment-specific settings, including HTTPS and automatic certificate handling. It is explicitly combined with compose.yml when deploying the application.
The backend reads local settings from the .env file. Docker Compose also uses it for variable interpolation and passes the settings each container needs.
After changing variables, make sure you restart the stack:
docker compose watchThe tracked .env file contains local development defaults, passwords, and other configuration. Its hostnames use localhost for processes running on your machine. Docker Compose overrides hostnames such as the database and SMTP server with their Compose service names.
Do not store deployment secrets in .env. Configure them as described in the FastAPI Cloud deployment guide or the Docker Compose deployment guide.
The project uses prek, a modern alternative to pre-commit, for code linting and formatting.
You can find a file .pre-commit-config.yaml with configurations at the root of the project.
prek is already part of the dependencies of the project.
From the project root, install the Git hook so that prek runs automatically before each commit:
uv run prek install -fThe -f flag forces the installation, in case there was already a pre-commit hook previously installed.
Now whenever you try to commit, for example with:
git commitprek will check and format the code you are about to commit. If it modifies any files, add those files to Git again before committing.
You can also run prek manually on all files from the project root:
uv run prek run --all-files