When you deploy to Fly, you are deploying an image to the Fly infrastructure. Fly currently uses Docker images for this purpose, for widest compatibility. We’re going to take a look at some features available which can power-up your image building.
Identifying your build
When you deploy, the flyctl
application looks for instructions to build the image in a Dockerfile or creates a builder VM to do the image build. Let’s start with the flags that control where flyctl
looks for things.
- -c, –config filename : It all starts with the config file, which is assumed to be
fly.toml
in the current directory. Of course you may be building multiple different applications out of the same directory, or just be very organized and have a directory for your different configurations. Whatever the case, the--config
option will let you point at a different configuration file. - –dockerfile filename : If you are building an image without a builder,
flyctl
looks for a file calledDockerfile
to get its build instructions. Again, if you are building and deploying multiple different applications out of the same directory this can be a problem, which is why this option exists. It tellsflyctl
to use the filename as the docker file to do the build with.
Controlling the build
So, now we can tell flyctl
what config and docker file we want to use. The next part of taking control of the build applies to any invocation of flyctl
where a docker file is involved and that’s --build-args
.
But let’s first rewind back into some docker commands. ARG
and ENV
both deal with variables that can be set in the build process. The ARG
command allows variables to be specified that are taken from the build command and used during the build process. The ENV
command allows variables to be created that will become environment variables set within the image when it starts running.
Using a combination of these, it’s possible to take a command-line argument and turn it into a runtime environment variable. Consider, for example, that we want to set the port that an NGINX server runs on. We may have had something like:
ENV NGINX_PORT=8080
in the docker file. To make that controllable from the command line we can replace that with:
ARG NGINX_PORT=8080
ENV NGINX_PORT=${NGINX_PORT}
The ARG
command makes a variable called NGINX_PORT
and sets it to a default of 8080. The ENV
command creates an environment variable also called NGINX_PORT
. This variable will live on into the running version of the image and can be used by scripts within it to control applications running in the image. It takes its value from the ARG
setting of NGINX_PORT
through the expansion of ${NGINX_PORT}
which refers specifically to the ARG
variable and thus will expand to either the default or the passed-in value.
Which leaves the question of how to set that ARG
value with flyctl
. That’s where --build-args
comes in. You can use this option to pass a number of name/value pairs over to the build process. So for our example above we could do:
flyctl deploy --build-args NGINX_PORT=4000
This will set the build argument which will override the default of the environment variable.
When to use –build-args
It may look like this is a good way to pass credentials and other sensitive data to your Fly applications, but it isn’t. This is built for non-sensitive data as the information is baked into the image and could be retrievable. If it’s sensitive information you want to pass to the application, check out Fly Secrets which are securely stored and injected, as environment variables, into the application when the image starts running on the Fly platform.