If you've read anything on Fly.io, you've probably noticed a snippet like this:
We transmogrify Docker containers into lightweight micro-VMs and run them on our own hardware in racks around the world, so your apps can run close to your users.
Fly deploys an application by building it into a Docker image, and then doing a whole lotta stuff to run it as a "for-real" virtual machine.
To deploy an application, all we need to care about is creating a working Docker image.
Deploying a Laravel application involves installing Composer dependencies "at build time" - when the Docker image is being built, just before releasing the deployment.
However, installing a private package such as Laravel Nova or Spark will fail unless we provide authentication tokens!
You can set secrets for your application, but these are only available at run-time. They aren't available when building your Docker image. For that, we need build-time secrets.
Authenticating Private Packages
Authenticating Composer packages comes in a few forms.
You can create an
auth.json file in your
$COMPOSER_HOME path, or perhaps populate a
$COMPOSER_AUTH environment variable with some JSON (examples here).
A short-cut to this is running the following command (or something like it, as it varies a bit per package):
# Authenticate Composer for Laravel Nova composer config http-basic.nova.laravel.com \ "email@example.com" "some-auth-token"
Let's see how to use this command in our
Dockerfile to pull in Laravel Nova.
Secrets in Docker Builds
Our goal is to authenticate private packages within Docker builds, without leaking secrets.
We'll make use of Docker secrets to accomplish this.
You may have used the
fly launch command to generate a
Dockerfile, or perhaps you created your own. Either way, you should have a
To get some secrets into a build, edit the
Dockerfile, find the
composer install command (it may be
composer update), and update it:
# Mount 2 secrets, configure composer, install dependencies RUN --mount=type=secret,id=nova_user \ --mount=type=secret,id=nova_pass \ \ composer config http-basic.nova.laravel.com \ "$(cat /run/secrets/nova_user)" "$(cat /run/secrets/nova_pass)" \ \ && composer install --optimize-autoloader --no-dev \ ...
We defined 2 secrets. The secrets are named
nova_pass. Mounting secrets in Docker creates a file per secret in
/run/secrets. These are available only during the building of the container image (e.g. when you run
In our case, we use the secrets to run
composer config... and add the authentication details used to install Laravel Nova.
--mount directive is not a shell command, so there's no need to add
&& after it as you commonly see when chaining commands.
We can pass the values of those secrets when we run
fly deploy \ --build-secret firstname.lastname@example.org \ --build-secret nova_pass=LARAVEL_NOVA_AUTH_TOKEN_HERE
You should see that the
composer install command works - it authenticates and pulls down Laravel Nova!