Deploying on Fly.io
Christopher De Vries
January 17, 2023
A while ago I deployed this blog to [Fly.io][fly] as a small exercise to gain
some experience with the platform, but this is just a static blog that can be
deployed on any static hosting site. In order to learn more, I decided to
deploy a small project, PostNewsRSS, to [Fly.io][fly] to get a better idea of how well it performs and how
easy it is to use.
What is Fly.io and what does it cost?
[Fly.io][fly] is a PaaS service with servers in 26 locations around the world.
Their service is based in building and deploying a docker container, but rather
that deploy it as a container in a host operating system, they deploy each
container as a separate [firecracker microVM][firecracker]. This creates additional
isolation between adjacent services as no two deployed apps use the same kernel.
[Fly][fly] also deploys their own hardware to datacenters, which allows them to
potentially charge cheaper compute, storage, and bandwidth rates than they
could if they also relied on cloud services such
as [AWS][aws], [GCP][gcp], or [Azure][azure]. Compute does seem to be fairly
competitively priced with a single shared CPU with 1 Gigabyte of RAM costing
$5.70 a month on [Fly][fly]. Similar VMs at GCP would run around $6.03 for
[GCP][gcp] (e2-micro VM), and $6.05 on [AWS][aws] (t4g.micro). Dedicated
compute at [Fly][fly] is a much higher price with a 2 CPU with 4 Gigabytes of RAM
solution running $62 a month versus $24.12 for [GCP][gcp] (e2-medium) and
$24.19 on [AWS][aws] (t4g.medium).
Volume storage runs $0.15 per Gigabyte per Month which compares favorably to
[GCP][gcp]'s SSD price of $0.17 per Gigabyte per Month, but is higher than
[Amazon][aws]'s $0.125 per Gigabyte per Month io2 provisioned SSDs. Overall
these prices are fairly similar. Outbound data transfer runs from $0.02 per GB
to $0.12 per GB depending on region, compared to between $0.12 per GB and $0.23
per GB for [Google][gcp] and $0.09 per GB for [Amazon][aws]. [Fly][fly] also
offers a generous free tier which includes up to 3 shared 1 CPU VMs with 256
Megabytes of RAM, 3 Gigabytes of volume storage, and 160 Gigabytes of outbound
data transfer, which is definitely enough to get started.
In addition to basic compute, they also offer a
semi-managed
Postgres database service. I have not taken advantage of this service yet, and
would recommend keeping an eye on the work they are doing with distributed
sqlite. They also offer managed redis
through [upstash]. I have not tried any of these services, so I cannot evaluate
them right now.
One interesting approach [Fly.io][fly] has to pricing is that they offer in
addition to the "Hobby" (pay-as-you-go) pricing. [Fly][fly] has support tiers with
fixed monthly rates, however they also come with an equivalent amount of usage
included. So for example if you were to reliably use over $29 a month in resources,
it would behoove you to buy the "Launch" plan which costs $29 a month, and
includes $29 a month in usage. This would give you access to email support at
no additional cost. At the $199 a month level is the "Scale" plan which includes
$199 a month in usage, priority email support, and some compliance assistance.
This includes signing a BAA under HIPAA as well as filling out the security
controls they are responsible for in a NIST 800-53 type form. There is also
an "Enterprise" level which includes additional compliance and support levels
including an SLA. If you need this level, you know it, and have to negotiate for
the price.
What is the developer experience?
For my blog, I deployed a simple Docker container running [nginx] using the
[flyctl] command line client. Running flyctl launch will do an analysis of
the project and create a fly.toml configuration file you can edit. Then
flyctl deploy will deploy your project. It will be sent to a free build
instance which will do the docker build and send the image to a private fly
docker image repository. Then the project will be deployed as microVMs in one or
more regions depending on how you scale the project. This is a relatively fast
and smooth process for my blog.
The [PostNewsRSS][postnewsrss] project is written in [Go] and will generate an RSS
feed on the fly by querying the [post.news][postnews] API. For this project I
decided to use [paketo buildpacks][paketo] which are the default for many programming
languages detected by [flyctl]. I deployed this service to two regions to allow
for some geographic diversity and to potentially have no downtime should one
region go down. When I first deployed I thought I had a problem, because the build
seemed to hang for several minutes after downloading the paketo build images.
Eventually the compilation phase starts, but for several minutes it appears there
is little or no progress. I am not sure why there is
this delay, but it seems pretty consistent for me, even after I destroyed and
redeployed my build server. It is not a showstopper at all, but it is something
to be aware of. During a build the old version of the application remains up, so
it does not cause any downtime, but it does mean that a deployment will take up
to 10 minutes.
You can review the logs of the application using the flyctl CLI as well as on
the [Fly.io][fly] dashboard, but one of the major benefits of the platform is
that a wide variety of [metrics] are available and can be queried using [PromQL].
This means it is trivial to attach a Grafana dashboard to an application for
monitoring. [Fly.io][fly] will also gather custom metrics from your application
every 15 seconds and save those metrics for approximately 3 days. For my application
I set up metrics to monitor the count of the number of times queries were throttled
from individual IP addresses as well as metrics to measure the success and
response codes from queries made by my application to the upstream [post.news][postnews]
servers. The metrics can be served on a separate port from the web service to
keep them private, and if you want to save them for a longer time period, [Fly][fly]
exposes the prometheus federation endpoint allowing you to copy the data into a
private prometheus or influxdb database. This custom metrics service allows for
a lot of flexibility in monitoring and is a major benefit to the platform.
Final thoughts
I really enjoy using [Fly.io][fly] and I will keep it in mind for future projects.
I agree with this post that
[Fly.io][fly] is a very good successor to Heroku and encourage anyone looking for
a PaaS platform to give it a try. I am also happy to count it among several moderate
size companies creating deployment platforms that can compete with the big cloud
providers by offering a tremendous developer experience in a specific cloud
technology, rather than offering a catalog of generalized cloud services.
[fly]: https://fly.io/
[firecracker]: https://firecracker-microvm.github.io/
[aws]: https://aws.amazon.com/
[gcp]: https://cloud.google.com/
[azure]: https://azure.microsoft.com/
[nginx]: https://www.nginx.com/
[flyctl]: https://fly.io/docs/hands-on/
[postnewsrss]: https://postnewsrss.unnecessary.tech/
[postnews]: https://post.news/
[upstash]: https://upstash.com/
[Go]: https://go.dev/
[paketo]: https://paketo.io/
[metrics]: https://fly.io/docs/reference/metrics/
[PromQL]: https://prometheus.io/docs/prometheus/latest/querying/basics/
Discussion in the ATmosphere