Preview: Deploying applications on Machines with flyctl

We recently released Fly Machines - an API for directly launching and interacting with VMs worldwide.

We’ve started porting our standard deployment platform to use Machines! This will eventually replace the current deployment system, leading to faster deployments and more granular control over what happens at deploy time.

After grabbing the latest flyctl, fly machine launch will get you started and generate a fresh fly.toml. Then you can use fly deploy as you would normally. The default deployment strategy will update machines one by one.

Deployment is now orchestrated directly from flyctl. This means interrupting a deployment will leave your app in a weird state. This may sounds unusual, but flyctl is the testing ground for work on machines. It means you can see exactly how things work, and help guide the developer experience as features are added.

Evenutally, we’ll want to add more robust orchestration tooling on top of flyctl, once the experience feels right.

Check these out useful commands for working with individual machines:

fly machine update (useful for changing the VM size)
fly machine clone (useful for scaling your app or adding to other regions)
fly machine run (launch a machine directly into an app with specific config)
fly machine status (use -d to see details about an individual machine’s config)
fly machine start/stop

Now, the caveats!

Machine apps support:

  • fly ssh
  • fly secrets
  • [services] in fly.toml
  • [build] in fly.toml
  • [env] in fly.toml

Machine apps do not yet support:

  • release commands
  • specifying volumes in fly.toml
  • metrics
  • statics
  • fly vm commands
  • fly scale commands
  • Tracking releases
  • Saving application config to the Fly backend
  • Health checks

You might wonder how you can scale your app without fly scale. For now, you can use fly machine clone to make copies of existing machines, and to launch them in other regions. Then fly deploy will pick those up.

In the short term we plan to work on:

  • fly scale vm support
  • release_command support
  • Running multiple processes in groups of VMs under one app, aka process groups
  • more deployment strategies (only immediate and rolling are supported now

We release this is a major departure from how things work today, and that it’s raw. But we wanted to get it out there.

The new platform is an opportunity to work with customers to build the best experience possible - not just copy what we already did in the previous platform version. We look forward to your feedback and suggestions!


Hello. I was trying machines today and I got stock how start a vanilla ubuntu machine

I tried

fly machines run --port 80:8080/tcp:http --port 443:8080/tcp:http:tls --region mad --size shared-cpu-1x ubuntu:20.04

since I was planning to run a web server there but status is always stopped.

if I run the same command but I use the nginx:latest image it starts and I can ssh into it.


The VM needs to run a command in order to stay running, so you’d need to use an existing web server, or make a Dockerfile based on Ubuntu that installs what you need and runs the web server.

That command could just be something like tail -f /dev/null if you just want a generic VM to play around on. But for production usage, you’d want your web server to be the running command for various reasons.



Machine apps support:

[services] in fly.toml

Does that mean, request and connections parameters will be honoured by Fly proxy when forwarding packets to Machines?

For example, if I set hard_limit/soft_limit for connections/requests to 1, will a Machine then only serve one connection/http-request at a time?

From: How to spin up one fly machine per request?

1 Like

A few disparities between flyctl deploy and flyctl m run:

  1. Creating a new machine with flyctl m run --c <path/to/config> doesn’t respect primary_region set in the config and instead deploys to the region the wireguard peer is connected to (usually, the nearest one). flyctl deploy -c ... does respect the primary_region directive

  2. Also, flyctl m run -c </path/to/config> doesn’t seem to use any [env] vars from the config (as before, flyctl deploy -c ... does).

Incorrect behaviour with flyctl deploy -c a machine.

  1. Even though [services] section exists with ports and handlers defined in my config, flyctl deploy -c ... did not allocate a public-ip (neither v4 nor v6) address; but the documentation says otherwise.


flyctl deploy --app <app-name> --config <config> --image <img>
==> Verifying app config
--> Verified app config
==> Building image
Searching for image '<img>' remotely...
Error failed to fetch an image or build from source: Could not find image "<img>"

Couldn’t find a valid image for --app <app-name>. If I define the same <app-name> in the <config> file, it works fine.


flyctl deploy --app <app-name> --config <config> --remote-only
==> Verifying app config
--> Verified app config
==> Building image
Remote builder fly-builder-<yolo> ready
==> Creating build context
--> Creating build context done
==> Building image with Docker
--> docker host: 20.10.12 linux x86_64
[+] Building 64.3s (0/1)                                                                                                                                                            
[+] Building -1.6s (18/18) FINISHED                                                                                                                                                 
--> Building image done
==> Pushing image to fly
--> Pushing image done
image size: 000 MB
==> Creating release
Error This operation requires the 'nomad' app platform. This app was created for the  'machines' platform.

Didn’t work either, as it thought (wrong) that the Fly Machine app <app-name> was actually a regular Fly app: nomad? that’s just lame (:

Then, there’s this issue with flyctl deploy --strategy rolling timing out too: Error failed to wait for VM in started state: failed to wait for machine to be ready

1 Like

Just gave this a try to get better control over region placement. Deploying the initial app worked fine, but when I tried to clone it to another region as per the original post:

fly machine clone (useful for scaling your app or adding to other regions)

It fails with a rather unhelpful message:

Oops, something went wrong! Could you try that again?

Adding --verbose and/or --json flags seems to have no effect on the output.

Any ideas what could be happening? Or at least how I could get more useful debug information out of flyctl?

Another rather nasty bug I just ran into: I had my app set to use 2048MB memory and 2 shared cpus through fly machine update. But running fly deploy seems to have reset it to 1 shared cpu and 256MB memory.

flyctl m clone is either defunct or broken: flyctl machine clone is defunct?

There’s a bunch of nil pointer dereference in code because of the differences between regular Fly apps and Machine apps. I’ve seen this to be the cause of such error msgs.

If you want to, you can git clone flyctl, build it locally with go build -o fly2 and use that. fly2 should now show panics and stacktraces, unlike the prod version.

Yikes. Do report it here: Issues · superfly/flyctl · GitHub

1 Like