Migrate from Fly.io

Fly.io and Temps are both container-first platforms, so your Dockerfile works as-is. The key differences are deployment model (Fly distributes apps globally across edge nodes; Temps runs on a single VPS or multi-node cluster you control) and managed services (Fly Postgres, Redis, and volumes become Temps equivalents).


What Transfers Without Changes

FeatureFly.ioTemps
DockerfileFly builds and runs itTemps builds and runs it — same Dockerfile
HTTPSAutomaticSame — Let's Encrypt, auto-renewed
Environment variables (secrets)fly secrets setTemps dashboard or temps env set
Health checks[checks] in fly.tomlConfigurable health check path in project settings
Private networkingWireGuard meshLocalhost — services on the same server share a private network
TCP/UDP services[[services]] in fly.tomlPort mapping in project settings

What Needs an Alternative

Fly featureTemps equivalent
Fly PostgresTemps managed Postgres or external (Neon, Supabase)
Fly Redis (Upstash)Temps managed Redis
Fly VolumesProject volumes (VPS-mounted directories)
Multi-region deploymentMulti-node Temps (advanced)
flyctl CLItemps CLI or @temps-sdk/cli
fly.tomlTemps project settings (dashboard or CLI)
Machine scaling (scale to zero)Configurable replicas in project settings

Pre-Migration Checklist

  • SSH access to a VPS running Ubuntu 22.04+ (choosing a server)
  • Domain name with DNS access
  • Fly secrets exported (see Step 1)
  • Fly Volumes data backed up (see Step 3)
  • Fly Postgres backup taken (see Step 2)

Step 1: Export Secrets (Environment Variables)

# List all secrets — values are hidden but names are visible
fly secrets list --app YOUR_APP_NAME

# Fly does not expose secret values via CLI for security.
# Retrieve them from your original source (e.g. .env file, 1Password, etc.)
# or from your app's configuration.

Note which secrets reference Fly-specific infrastructure:

Fly secretAction
DATABASE_URLReplace with new Postgres URL after migration
REDIS_URLReplace with new Redis URL after migration
FLY_APP_NAMERemove — Fly-specific
FLY_REGIONRemove — Fly-specific
FLY_PUBLIC_IPRemove — replace with your VPS IP if needed
PRIMARY_REGIONRemove — not applicable

Step 2: Migrate Your Database

Export from Fly Postgres

# Open a proxy to your Fly Postgres instance
fly proxy 5433:5432 -a YOUR_POSTGRES_APP &

# Export the database
pg_dump "postgresql://postgres:PASSWORD@localhost:5433/YOUR_DB" \
  --no-acl \
  --no-owner \
  -Fc \
  -f fly_backup.dump

# Close the proxy
kill %1

Find your Fly Postgres password in:

fly secrets list -a YOUR_POSTGRES_APP
# Look for DATABASE_URL — it contains the password

Set Up the New Database

Option A — Temps managed Postgres (recommended for simplicity):

  1. In the Temps dashboard, go to Managed Services → New Service → PostgreSQL
  2. Copy the connection string shown after creation

Option B — External Postgres: Create a database at Neon, Supabase, or any hosted provider.

Restore

pg_restore \
  --clean \
  --if-exists \
  -d "$NEW_DATABASE_URL" \
  fly_backup.dump

Verify the restore by checking row counts on your most important tables before cutting over.


Step 3: Migrate Fly Volumes

Fly Volumes are persistent disks attached to your Machines. On Temps, use project volumes instead.

First, copy your volume data while Fly is still running:

# SSH into your Fly Machine
fly ssh console -a YOUR_APP_NAME

# Compress the volume data
tar -czf /tmp/volume_backup.tar.gz /path/to/your/volume

# Exit the console
exit

# Copy the archive to your local machine
fly sftp get /tmp/volume_backup.tar.gz ./fly_volume_backup.tar.gz -a YOUR_APP_NAME

Then, after deploying to Temps:

# Copy the archive to your VPS
scp fly_volume_backup.tar.gz user@YOUR_VPS_IP:/tmp/

# SSH into your VPS and extract it to the mounted volume path
ssh user@YOUR_VPS_IP
tar -xzf /tmp/fly_volume_backup.tar.gz -C /path/to/temps/volume/

In the Temps dashboard: Project → Settings → Volumes → Add Volume, and mount at the same path your app uses.


Step 4: Reuse Your Dockerfile

Your existing Dockerfile works on Temps without changes. Temps detects it automatically when you connect your repository.

If your fly.toml has a custom build context or build args, set those in Project → Settings → Build Arguments.

# fly.toml — what you had
[build]
  build-target = "production"
  [build.args]
    NODE_ENV = "production"

In Temps project settings, add build argument NODE_ENV=production.


Step 5: Map fly.toml to Temps Settings

fly.toml settingTemps equivalent
internal_portPort in project settings (default 8080)
[[services.http_checks]]Health check path in project settings
[processes]Process command in project settings
min_machines_runningMinimum replicas in scaling settings
auto_stop_machinesScale-to-zero in scaling settings

Step 6: Install Temps and Deploy

Install Temps on your server:

curl -fsSL https://temps.sh/deploy.sh | bash

Then:

  1. Go to Projects → New Project in the Temps dashboard
  2. Connect your Git repository
  3. Temps detects your Dockerfile automatically
  4. Add your environment variables (update DATABASE_URL to your new database)
  5. Click Deploy

Your app gets a preview URL. Test it before cutting over DNS.


Step 7: Cut Over DNS

Once your app works on the Temps preview URL:

  1. Go to Project → Settings → Domains → Add Domain
  2. Enter your domain
  3. Add the DNS records Temps shows you

In your DNS provider:

TypeNameValue
Aapp (or @ for root)YOUR_SERVER_IP

Lower your DNS TTL to 60 seconds before the cutover so you can revert quickly.

Keep your Fly app running for 48 hours after cutting over DNS as a fallback.


Multi-Region

Fly.io's main advantage over a single-server setup is global distribution. On Temps, apps run on a single VPS by default. Options if you need multi-region:

  • CDN for static assets — put Cloudflare in front of your Temps instance for free
  • Multi-node Temps — see the Multi-node guide for running Temps across multiple servers
  • Keep non-latency-sensitive apps on Temps, latency-critical on Fly — Temps and Fly are not mutually exclusive

For most apps, a single well-located VPS with a CDN is sufficient.


Next Steps

Was this page helpful?