---
title: "Powerbuilding with Fly"
---

# Powerbuilding with Fly

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`](https://fly.io/docs/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 called `Dockerfile` 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 tells `flyctl` 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](https://fly.io/docs/secrets/) which are securely stored and injected, as environment variables, into the application when the image starts running on the Fly platform.
