Skip to main content
Getting an application running on Fly.io is essentially working out how to package it as a deployable image. Once packaged it can be deployed to the Fly.io platform. In this guide we’ll learn how to deploy a Meteor application on Fly.io.
This guide is intended for users of Meteor 3. If you’re using Meteor 2 and want to migrate, please see the Meteor 3.0 migration guide.
Meteor is a full-stack JavaScript framework for building modern web and mobile applications. You get real-time features for free, built-in accounts, TypeScript support, and a powerful CLI tool for creating and managing your app. We’ll start off by installing Meteor:

Generate the Meteor app

We’ll assume you have NodeJS installed already. Meteor 3 requires NodeJS v20 or higher. We’ll be using a skeleton web application generated by Meteor. This is a bare-bones app that does not need a MongoDB database. Let’s create the new project by running meteor create. We’ll choose a “minimal” skeleton, which is a good choice for a new project and to get up and running quickly.

Preview your Application

You can preview your production build locally, simply by executing the command meteor.

Install flyctl and Login

We are ready to start working with Fly.io, and that means we need flyctl, our CLI app for managing apps on Fly.io. If you’ve already installed it, carry on. If not, hop over to our installation guide. Once that’s installed you’ll want to log in to Fly.io.

Deploy the app on Fly.io

Each Fly App needs a fly.toml file to tell the system how we’d like to deploy it. That file can be automatically generated with fly launch. This command will also generate a Dockerfile for deployment.

Inside fly.toml

The fly.toml file now contains a default configuration for deploying your app. In the process of creating that file, flyctl has also created a Fly.io application slot of the same name, “hello-meteor”. If we look at the fly.toml configuration file we can see the name in there:
We make sure to set the ROOT_URL and PORT environment variables. These are important to Meteor. When you eventually add a custom domain to your app, you’ll want to make sure your ROOT_URL is set to the domain name. The flyctl command will always refer to this file in the current directory if it exists, specifically for the app name/value at the start. That name will be used to identify the application to the Fly.io platform. The rest of the file contains settings to be applied to the application when it deploys.

Viewing the Deployed App

If you want to find out more about the deployment. The command fly status will give you all the essential details.

Connecting to the App

The quickest way to browse your newly deployed application is with the fly apps open command.
Your browser will be sent to the displayed URL.

Session Affinity (aka ‘Sticky Sessions’)

Sticky sessions are a feature of a load balancer that ensures that all requests from a client are routed to the same server. This can be important for Meteor applications depending on the client/server architecture of your app, as it ensures that the client is always connected to the same server, and that any changes made to the server are reflected in the client. The easiest way to achieve this on Fly.io is to run your app with a maximum of one Machine per region. The Fly Proxy will take care of load balancing clients — sending requests to the Machine closest to them. A better option, is to use dynamic request routing with the fly-replay response header. You’ll need to implement some additional code (roughly 18 lines) that uses the meteor/webapp package and plugs into your app’s server-side entry point. This example uses middleware to create a client-side cooking containing the Machine ID to “pin” requests to. The process is explained in greater detail here. First, install cookie-parser:
Now create a new file called sticky.js wherever you keep your server server-side code:
Make sure to import that module when initializing your Meteor server, then you should see clients routed to the same Fly Machine for the duration of the session.

Bonus Points

Let’s take a look at a slightly more advanced app that uses a MongoDB database for storing account details and user data — but also for real-time UI updates. First, we’ll need a MongoDB database to connect to. If you have one, great! If not, it’s easy to deploy a development MongoDB database on Fly.io. If you’re deploying a production app, we recommend that you look at a managed service like MongoDB Atlas. Save the below as your mongo.fly.toml, then run fly launch -c mongo.fly.toml --no-deploy to create the database app without deploying it.
Now, set the default username and password for the database:
And finally, deploy it:
Ok, now we can deploy our Meteor app. We’ll use the Simple Tasks example app:
This simultaneously clones the GitHub repo and launches the new app on Fly.io Set the MONGO_URL secret so Meteor knows where to connect to:
And deploy the app:
And finally, open the app. It’ll take a second longer on the first run while database migrations are performed:
That’s it! You should see the app running: A screenshot of the Simple Tasks Meteor app login page.

Arrived at Destination

You have successfully built, deployed, and connected to your first Meteor application on Fly.io.