Installing Pro in CI, Docker and Fly

Pro is served from the Aurora Meter package repository at https://aurorameter.com/repo, not from hex.pm. Every machine that runs mix deps.get needs that repository added first, with your key: your laptop, your CI runner and the machine that builds your release image. Skip it on any one of them and mix deps.get stops with:

** (Mix) Unknown repository "aurorameter", add new repositories with the `mix hex.repo add` task

A repository added with a missing, revoked or mistyped key fails instead with an authentication error from the repository.

Your key (amp_...) is on your account page. Treat it as a secret: it is a credential for your subscription, and it is shown in full only when it is issued or rotated. The examples below call the secret AURORA_METER_KEY (aurora_meter_key where Docker wants a lower-case id).

The command every one of them runs is the same:

mix hex.repo add aurorameter https://aurorameter.com/repo \
  --fetch-public-key SHA256:+g07CrUcsckpovkT9THeaiPWYLyyAP0p/OS+iZ1qTT8 \
  --auth-key "$AURORA_METER_KEY"

--fetch-public-key downloads the repository’s public key and refuses it unless its fingerprint is the one given, so a machine never trusts a key it was not told about. Hex then checks the signature on every registry file it reads.

GitHub Actions

Add the key as a repository secret (Settings, Secrets and variables, Actions, New repository secret) named AURORA_METER_KEY. Then add the repository in your workflow, after Elixir is set up and before mix deps.get:

- uses: erlef/setup-beam@v1
  with:
    otp-version: "27"
    elixir-version: "1.18"

- name: Add the Aurora Meter package repository
  run: |
    mix hex.repo add aurorameter https://aurorameter.com/repo \
      --fetch-public-key SHA256:+g07CrUcsckpovkT9THeaiPWYLyyAP0p/OS+iZ1qTT8 \
      --auth-key "$AURORA_METER_KEY"
  env:
    AURORA_METER_KEY: ${{ secrets.AURORA_METER_KEY }}

- run: mix deps.get

The key goes in through env: rather than written straight into the command (--auth-key ${{ secrets.AURORA_METER_KEY }} works too). GitHub masks the value in logs either way; the environment variable keeps it out of the generated script.

erlef/setup-beam installs Hex, which mix hex.repo add needs. If you set up Elixir another way, run mix local.hex --force first.

If you cache deps/ keyed on mix.lock, keep the repository step unconditional: a cache miss still runs mix deps.get, and that is the run that needs it. Pull requests from forks do not receive repository secrets, so their mix deps.get fails at Pro; that is GitHub’s rule for every secret.

Docker

mix phx.gen.release --docker writes a Dockerfile whose build stage installs Hex and then fetches dependencies:

# install hex + rebar
RUN mix local.hex --force && \
    mix local.rebar --force

# set build ENV
ENV MIX_ENV="prod"

# install mix dependencies
COPY mix.exs mix.lock ./
RUN mix deps.get --only $MIX_ENV

Add the repository between Hex and mix deps.get, reading the key from a build secret:

# install hex + rebar
RUN mix local.hex --force && \
    mix local.rebar --force

# the Aurora Meter package repository, for aurora_meter_pro
RUN --mount=type=secret,id=aurora_meter_key \
    mix hex.repo add aurorameter https://aurorameter.com/repo \
      --fetch-public-key SHA256:+g07CrUcsckpovkT9THeaiPWYLyyAP0p/OS+iZ1qTT8 \
      --auth-key "$(cat /run/secrets/aurora_meter_key)"

# set build ENV
ENV MIX_ENV="prod"

# install mix dependencies
COPY mix.exs mix.lock ./
RUN mix deps.get --only $MIX_ENV

RUN --mount=type=secret needs BuildKit, which is the default builder in current Docker and on Fly. On an older Docker, put # syntax=docker/dockerfile:1 on the first line of the Dockerfile.

Build it with the key passed as a secret:

docker build --secret id=aurora_meter_key,env=AURORA_METER_KEY .

(--secret id=aurora_meter_key,src=path/to/file reads it from a file instead.)

Never pass the key as a build ARG or ENV. Both are recorded in the image’s history, where anyone who can pull the image can read them. A build secret is mounted for that one RUN and is not part of any layer.

One thing does persist: mix hex.repo add writes the repository, key included, into Hex’s configuration in the build stage. The generated Dockerfile is multi-stage and the final image copies only the release out of the build stage, so the key never reaches the image you run. Do not push the build stage itself to a shared registry or cache.

Fly

fly deploy builds the same Dockerfile on Fly’s builder, which mounts build secrets the same way. Pass the key with --build-secret:

fly deploy --build-secret aurora_meter_key="$AURORA_METER_KEY"

The name before = is the id in the Dockerfile’s --mount=type=secret. A build secret is used only while the image is built; it is not a runtime secret, and your running app never needs the repository key. (fly secrets set is for runtime values such as STRIPE_WEBHOOK_SECRET, and does not reach the build.)

Deploying from GitHub Actions combines the two: the AURORA_METER_KEY repository secret, and the flag above in the deploy step.

- uses: superfly/flyctl-actions/setup-flyctl@master

- run: flyctl deploy --remote-only --build-secret aurora_meter_key="$AURORA_METER_KEY"
  env:
    FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
    AURORA_METER_KEY: ${{ secrets.AURORA_METER_KEY }}

When the key changes

Rotating the key on your account page revokes the old one at once. Update the secret everywhere it is stored (each CI secret, and any local mix hex.repo add), and run mix hex.repo add again with the new key on any machine that keeps its Hex configuration between builds. A build that still has the old key fails at mix deps.get with an authentication error; nothing that is already built and running is affected, because the running app never talks to the repository.

When a subscription ends, the key stops working on the next mix deps.get. Releases you have already built keep running.