# FastAPI Project - Development ## Local Development For local development, run PostgreSQL and Mailcatcher with Docker Compose, and run the FastAPI and Vite development servers locally. Start the supporting services: ```bash docker compose up -d db mailcatcher ``` Then, from the `backend` directory, install the dependencies and prepare the database: ```bash uv sync uv run bash scripts/prestart.sh ``` Start the FastAPI development server: ```bash uv run fastapi dev ``` In another terminal, from the project root, install the frontend dependencies and start the Vite development server: ```bash bun install bun run dev ``` Now you can open these URLs: Frontend development server: Backend API: Automatic interactive API documentation with Swagger UI: Mailcatcher: The frontend development server uses the backend at `http://localhost:8000`, as configured in `frontend/.env`. ### Frontend Served by FastAPI Build the frontend from the `frontend` directory: ```bash bun run build ``` The build is written to `backend/app/frontend` and served by FastAPI at . Rebuild the frontend after making frontend changes. ## Full Stack with Docker Compose To run the backend and built frontend in Docker Compose: ```bash docker compose run --rm backend bash scripts/prestart.sh docker compose watch ``` Now you can open these URLs: Application, with the frontend and API served by FastAPI: Automatic interactive API documentation with Swagger UI: Adminer, database web administration: Traefik UI, to see how the routes are being handled by the proxy: Mailcatcher: 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 to be ready while the backend waits for the database and configures everything. To monitor it, use `docker compose logs`, or `docker compose logs backend` for the backend service. ## Mailcatcher 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 . ## Docker Compose in `localhost.tiangolo.com` When you start the Docker Compose stack, it uses `localhost` by default, with different ports for each service (backend, adminer, etc). When you deploy it to production (or staging), the application uses one domain. The frontend is served at `/` and the API lives under `/api`. In the guide about [deployment](deployment.md) you can read about Traefik, the configured proxy. That's the component in charge of transmitting traffic to the application service based on the domain. If you want to test that it's all working locally, you can edit the local `.env` file, and change: ```dotenv DOMAIN=localhost.tiangolo.com ``` That will be used by the Docker Compose files to configure the base domain for the services. Traefik will transmit application traffic at `localhost.tiangolo.com` to FastAPI, which serves both the frontend and API. The domain `localhost.tiangolo.com` is a special domain that is configured (with all its subdomains) to point to `127.0.0.1`. This way you can use that for your local development. After you update it, run again: ```bash docker compose watch ``` Traefik is included in the main Docker Compose file. The development overrides expose its local dashboard so you can inspect the routes used with `localhost.tiangolo.com`. ## Docker Compose files and env vars There is a main `compose.yml` file with all the configurations that apply to the whole stack, it is used automatically by `docker compose`. And there's also a `compose.override.yml` with overrides for development, for example to mount the source code as a volume. It is used automatically by `docker compose` to apply overrides 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. They also use some additional configurations taken from environment variables set in the scripts before calling the `docker compose` command. After changing variables, make sure you restart the stack: ```bash docker compose watch ``` ## The .env file The `.env` file contains the shared local defaults, generated keys, 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. Depending on your workflow, you could want to exclude it from Git, for example if your project is public. In that case, you would have to make sure to set up a way for your CI tools to obtain it while building or deploying your project. One way to do it could be to add each environment variable to your CI/CD system. ## Pre-commits and code linting we are using a tool called [prek](https://prek.j178.dev/) (modern alternative to [Pre-commit](https://pre-commit.com/)) for code linting and formatting. When you install it, it runs right before making a commit in git. This way it ensures that the code is consistent and formatted even before it is committed. You can find a file `.pre-commit-config.yaml` with configurations at the root of the project. #### Install prek to run automatically `prek` is already part of the dependencies of the project. After having the `prek` tool installed and available, you need to "install" it in the local repository, so that it runs automatically before each commit. Using `uv`, you could do it with (make sure you are inside `backend` folder): ```bash ❯ uv run prek install -f prek installed at `../.git/hooks/pre-commit` ``` The `-f` flag forces the installation, in case there was already a `pre-commit` hook previously installed. Now whenever you try to commit, e.g. with: ```bash git commit ``` ...prek will run and check and format the code you are about to commit, and will ask you to add that code (stage it) with git again before committing. Then you can `git add` the modified/fixed files again and now you can commit. #### Running prek hooks manually you can also run `prek` manually on all the files, you can do it using `uv` with: ```bash ❯ uv run prek run --all-files check for added large files..............................................Passed check toml...............................................................Passed check yaml...............................................................Passed fix end of files.........................................................Passed trim trailing whitespace.................................................Passed ruff.....................................................................Passed ruff-format..............................................................Passed biome check..............................................................Passed ``` ## URLs The production or staging URLs would use these same paths, but with your own domain. ### Development URLs Development URLs, for local development. Application: Automatic Interactive Docs (Swagger UI): Automatic Alternative Docs (ReDoc): Adminer: Traefik UI: MailCatcher: ### Development URLs with `localhost.tiangolo.com` Configured Development URLs, for local development. Application: Automatic Interactive Docs (Swagger UI): Automatic Alternative Docs (ReDoc): Adminer: Traefik UI: MailCatcher: