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
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.
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.
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).
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.
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.
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.
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.