Configuration and fly.toml
All Fly applications have a fly.toml
file which describes how the application should be configured when it is deployed onto the Fly platform. This configuration includes the application name, builder to be used (optional), ports, services, and handlers to set up and parameters for health checks.
The file is in TOML format (github reference). If you are unfamiliar with TOML, here's a useful introduction. It is made up of lines with either key/value settings or sections (noted by values surrounded by one or more pairs of square brackets).
You don't need to create a fly.toml
file by hand. Running flyctl init
generates one for you, interactively prompting you for various values.
Fly.toml - line by line
The app
name
The first key/value in any fly.toml
file is the application name. This will also be used to create the host name that the application will use by default. For example:
app = "restless-fire-6276"
Whenever flyctl
is run, it will look for a fly.toml
file in the current directory and use the application name in that file. This behavior can be overridden by using the -a
flag to set the application name, or on some commands (such as deploy
) by using a -c
flag to point to a different fly.toml
file.
Runtime options
Various options are available to control the lifecycle of a running application. These are optional and can be placed at the top level of the fly.toml
file:
kill_signal
option
When shutting down a Fly app instance, by default, Fly sends a SIGINT
signal to the running process. Typically this triggers a hard shutdown option on most applications. The kill_signal
option allows you to change what signal is sent so that you can trigger a softer, less disruptive shutdown. Options are SIGINT
(The default), SIGTERM
, SIGQUIT
, SIGUSR1
, SIGUSR2
, SIGKILL
, or SIGSTOP
. For example, to set the kill signal to SIGTERM, you would add:
kill_signal = "SIGTERM"
kill_timeout
option
When shutting down a Fly app instance, by default, after sending a signal, Fly gives an app instance five seconds to close down before being killed. Depending on the type of VM, this timeout can be adjusted. Shared VMs can extend it to 300 seconds (five minutes). Dedicated VMs can extend the timeout to 86400 seconds (twenty-four hours). To set the timeout to two minutes, you would add:
kill_timeout = 120
The build
section
The optional build section contains key/values concerned with how the application should be built. You can read more about builders in Builders and Fly
There are then four possible settings for builders in the build
section of fly.toml
:
- builtin
- builder
- image
- dockerfile
builtin
[build]
builtin = "node"
The builtin builder setting makes flyctl use one of the integrated builders. These are available for go, node, deno, ruby, and static (web server). They are designed for quick deployments with minimal fuss. When running flyctl init
, you are offered a chance to select from the available builtins or you can specify flyctl init --builtin node
to preselect the node builtin.
builder
[build]
builder = "gcr.io/buildpacks/builder"
The builder "builder" uses CNB Buildpacks and Builders to create the application image. These are third party toolkits which can use Heroku compatible build processes or other tools. The tooling is all managed by the buildpacks and buildpacks are assembled into CNB Builders - images complete with the buildpacks and OS to run the tool chains.
A selection of recommended buildpacks is offered when running flyctl init
. If you want a buildpack builder that is not listed, run fly init
time and use --builder buildername
in the command line.
In our example above, the builder is being set to use Google's all-purpose buildpack. To learn more about buildpacks and Fly, refer to this blog posting Simpler Fly deployments for NodeJS, Rails, Go, and Java.
image
[build]
image = "flyio/hellofly:latest"
The image builder is used when you want to immediately deploy an existing public image. When deployed, there will be no build process; the image will be prepared and uploaded to the Fly infrastructure as it. This option is useful if you already have a working Docker image you want to deploy on Fly or you want a well known Docker image from a repository to be run.
When running flyctl init
add --image imagename
to the command line to get this option configured - it is not available for interactive selection.
dockerfile
Not really a particular setting, more the default. If there is no build section, flyctl will look for a Dockerfile
to use to build the app image.
Although there is no build section for using a dockerfile, there is the option to pass build arguments to the Dockerfile via the fly.toml file using a [build.args]
sub-section:
[build.args]
USER="plugh"
MODE="production"
This will always pass the USER and MODE build arguments to the Dockerfile build process. Users can always set their own build arguments on the command line of fly deploy
using --build-arg
.
The env
variables section
The env variables section is an optional section that allows for the setting of non-sensitive information as environment variables in the application's runtime environment.
For sensitive information, such as credentials or passwords, we recommend using the secrets command. For anything else though, the env
section provides a simple way to set environment variables. Here's an example:
[env]
LOG_LEVEL = "debug"
RAILS_ENV = "production"
S3_BUCKET = "my-app-production"
Env variable names are strictly case-sensitive and cannot begin with FLY_
(as this could clash with the runtime enviroment). Env values can only be strings.
Where there is a secret and an env variable set with the same name, the secret will take precedence.
The services
sections
The services
sections configure the mapping of ports on the application to ports and services on the Fly platform. These mappings determine how connections to the application will be handled on their journey from the Fly edge network to running Fly applications.
You can have:
- No
services
section: The application has no mappings to the external internet - typically apps like databases that talk over 6PN private networking to other apps. - One
services
section: One internal port mapped to the one or more external ports on the internet. - Multiple
services
sections: Mapping multiple internal ports to multiple external ports.
The services
section itself is a table of tables in TOML, so the section is delimited with double square brackets, like this:
[[services]]
internal_port = 8080
protocol = "tcp"
internal_port
: The port this service (and application) will use to communicate with clients. The default is 8080. We recommend applications use the default.protocol
: The protocol that this service will use to communicate. Typicallytcp
for most applications, but can also beudp
.
services.concurrency
The services concurrency sub-section configures the application's behavior with regard to concurrent connections and compute scaling. It is a simple list of key/values, so the section is denoted with single square brackets like so:
[services.concurrency]
hard_limit = 25
soft_limit = 20
hard_limit
: When an application instance is at or over this number of concurrent connections, the system will bring up another instance.soft_limit
: When an application instance is at or over this number of concurrent connections, the system is likely bring up another instance.
services.ports
For each external port you want to accept connections on, you will need a services.ports
section. One for each port, the section is denoted by double square brackets like this:
[[services.ports]]
handlers = ["http"]
port = "80"
This example defines an HTTP handler on port 80.
handlers
: An array of strings, each string selecting a handler process to terminate the connection with at the edge. Here, the "HTTP" handler will accept HTTP traffic and pass it on to the internal port of the application which we defined earlier.port
: A string which selects which external ports you want Fly to accept traffic on. You can configure an application to listen for global traffic on ports 80, 443, 5000, and ports 10000 - 10100.
You can have more than one services.ports
sections. The default configuration, for example, contains two. We've already seen one above. The second one defines an external port 443 for secure connections, using the "tls" handler.
[[services.ports]]
handlers = ["tls", "http"]
port = "443"
The details of how these handlers manage network traffic, and other handlers available, are detailed in the Network Services documentation.
services.tcp_checks
When a service is running, the Fly platform checks up on it by connecting to a port. The services.tcp_checks
section defines parameters for those checks. For example, the default tcp_checks look like this:
[[services.tcp_checks]]
interval = 10000
timeout = 2000
interval
: The time in milliseconds between connectivity checks.timeout
: The maximum time a connection can take before being reported as failing its healthcheck.
services.http_checks
Another way of checking a service is running is through HTTP checks as defined in the services.http_checks
section. These checks are more thorough than tcp_checks as they require not just a connection but a successful HTTP status in response (i.e, 2xx). Here is an example of a services.http_checks
section:
[[services.http_checks]]
interval = 10000
method = "get"
path = "/"
protocol = "http"
timeout = 2000
tls_skip_verify = false
[services.http_checks.headers]
Roughly translated, this section says every ten seconds, perform a HTTP GET on the root path (e.g. http://appname.fly.dev/) looking for it to return a HTTP 200 status within two seconds. The parameters of a http_check
are listed below.
interval
: The time in milliseconds between connectivity checks.method
: The HTTP method to be used for the check.path
: The path of the URL to be requested.protocol
: The protocol to be used (http
orhttps
)timeout
: The maximum time a connection can take before being reported as failing its healthcheck.tls_skip_verify
: Whentrue
(and using HTTPS protocol) skip verifying the certificates sent by the server.services.http_checks.headers
: This is a sub-section ofservices.http_checks
. It uses the key/value pairs as a specification of header and header values that will get passed with the http_check call.
Note: The services.http_checks
section is optional and not generated in the default fly.toml
file.
The mounts
section
This section supports the Volumes feature for persistent storage, available as a feature preview. The section has two settings, both are needed.
[mounts]
source="myapp_data"
destination="/data"
source
The source
is a volume name that this app should mount. Any volume with this name, in the same region as the app and that isn't already mounted, may be mounted. A volume of this name must exist in some region for the application to deploy.
destination
The destination
is directory where the source
volume should be mounted on the running app.