Skip to content
dply/edge

Guides

Migrate from Fly.io

Move a Fly.io app to dply: build the same Dockerfile, set the port, copy secrets, replace Fly databases with dply resources, and switch the domain.

This guide is for apps that run on Fly Machines today. dply doesn't read fly.toml, but it builds your Dockerfile as it is, so most Fly apps run unchanged as container apps that sleep when idle.

How the pieces map

Fly.io dply
App A container app
Dockerfile Built as it is
fly.toml Not read. Move the settings you need by hand (see below)
[http_service] internal_port The EXPOSE port in your Dockerfile
[deploy] release_command The release command: build.release in dply.yaml (Configuration files)
[env] Environment (Environment variables)
Secrets Environment
[processes] The web process is the app; others become Queue workers (Queue workers)
Machines, auto_stop_machines, min_machines_running Instances, Sleeps after and Min instances (Scaling & sleep)
Regions Data regions
Volumes Not available. Use object storage
Managed Postgres dply Postgres (Postgres, MySQL & MongoDB)
Upstash Redis dply Valkey (Valkey (Redis))
fly ssh console The app's Console, or dply-edge ssh from the CLI
*.fly.dev The app's *.on-dply.live hostname (Domains)

1. Check the port

dply sends traffic to the first EXPOSE port in your Dockerfile, or 8080 when there isn't one. Fly uses internal_port from fly.toml instead, so many Fly Dockerfiles have no EXPOSE. Add one with the port your app listens on:

dockerfile
EXPOSE 3000

A Procfile web: line doesn't change the start command of your own Dockerfile; its CMD is used. A release: line still runs. See Procfile.

2. Deploy the app

  1. Choose New app, connect your source control, and select the repository and branch.
  2. Check that dply found the Dockerfile and shows App, then choose Deploy.

If fly.toml has a release_command, add it to dply.yaml:

yaml
build:
  release: bin/rails db:migrate

3. Copy secrets and environment

fly secrets list shows only names and digests, not values. Take the values from where you keep them, or print them from a running Machine:

bash
fly ssh console -C printenv

Copy the [env] values from fly.toml too. Paste everything into Environment on dply as KEY=value lines. Leave out DATABASE_URL and REDIS_URL: dply sets them from the resources you attach next.

4. Attach resources

On the app's Overview, choose Add resource and add a Database for Postgres and dply Valkey for Redis. Add Queue workers for each extra process group. Redeploy so the app receives the new variables.

5. Move the database

  1. Stop writes to the Fly app.

  2. Open a tunnel with fly proxy (or use your managed database's connection string) and export:

    bash
    pg_dump --no-owner --no-acl -Fc "$FLY_DATABASE_URL" > app.dump
    
  3. Open the database from the app's Overview. Under Export and import, choose Get upload command, run it where app.dump is, then choose Load it.

See Postgres, MySQL & MongoDB.

6. Switch the domain

  1. Check the app on its on-dply.live address.
  2. Add the domain under Routing, Domains.
  3. Lower the TTL on the existing record, then replace the A and AAAA records pointing at Fly with the CNAME target dply shows. Apex domains need an ALIAS, ANAME or flattened CNAME at most DNS providers.
  4. Choose Verify DNS and wait for TLS to be active.
  5. Remove the certificate from Fly with fly certs remove, then scale the app to zero.

See Domains.

Next steps

View as Markdown llms.txt

dply/edge