|
| 1 | +# FastAPI Project - Docker Compose Deployment |
| 2 | + |
| 3 | +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. |
| 4 | + |
| 5 | +## Preparation |
| 6 | + |
| 7 | +* Have a remote server ready and available. |
| 8 | +* 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.com` and `adminer.fastapi-project.example.com`. |
| 9 | +* Install and configure [Docker](https://docs.docker.com/engine/install/) on the remote server (Docker Engine, not Docker Desktop). |
| 10 | + |
| 11 | +## Copy the Code |
| 12 | + |
| 13 | +```bash |
| 14 | +rsync -av --exclude=".git/" --filter=":- .gitignore" ./ root@your-server.example.com:/root/code/app/ |
| 15 | +``` |
| 16 | + |
| 17 | +The `--filter=":- .gitignore"` option tells `rsync` to use the same ignore rules as Git, excluding files such as the Python virtual environment. |
| 18 | + |
| 19 | +## Configure the Application |
| 20 | + |
| 21 | +### Environment Variables |
| 22 | + |
| 23 | +Set the application domain, project name, and first superuser email: |
| 24 | + |
| 25 | +```bash |
| 26 | +export DOMAIN=fastapi-project.example.com |
| 27 | +export PROJECT_NAME="Full Stack FastAPI Project" |
| 28 | +export FIRST_SUPERUSER=admin@example.com |
| 29 | +``` |
| 30 | + |
| 31 | +You can also configure these environment variables as needed: |
| 32 | + |
| 33 | +* `SMTP_HOST`: The SMTP server host from your email provider. |
| 34 | +* `SMTP_USER`: The SMTP server user. |
| 35 | +* `EMAILS_FROM_EMAIL`: The email account used to send emails. |
| 36 | +* `SENTRY_DSN`: The DSN for Sentry. |
| 37 | + |
| 38 | +### Secrets |
| 39 | + |
| 40 | +Generate and set secure values for the database password, token signing key, and first superuser password: |
| 41 | + |
| 42 | +```bash |
| 43 | +export POSTGRES_PASSWORD="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" |
| 44 | +export SECRET_KEY="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" |
| 45 | +export FIRST_SUPERUSER_PASSWORD="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" |
| 46 | +``` |
| 47 | + |
| 48 | +To use an authenticated email provider, also set `SMTP_PASSWORD`. |
| 49 | + |
| 50 | +## Deploy |
| 51 | + |
| 52 | +```bash |
| 53 | +cd /root/code/app/ |
| 54 | +docker compose -f compose.yml -f compose.deploy.yml build |
| 55 | +docker compose -f compose.yml -f compose.deploy.yml run --rm backend bash scripts/prestart.sh |
| 56 | +docker compose -f compose.yml -f compose.deploy.yml up -d |
| 57 | +``` |
| 58 | + |
| 59 | +The `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`. |
| 60 | + |
| 61 | +The backend Docker image builds the frontend, so the server does not need Bun or prebuilt frontend files. |
| 62 | + |
| 63 | +## Deploy with GitHub Actions |
| 64 | + |
| 65 | +The included `.github/workflows/deploy-docker-compose.yml` workflow runs the deployment commands on the server when manually triggered from GitHub Actions. |
| 66 | + |
| 67 | +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. |
| 68 | + |
| 69 | +### Configure Repository Variables and Secrets |
| 70 | + |
| 71 | +In the repository, go to **Settings** > **Secrets and variables** > **Actions** and add these repository variables: |
| 72 | + |
| 73 | +* `DOMAIN` |
| 74 | +* `PROJECT_NAME` |
| 75 | +* `FIRST_SUPERUSER` |
| 76 | + |
| 77 | +To enable emails, add these optional repository variables: |
| 78 | + |
| 79 | +* `SMTP_HOST` |
| 80 | +* `SMTP_USER` |
| 81 | +* `EMAILS_FROM_EMAIL` |
| 82 | + |
| 83 | +To enable Sentry, add the optional `SENTRY_DSN` repository variable. |
| 84 | + |
| 85 | +Add these repository secrets: |
| 86 | + |
| 87 | +* `POSTGRES_PASSWORD` |
| 88 | +* `SECRET_KEY` |
| 89 | +* `FIRST_SUPERUSER_PASSWORD` |
| 90 | + |
| 91 | +To use an authenticated email provider, add the optional `SMTP_PASSWORD` repository secret. |
| 92 | + |
| 93 | +### Install a Self-Hosted Runner |
| 94 | + |
| 95 | +On the server, create a dedicated user and grant it access to Docker: |
| 96 | + |
| 97 | +```bash |
| 98 | +sudo adduser github |
| 99 | +sudo usermod -aG docker github |
| 100 | +sudo su - github |
| 101 | +``` |
| 102 | + |
| 103 | +In 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`. |
| 104 | + |
| 105 | +After registering the runner, exit the `github` user session and install the runner as a system service: |
| 106 | + |
| 107 | +```bash |
| 108 | +exit |
| 109 | +cd /home/github/actions-runner |
| 110 | +sudo ./svc.sh install github |
| 111 | +sudo ./svc.sh start |
| 112 | +sudo ./svc.sh status |
| 113 | +``` |
| 114 | + |
| 115 | +See GitHub's guides for [adding a self-hosted runner](https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/add-runners) and [configuring the runner as a service](https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/configure-the-application?platform=linux). |
| 116 | + |
| 117 | +### Run the Deployment |
| 118 | + |
| 119 | +When the runner is online, open the repository's **Actions** tab, select **Deploy with Docker Compose**, and select **Run workflow**. |
| 120 | + |
| 121 | +## URLs |
| 122 | + |
| 123 | +Replace `fastapi-project.example.com` with your domain. |
| 124 | + |
| 125 | +Application (frontend and API): `https://fastapi-project.example.com` |
| 126 | + |
| 127 | +Interactive API docs: `https://fastapi-project.example.com/docs` |
| 128 | + |
| 129 | +Adminer: `https://adminer.fastapi-project.example.com` |
0 commit comments