Skip to content

Mirror Docker Images #151

Mirror Docker Images

Mirror Docker Images #151

Workflow file for this run

# Mirror Docker images from various upstream sources to GHCR
# This workflow mirrors pre-built images from Docker Hub to our registry
# with proper tagging at different granularity levels
#
# Source images:
# - sharelatex/sharelatex -> ghcr.io/btreemap/overleaf:official-*
# - tuetenk0pp/sharelatex-full -> ghcr.io/btreemap/overleaf:full-*
# - overleafcep/sharelatex -> ghcr.io/btreemap/overleaf:cep-*
#
# Note: For older Docker images with schema1 manifest format (not supported by
# modern Docker toolchains), we use a placeholder image instead.
name: Mirror Docker Images
on:
schedule:
# Daily at 03:00 UTC
- cron: '0 3 * * *'
push:
branches:
- main
paths:
- '.github/workflows/mirror-images.yml'
- '.github/scripts/mirror_images.py'
workflow_dispatch:
inputs:
force_full_sync:
description: 'Force full sync of all versions (ignore binary search optimization)'
required: false
default: 'false'
type: boolean
variant:
description: 'Variant to mirror (all, official, full, cep)'
required: false
default: 'all'
type: choice
options:
- all
- official
- full
- cep
env:
REGISTRY: ghcr.io
IMAGE_NAME: btreemap/overleaf
PLACEHOLDER_IMAGE: ghcr.io/btreemap/dockerfiles:placeholder
permissions:
contents: read
packages: write
jobs:
discover-versions:
name: Discover Versions
runs-on: ubuntu-latest
outputs:
official_versions: ${{ steps.discover.outputs.official_versions }}
full_versions: ${{ steps.discover.outputs.full_versions }}
cep_versions: ${{ steps.discover.outputs.cep_versions }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Discover versions to mirror
id: discover
env:
FORCE_FULL_SYNC: ${{ inputs.force_full_sync || 'false' }}
VARIANT_FILTER: ${{ inputs.variant || 'all' }}
run: |
ARGS="--output-format github --image ${{ env.IMAGE_NAME }}"
[[ "$FORCE_FULL_SYNC" == "true" ]] && ARGS="$ARGS --force-full-sync"
[[ "$VARIANT_FILTER" != "all" ]] && ARGS="$ARGS --variant $VARIANT_FILTER"
# shellcheck disable=SC2086
python3 .github/scripts/mirror_images.py discover $ARGS
mirror-official:
name: Mirror Official ${{ matrix.version }}
needs: discover-versions
if: needs.discover-versions.outputs.official_versions != '[]'
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 5
matrix:
version: ${{ fromJson(needs.discover-versions.outputs.official_versions) }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Mirror image with multiple tags
run: |
python3 .github/scripts/mirror_images.py mirror \
--source sharelatex/sharelatex \
--dest "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" \
--version "${{ matrix.version }}" \
--variant official \
--placeholder "${{ env.PLACEHOLDER_IMAGE }}"
mirror-full:
name: Mirror Full ${{ matrix.version }}
needs: discover-versions
if: needs.discover-versions.outputs.full_versions != '[]'
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 5
matrix:
version: ${{ fromJson(needs.discover-versions.outputs.full_versions) }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Mirror image with multiple tags
run: |
python3 .github/scripts/mirror_images.py mirror \
--source tuetenk0pp/sharelatex-full \
--dest "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" \
--version "${{ matrix.version }}" \
--variant full \
--placeholder "${{ env.PLACEHOLDER_IMAGE }}"
mirror-cep:
name: Mirror CEP ${{ matrix.version }}
needs: discover-versions
if: needs.discover-versions.outputs.cep_versions != '[]'
runs-on: ubuntu-latest
strategy:
fail-fast: false
max-parallel: 5
matrix:
version: ${{ fromJson(needs.discover-versions.outputs.cep_versions) }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Mirror image with multiple tags
run: |
python3 .github/scripts/mirror_images.py mirror \
--source overleafcep/sharelatex \
--dest "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" \
--version "${{ matrix.version }}" \
--variant cep \
--placeholder "${{ env.PLACEHOLDER_IMAGE }}"
update-latest-tags:
name: Update Latest Tags
needs: [discover-versions, mirror-official, mirror-full, mirror-cep]
if: always() && (needs.mirror-official.result == 'success' || needs.mirror-full.result == 'success' || needs.mirror-cep.result == 'success' || needs.mirror-official.result == 'skipped' || needs.mirror-full.result == 'skipped' || needs.mirror-cep.result == 'skipped')
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Update floating latest tags
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python3 .github/scripts/mirror_images.py update-latest --image "${{ env.IMAGE_NAME }}"