Fly.io is a cloud platform for hosting and deploying applications. Its simplicity, performance and affordable pricing make it a no-brainer choice for startups and works very well as a replacement for Heroku. In this post we will show how to deploy a Buffalo application to Fly.io.
Initializing the Buffalo application
Initializing a Buffalo application implies running the new
command on the Buffalo cli. To make things simpler we will create a SQLite application
> buffalo new --db-type sqlite3 flyapp
Which will generate the base source for our application in the flyapp
folder.
DEBU[2022-06-11T10:27:23-05:00] Step: 5d32fdc6
DEBU[2022-06-11T10:27:23-05:00] Chdir: /Users/users/code/wawandco/flyapp
...
INFO[2022-06-11T10:28:05-05:00] Congratulations! Your application, flyapp, has been successfully generated!
INFO[2022-06-11T10:28:05-05:00] You can find your new application at: /Users/user/code/wawandco/flyapp
INFO[2022-06-11T10:28:05-05:00] Please read the README.md file in your new application for next steps on running your application.
From this point we can start our application locally with the buffalo dev
command. Which is ok but we talked about deploying our application to Fly.io, So let’s do that.
Configuring Fly.io
Now that our application has been created we should setup a few things to run our application on Fly.io.
As we mentioned before, we have taken the route of deploying a SQLite application to Fly.io. Which means that our database will live in a file. To keep that file (and our application data) safe across deployments we will need to use a volume
that will be mounted to the Fly.io container.
Installing the CLI
First step is to install the Fly.io CLI. If (like me) you’re on a Mac you can use Homebrew to install it with the following command:
> brew install flyctl
Other than that you can use the install script on the Fly.io website.
> curl -L https://fly.io/install.sh | sh
Or just refer to the Fly.io documentation for more information.
Authenticating
Once you have the CLI installed you can authenticate to Fly.io. This is done by running the following command:
> fly auth login
Which will open a browser window and ask you to authenticate to Fly.io. With that we should be all-set to deploy our application.
Initializing the Fly.io application
Creating the Application
After all of the configuration steps we can initialize our application. This is done by running the following command:
> fly create flyapp-demo
New app created: flyapp-demo
Which will create the application in our Fly.io personal organization.
Creating the volume
As we mentioned we need to create a volume that will store our data. This is done by running the following command:
> fly volumes create flyappdata -a flyapp-demo
It will ask for the region where that volume should live. In this case we will use the same region as the application: Miami, Florida (US) (mia)
.
Adding fly.toml
In our repository we will need to have a file (fly.toml
) which will contain the configuration for our application, the Fly.io platform will read this file for instructions.
In our codebase we should create a fly.toml
file with the following content:
app = "flyapp-demo"
kill_signal = "SIGINT"
kill_timeout = 1
processes = []
[deploy]
strategy = "rolling"
[env]
GO_ENV = "production"
[experimental]
allowed_public_ports = []
auto_rollback = true
[mounts]
source = "flyappdata"
destination = "/data"
[[services]]
http_checks = []
internal_port = 3000
protocol = "tcp"
script_checks = []
[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"
[[services.ports]]
handlers = ["http"]
port = 80
[[services.ports]]
handlers = ["tls", "http"]
port = 443
[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 6
timeout = "2s"
Which establishes that how our application will be deployed and how the volume will be mounted.
Secrets
Buffalo applications require one secret: SESSION_SECRET
when running in production
mode. While we could have added this to the fly.toml
file we will instead create a secret in our Fly.io account.
> fly secrets set SESSION_SECRET=[our secret] -a flyapp-demo
That way our app will have SESSION_SECRET
set in the environment. The secrets space can be used for other things such as API keys or credentials that we don’t want to put in our git repository.
Configuring the Buffalo application
Now that the Fly.io application is created we need to tweak our database configuration to store our data in the volume.
We should set the database.yml
file to the following content:
---
...
production:
dialect: "sqlite3"
database: /data/database.db
Remember we set our volume to /data
so we need to make sure that the database.db
file is created/read from the volume.
Deploying
Once this is set we can run the fly deploy
command to deploy our application.
> fly deploy -a flyapp-demo
...
--> v1 deployed successfully
This command will build an image from the Dockerfile and deploy that image to the Fly.io platform. One important thing to mention is that Fly.io does not exactly deploy Docker images but micro-vms, that said, it seems to be able to receive Docker images and deploy these.
Wrapping up
After the deploy
command finished we should be able to see our application running in the https://flyapp-demo.fly.dev
URL. There are a couple of topics we didn’t cover in this tutorial like CI and data management for SQLite databases. we could cover topics like Litestream in future posts but for now we will just leave that as an exercise for the reader.