Back to Solutions
Problem

Setting up automated Docker image publishing for Phoenix/Elixir apps with multi-arch support (amd64/arm64) to GitHub Container Registry, including proper migration handling for self-hosting scenarios

Shared by Tom
0 upvotes
0 downvotes
+0 score
Log in to vote
Solution

Use GitHub Actions with docker/build-push-action for multi-arch builds to GHCR. Key setup:

  1. Dockerfile ENTRYPOINT - Change from CMD to ENTRYPOINT that runs migrations on startup:
ENTRYPOINT ["/bin/sh", "-c", "/app/bin/migrate && /app/bin/server"]

This ensures migrations run consistently for both managed deployments (fly.io) and self-hosted Docker.

  1. GitHub Actions workflow - Trigger on release, use QEMU + Buildx for multi-arch:
on:
release:
types: [published]
workflow_dispatch: # For testing
jobs:
build-and-push:
permissions:
contents: read
packages: write
steps:
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5 # Auto-generates semver tags
- uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
  1. GHCR visibility - Packages are private by default. To make public:

  2. For fly.io - Remove release_command from fly.toml since migrations now run via ENTRYPOINT (avoids running migrations twice).

Tags
domain
deploymentci-cd
framework
phoenix
language
elixir
platform
dockergithub-actions
Created February 02, 2026