Fly.io#

Pegasus supports container-based deployment to Fly.io.

Prerequisites#

If you haven’t already, install the flyctl CLI.

The create an account with fly auth signup or login with fly auth login.

Setup#

Once you have logged in via the CLI you can create your app and the services it will need. For each of the commands below follow the prompts given.

In the example below the “Chicago, Illinois (US) (ord)” region is selected. You may change the region to suit your needs, but it should be consistent throughout the commands.

  1. Create your app in Fly.io

$ fly launch --dockerfile Dockerfile.web \
      --dockerignore-from-gitignore \
      --no-deploy \
      --name {app-name} \
      --region ord

After running that, answer ‘yes’ to the first question:

An existing fly.toml file was found for app {app-name}
? Would you like to copy its configuration to the new app? Yes

Fly will output some details, then ask another question about customizing. Answer ‘yes’ to that as well:

Using dockerfile Dockerfile.web
Creating app in /path/to/app/source

We're about to launch your app on Fly.io. Here's what you're getting:

Organization: Your Name              (fly launch defaults to the personal org)
Name:         {app-name}             (specified on the command line)
Region:       Chicago, Illinois (US) (specified on the command line)
App Machines: shared-cpu-1x, 1GB RAM (most apps need about 1GB of RAM)
Postgres:     <none>                 (not requested)
Redis:        <none>                 (not requested)

? Do you want to tweak these settings before proceeding? (y/N) Yes

A browser tab should open where you should add a Fly Postgres database called {app-name}-db, and an Upstash Redis server. You can leave the other defaults or change the machine size as you see fit. It should look something like this:

Fly DB config

Click “Confirm Settings” and then close the tab. Back on the command line, Fly will output some more things and should eventually end with a message like this:

✓ Configuration is valid
Your app is ready! Deploy with `flyctl deploy`

If you see these two lines you are ready to deploy! If not, see the “Troubleshooting” section below.

Deploying#

You are now ready to deploy your app. You can do this by running:

$ fly deploy

In a few minutes your app should be live! After deploying, review the production checklist for a list of common next steps

Running Database Migrations#

Database migrations are applied in the release command during deploy. This is configured in the fly.toml file.

Settings and Secrets#

Fly.io builds use the settings_production.py file. You can add settings here or in the base settings.py file, and use environment variables to manage any secrets, following the examples in these files.

Secrets are managed in Fly.io via the web UI or on the command line using the CLI:

$ fly secrets set MY_VAR=secret_value

Running One-Off Commands#

You can one-off commands via a shell:

$ fly ssh console

app $ ./code/manage.py [command]

Celery Support#

Out of the box, Pegasus is configured to run Celery using the multiprocess support provided by Fly.io.

For alternatives see https://fly.io/docs/app-guides/multiple-processes/

Troubleshooting#

My release / migrate command is failing.

If you get an error like the following when running fly deploy

  django.db.utils.OperationalError: connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
  	Is the server running on that host and accepting TCP/IP connections?

it is likely that your Database is not set up properly. You can confirm if this is the case by running fly secrets list and making sure that you see a DATABASE_URL variable. If you do not see one, it is not properly connected/attach.

If you need to create a new database, you can run:

fly postgres create --name {your-app-db}

And you can (re-)attach a database to an app by running:

fly postgres attach {your-app-db} -a {your-app-name}

My deploy keeps timing out.

If you keep getting an error like the following:

Error: timeout reached waiting for health checks to pass for machine 28749e0b443558

You can try re-deploying with a higher timeout. For example, try running:

flyctl deploy --wait-timeout 5m