meal-checker

FastAPI Project - Deployment

You can deploy the project using Docker Compose to a remote server.

This project expects you to have a Traefik proxy handling communication to the outside world and HTTPS certificates.

You can use CI/CD (continuous integration and continuous deployment) systems to deploy automatically, there are already configurations to do it with GitHub Actions.

But you have to configure a couple things first. 🤓

Preparation

Public Traefik

We need a Traefik proxy to handle incoming connections and HTTPS certificates.

You need to do these next steps only once.

Traefik Docker Compose

mkdir -p /root/code/traefik-public/

Copy the Traefik Docker Compose file to your server. You could do it by running the command rsync in your local terminal:

rsync -a compose.traefik.yml root@your-server.example.com:/root/code/traefik-public/

Traefik Public Network

This Traefik will expect a Docker “public network” named traefik-public to communicate with your stack(s).

This way, there will be a single public Traefik proxy that handles the communication (HTTP and HTTPS) with the outside world, and then behind that, you could have one or more stacks with different domains, even if they are on the same single server.

To create a Docker “public network” named traefik-public run the following command in your remote server:

docker network create traefik-public

Traefik Environment Variables

The Traefik Docker Compose file expects some environment variables to be set in your terminal before starting it. You can do it by running the following commands in your remote server.

export USERNAME=admin
export PASSWORD=changethis
export HASHED_PASSWORD=$(openssl passwd -apr1 $PASSWORD)

To verify that the hashed password is correct, you can print it:

echo $HASHED_PASSWORD
export DOMAIN=fastapi-project.example.com
export EMAIL=admin@example.com

Note: you need to set a different email, an email @example.com won’t work.

Start the Traefik Docker Compose

Go to the directory where you copied the Traefik Docker Compose file in your remote server:

cd /root/code/traefik-public/

Now with the environment variables set and the compose.traefik.yml in place, you can start the Traefik Docker Compose running the following command:

docker compose -f compose.traefik.yml up -d

Deploy the FastAPI Project

Now that you have Traefik in place you can deploy your FastAPI project with Docker Compose.

Note: You might want to jump ahead to the section about Continuous Deployment with GitHub Actions.

Copy the Code

rsync -av --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.

Environment Variables

You need to set some environment variables first.

Generate secret keys

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:

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.

Required Environment Variables

Set the ENVIRONMENT, by default local (for development), but when deploying to a server you would put something like staging or production:

export ENVIRONMENT=production

Set the DOMAIN, by default localhost (for development), but when deploying you would use your own domain, for example:

export DOMAIN=fastapi-project.example.com

Set the POSTGRES_PASSWORD to something different than changethis:

export POSTGRES_PASSWORD="changethis"

Set the SECRET_KEY, used to sign tokens:

export SECRET_KEY="changethis"

Note: you can use the Python command above to generate a secure secret key.

Set the FIRST_SUPER_USER_PASSWORD to something different than changethis:

export FIRST_SUPERUSER_PASSWORD="changethis"

Set the BACKEND_CORS_ORIGINS to include your domain:

export BACKEND_CORS_ORIGINS="https://dashboard.${DOMAIN?Variable not set},https://api.${DOMAIN?Variable not set}"

You can set several other environment variables:

GitHub Actions Environment Variables

There are some environment variables only used by GitHub Actions that you can configure:

Deploy with Docker Compose

With the environment variables in place, you can deploy with Docker Compose:

cd /root/code/app/
docker compose -f compose.yml build
docker compose -f compose.yml up -d

For production you wouldn’t want to have the overrides in compose.override.yml, that’s why we explicitly specify compose.yml as the file to use.

Continuous Deployment (CD)

You can use GitHub Actions to deploy your project automatically. 😎

You can have multiple environment deployments.

There are already two environments configured, staging and production. 🚀

Install GitHub Actions Runner

sudo adduser github
sudo usermod -aG docker github
sudo su - github
cd

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:

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):

sudo su
cd /home/github/actions-runner
./svc.sh install github
./svc.sh start
./svc.sh status

You can read more about it in the official guide: Configuring the self-hosted runner application as a service.

Set Secrets

On your repository, configure secrets for the environment variables you need, the same ones described above, including SECRET_KEY, etc. Follow the official GitHub guide for setting repository secrets.

The current Github Actions workflows expect these secrets:

GitHub Action Deployment Workflows

There are GitHub Action workflows in the .github/workflows directory already configured for deploying to the environments (GitHub Actions runners with the labels):

If you need to add extra environments you could use those as a starting point.

URLs

Replace fastapi-project.example.com with your domain.

Main Traefik Dashboard

Traefik UI: https://traefik.fastapi-project.example.com

Production

Frontend: https://dashboard.fastapi-project.example.com

Backend API docs: https://api.fastapi-project.example.com/docs

Backend API base URL: https://api.fastapi-project.example.com

Adminer: https://adminer.fastapi-project.example.com

Staging

Frontend: https://dashboard.staging.fastapi-project.example.com

Backend API docs: https://api.staging.fastapi-project.example.com/docs

Backend API base URL: https://api.staging.fastapi-project.example.com

Adminer: https://adminer.staging.fastapi-project.example.com