Run a Crystal 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 global application platform.
In this guide we'll learn how to deploy a Crystal application on Fly.io.
Our example will be using a basic Lucky app with PostgreSQL. We'll assume you already have lucky+crystal installed.
Once lucky is installed, we can create a new project by running the following command:
This will walk you through project options and create a new project.
To run the application, first run
script/setup to install dependencies and create the database. Then run
lucky dev to start the application.
Connect to the address displayed in the console.
This should bring you to the "Hello Lucky" page.
It's time to install
flyctl, the 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 thats installed you'll want to log in to Fly.io.
When we run
fly launch from the newly-created project directory, the launcher will:
- Ask you to select a deployment region
- Set secrets required by Lucky (
SECRET_KEY_BASE, for example)
- Run the Lucky deployment setup task
- Optionally setup a Postgres instance in your selected region
- Deploy the application in your selected region
cd hello-lucky fly launch
Creating app in /Users/me/hello-lucky Scanning source code Detected a Lucky app ? App Name (leave blank to use an auto-generated name): hello-lucky ? Select organization: flyio (flyio) ? Select region: mad (Madrid, Spain) Created app hello-lucky in organization soupedup Set secrets on hello-lucky: SECRET_KEY_BASE Installing dependencies Running Docker release generator Wrote config file fly.toml ? Would you like to setup a Postgres database now? Yes Postgres cluster hello-lucky-db created Username: postgres Password: <password> Hostname: hello-lucky-db.internal Proxy Port: 5432 PG Port: 5433 Save your credentials in a secure place, you will not be able to see them again!
1 desired, 1 placed, 1 healthy, 0 unhealthy [health checks: 2 total, 2 passing] --> v0 deployed successfully
Connect to postgres Any app within the flyio organization can connect to postgres using the above credentials and the hostname "hello-lucky-db.internal." For example: postgres://postgres:email@example.com:5432
See the postgres docs for more information on next steps, managing postgres, connecting from outside fly: https://fly.io/docs/reference/postgres/ Postgres cluster hello-lucky-db is now attached to hello-lucky
Would you like to deploy now? Yes Deploying hello-lucky
==> Validating app configuration --> Validating app configuration done Services TCP 80/443 ⇢ 8080 Remote builder fly-builder-little-glitter-8329 ready ...
That's it! Run
fly open to see your deployed app in action.
Try a few other commands:
fly logs- Tail your application logs
fly status- App deployment details
fly status -a hello-lucky-db- Database deployment details
fly deploy- Deploy the application after making changes
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-side application slot of the same name, "hello-lucky". If we look at the
fly.toml file we can see the name in there:
app = "hello-lucky" kill_signal = "SIGINT" kill_timeout = 5 processes =  [env] [experimental] allowed_public_ports =  auto_rollback = true [[services]] http_checks =  internal_port = 8080 processes = ["app"] 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 = 0 timeout = "2s"
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 platform. The rest of the file contains settings to be applied to the application when it deploys.
We'll have more details about these properties as we progress, but for now, it's enough to say that they mostly configure which ports the application will be visible on.
To deploy changes to your app, just run just run:
This will lookup our
fly.toml file, and get the app name
hello-lucky from there. Then
flyctl will start the process of deploying our application to the Fly platform. Flyctl will return you to the command line when it's done.
Alternatively, you can use GitHub Actions to deploy your app to Fly
Now the application has been deployed, let's find out more about its deployment. The command
flyctl info will give you all the essential details.
App Name = hello-lucky Owner = personal Version = 0 Status = running Hostname = hello-lucky.fly.dev Deployment Status ID = 8d35eade-8c68-499e-e0a9-c6829e3c1c9d Version = v0 Status = successful Description = Deployment completed successfully Instances = 1 desired, 1 placed, 1 healthy, 0 unhealthy Instances ID PROCESS VERSION REGION DESIRED STATUS HEALTH CHECKS RESTARTS CREATED 235f9667 app 0 ord run running 1 total, 1 passing 0 1m2s ago
If you want to know what IP addresses the app is using, try
flyctl ips list:
flyctl ips list
TYPE ADDRESS REGION CREATED AT v4 188.8.131.52 global 3m20s ago v6 2a09:8280:1::3:23f4 global 3m20s ago
The quickest way to browse your newly deployed application is with the
flyctl open command.
Your browser will be sent to the displayed URL. Fly will auto-upgrade this URL to a HTTPS secured URL.
Fly also supports multi-region deployments.
To deploy to multiple regions, first Create a PostgreSQL Cluster, then follow these steps:
Configure your primary region by setting the env
PRIMARY_REGIONin your fly.toml
[env] PRIMARY_REGION = "ord"
Add the superfly/fly.cr shard shard to your project
dependencies: fly: github: superfly/fly.cr version: ~> 0.1
# src/shards.cr # ... require "avram" # ... require "fly/pg/error_handler" require "fly/avram" # ...
Fly::PG::ErrorHandlermiddleware to your list of middlewares, after the
# src/app_server.cr # ... def middleware : Array(HTTP::Handler) [ # ... Lucky::ErrorHandler.new(action: Errors::Show), Raven::Lucky::ErrorHandler.new, Fly::PG::ErrorHandler.new, # ..,. ]of HTTP::Handler end # ...
You can see replays in the
You have successfully built, deployed, and connected to your first Crystal application on Fly.