Custom container registry

Using an external registry

Sometimes you would want to pull your Docker images from an external registry, instead of using application images stored in the swarm registry.

Since GitHub recently announced GitHub Container Registry, let's build a project using GitHub Actions and push/pull the project image(s) to/from the GitHub Container Registry. The registry is located at https://ghcr.io

Steps
  1. Create a Personal Access Token in GitHub to allow registry access
  2. Add the PAT to your project repository's secrets so we can use it in the deploy action
  3. Create a GitHub Action, update the project Docker Compose and entrypoint files
  4. Store the registry credentials on the swarm
  5. Push an update to your GitHub project repository

Project configuration

Create GitHub Action

./.github/workflows/deploy.yml
name: Deploy to swarm
on:
push:
branches:
- master
env:
REMOTE_USER: git
REMOTE_HOST: mydomain.com
REGISTRY_HOST: ghcr.io
APP_NAME: my-fancy-app
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set image tag
run: echo "::set-env name=IMAGE_TAG::${{ github.repository_owner }}/${{ env.APP_NAME }}"
- name: Build and push to container registry
uses: docker/build-push-action@v1
with:
registry: ${{ env.REGISTRY_HOST }}
username: ${{ github.actor }}
password: ${{ secrets.CR_PAT }}
repository: ${{ env.IMAGE_TAG }}
tags: latest
- name: Deploy
run: |
cd $GITHUB_WORKSPACE
git fetch --unshallow
git remote add swarm $REMOTE_USER@$REMOTE_HOST:$APP_NAME
GIT_SSH_COMMAND="ssh -i $HOME/.ssh/id_rsa -F /dev/null -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
git push -u swarm master --force

Update the project Docker Compose file

./docker-compose.yml
version: '3.7'
services:
web:
image: ghcr.io/${REGISTRY_USERNAME}/my-fancy-app
secrets:
- github-registry-secrets
networks:
- traefik-public
deploy:
mode: replicated
replicas: 1
labels:
- traefik.enable=true
- traefik.http.services.my-fancy-app.loadbalancer.server.port=5000
- traefik.http.routers.my-fancy-app.rule=Host(`my-fancy-app.mydomain.com`)
- traefik.http.routers.my-fancy-app.entrypoints=http,https
- traefik.http.routers.my-fancy-app.middlewares=redirect@file
secrets:
github-registry-secrets:
external: true
networks:
traefik-public:
external: true

Create an entrypoint file

TODO

Store the registry credentials on the swarm

Create a new Docker secret on a swarm manager node.
In this example we'll name the secret github-registry-secrets.

cat << EOM | docker secret create github-registry-secrets -
REGISTRY_USERNAME="<your-github-username>"
REGISTRY_PASSWORD="<your-personal-access-token>"
REGISTRY_HOST=ghcr.io
EOM

Links