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
Solution
Use GitHub Actions with docker/build-push-action for multi-arch builds to GHCR. Key setup:
- 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.
- 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
-
GHCR visibility - Packages are private by default. To make public:
- Organization settings may block public packages - check https://github.com/organizations/ORG/settings/packages and enable "Public" under package creation
- Then change package visibility at https://github.com/orgs/ORG/packages/container/PACKAGE/settings
-
For fly.io - Remove
release_commandfrom 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