You can deploy the project to your own remote server with Docker Compose. The deployment configuration includes Traefik to handle HTTPS and route incoming traffic to 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, such as
fastapi-project.example.comandadminer.fastapi-project.example.com. - Install and configure Docker on the remote server (Docker Engine, not Docker Desktop).
rsync -av --exclude=".git/" --filter=":- .gitignore" ./ root@your-server.example.com:/root/code/app/The --filter=":- .gitignore" option tells rsync to use the same ignore rules as Git, excluding files such as the Python virtual environment.
Set the application domain, project name, and first superuser email:
export DOMAIN=fastapi-project.example.com
export PROJECT_NAME="Full Stack FastAPI Project"
export FIRST_SUPERUSER=admin@example.comYou can also configure these environment variables as needed:
SMTP_HOST: The SMTP server host from your email provider.SMTP_USER: The SMTP server user.EMAILS_FROM_EMAIL: The email account used to send emails.SENTRY_DSN: The DSN for Sentry.
Generate and set secure values for the database password, token signing key, and first superuser password:
export POSTGRES_PASSWORD="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
export SECRET_KEY="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
export FIRST_SUPERUSER_PASSWORD="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"To use an authenticated email provider, also set SMTP_PASSWORD.
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 -dThe compose.deploy.yml file adds HTTPS and automatic certificate handling to the shared compose.yml configuration. Explicitly listing both files excludes the local settings from compose.override.yml.
The backend Docker image builds the frontend, so the server does not need Bun or prebuilt frontend files.
The included .github/workflows/deploy-docker-compose.yml workflow runs the deployment commands on the server when manually triggered from GitHub Actions.
Use a self-hosted runner only for a repository whose contributors and workflow code you trust. GitHub recommends using self-hosted runners with private repositories because workflows execute directly on the runner machine.
In the repository, go to Settings > Secrets and variables > Actions and add these repository variables:
DOMAINPROJECT_NAMEFIRST_SUPERUSER
To enable emails, add these optional repository variables:
SMTP_HOSTSMTP_USEREMAILS_FROM_EMAIL
To enable Sentry, add the optional SENTRY_DSN repository variable.
Add these repository secrets:
POSTGRES_PASSWORDSECRET_KEYFIRST_SUPERUSER_PASSWORD
To use an authenticated email provider, add the optional SMTP_PASSWORD repository secret.
On the server, create a dedicated user and grant it access to Docker:
sudo adduser github
sudo usermod -aG docker github
sudo su - githubIn the GitHub repository, go to Settings > Actions > Runners, select New self-hosted runner, choose Linux, and follow the commands GitHub provides to download, configure, and register the runner. Install it in /home/github/actions-runner.
After registering the runner, exit the github user session and install the runner as a system service:
exit
cd /home/github/actions-runner
sudo ./svc.sh install github
sudo ./svc.sh start
sudo ./svc.sh statusSee GitHub's guides for adding a self-hosted runner and configuring the runner as a service.
When the runner is online, open the repository's Actions tab, select Deploy with Docker Compose, and select Run workflow.
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