---
title: "Deploying with Private Composer Packages"
description: "Authenticating Private Composer Packages"
---

# Deploying with Private Composer Packages

[Annie Ruygt](https://annieruygtillustration.com/)

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](https://docs.fly.io/laravel).

## The Problem

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](https://nova.laravel.com/) or [Spark](https://spark.laravel.com/) will fail unless we provide authentication tokens!

You can set [secrets](https://docs.fly.io/apps/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](https://docs.fly.io/apps/build-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](https://chipperci.com/docs/builds/composer-auth/)).

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 \
    "username@example.org" "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](https://docs.docker.com/develop/develop-images/build_enhancements/) 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 `Dockerfile` already.

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_user` and `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 `fly deploy`).

In our case, we use the secrets to run `composer config...` and add the authentication details used to install Laravel Nova.

The `--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`:

```
fly deploy \
    --build-secret nova_user=fideloper@fly.io \
    --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!
