Skip to main content
Illustration by Annie Ruygt of a flag depicting a Hello World app 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 static site on Fly.io. In this demonstration, we’ll use nginx, the world’s most popular web server to serve a few static files with very little configuration. We’ll provide a Dockerfile and our content for Fly to transmogrify into a web server running in a VM. You can clone all the files needed for this example from the hello-static GitHub repository to a local directory:
Alternatively, you can create all the files manually as you work through this guide.

Install flyctl and login

To configure our application and deploy it on Fly.io, we need flyctl, our CLI app for managing apps on Fly. 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.

Putting the app together

At this point, if you have a local clone of the hello-static repository, you could go ahead and run fly launch from its root directory and get the static site deployed without further ado. But that wouldn’t be very illuminating. Let’s go through what’s included in the example repository and why. If you cloned the repository, your new app already has its own directory. Otherwise, create one. This isn’t just for tidiness, or for letting flyctl detect your app by the fly.toml in the working directory (although these are good reasons). It also ensures that no extra files get included in the build context when the Docker image gets built. We’ll do everything from within this directory:

The Site

Our example will be a simple static site. That can be as trivial as a single index.html file. Let’s make it only slightly more complicated by writing two HTML files and having them link to each other. Put these HTML files into a subdirectory of their own, called public. Files in this directory are the ones our nginx server will serve. Create the hello-static/public directory if needed. Here’s index.html, which is the landing page:
Here’s goodbye.html.

The Dockerfile

nginx can be run in a container, and the official nginx image is available on Docker Hub. This is super convenient for us, because Fly apps use container images! We can use the nginx image as a base image. We just have to copy our site’s files to /usr/share/nginx/html in the image. Here’s our Dockerfile to do that:
The Dockerfile should be placed in the working directory (here, hello-static).

Configuring the App for Fly.io

We set the initial configuration for the app by running flyctl launch. This takes care of setting the app name, the Fly.io organization it belongs to, and a region to deploy to. It also generates a fly.toml file with more configuration settings. The hello-static repository contains a fly.toml that will be detected by flyctl launch; you can use it to configure your app. Otherwise, a new fly.toml will be generated with flyctl launch, and we can edit it.
This has configured the app with some default parameters, generated a fly.toml, attached a shared IPv4, created a dedicated IPv6, and deployed our image file for us. Before the app will work though, we need to do one more thing. nginx listens on port 80 by default, but the default fly.toml assumes port 8080. Edit internal_port in the services section to reflect this:
Now we’re ready to deploy:
The output should end something like this, if everything has gone well:

Viewing your static site

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