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.