diff --git a/.github/workflows/image-publish.yaml b/.github/workflows/image-publish.yaml new file mode 100644 index 0000000..0cd6c55 --- /dev/null +++ b/.github/workflows/image-publish.yaml @@ -0,0 +1,56 @@ +name: Publish a container image + +on: + push: + release: + types: [published, edited] + +jobs: + build: + runs-on: ubuntu-24.04 + permissions: + packages: write + steps: + - uses: actions/checkout@v6 + - uses: docker/setup-qemu-action@v3 + - run: ./build/set_image_metadata + + - name: Build an image + id: build-image + uses: redhat-actions/buildah-build@v2 + with: + image: ${{ github.event.repository.name }}-dev + tags: ${{ env.TAGS }} + platforms: linux/amd64, linux/arm64/v8 + containerfiles: | + ./Containerfile + labels: ${{ env.ANNOTATIONS }} + + - name: Push the image to GHCR + id: push-to-ghcr + uses: redhat-actions/push-to-registry@v2 + with: + image: ${{ steps.build-image.outputs.image }} + tags: ${{ steps.build-image.outputs.tags }} + registry: ghcr.io/${{ github.repository_owner }} + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Set the version tag (only if released) + id: retag-version + if: (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'edited')) + run: | + buildah tag \ + ${{ steps.build-image.outputs.image }}:${{ github.sha }} \ + ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest + buildah tag \ + ${{ steps.build-image.outputs.image }}:${{ github.sha }} \ + ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ github.event.release.tag_name }} + + - name: Push the release image to GHCR + if: (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'edited')) + uses: redhat-actions/push-to-registry@v2 + with: + tags: ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ github.event.release.tag_name }} + username: ${{ github.actor }} + password: ${{ github.token }} diff --git a/Containerfile b/Containerfile new file mode 100644 index 0000000..3962adb --- /dev/null +++ b/Containerfile @@ -0,0 +1,12 @@ +FROM mariadb:12 + +RUN apt-get update && apt-get install -y \ + curl \ + bash \ + rclone + +COPY entrypoint.sh / +RUN chmod +x /entrypoint.sh + +WORKDIR /backup +ENTRYPOINT /entrypoint.sh diff --git a/build/set_image_metadata b/build/set_image_metadata new file mode 100755 index 0000000..f341f78 --- /dev/null +++ b/build/set_image_metadata @@ -0,0 +1,35 @@ +#! /usr/bin/env bash +# -------------------------------------------- +# -- Should be used in Github Actions +# -------------------------------------------- +# +# -------------------------------------------- +# -- To have a multi-line env var in github, +# -- we must define the EOF +# -------------------------------------------- +EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) +echo "ANNOTATIONS<<$EOF" >> "$GITHUB_ENV" + +ANNOTATIONS=$(cat << EOF +org.opencontainers.image.created=$(date +"%Y-%m-%d %T") +org.opencontainers.image.authors=$GITHUB_ACTOR +org.opencontainers.image.url=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID +org.opencontainers.image.documentation=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/blob/main/README.md +org.opencontainers.image.source=$GITHUB_SERVER_URL/$GITHUB_REPOSITORY +org.opencontainers.image.version=$GITHUB_SHA +org.opencontainers.image.revision=$GITHUB_SHA +org.opencontainers.image.vendor=$GITHUB_REPOSITORY_OWNER +org.opencontainers.image.license=GNU GENERAL PUBLIC LICENSE v3 +org.opencontainers.image.title=$GITHUB_REPOSITORY +org.opencontainers.image.description=Backup databases using pg_dump and upload backups using rclone +EOF +) + +echo "${ANNOTATIONS}" >> "${GITHUB_ENV}" +echo "$EOF" >> "$GITHUB_ENV" +# -------------------------------------------- +# -- Set the image tag by commit sha +# -------------------------------------------- +echo "TAGS=${GITHUB_SHA}" >> "${GITHUB_ENV}" + + diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..0c67f81 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,40 @@ +#!/bin/bash +set -e + +echo "Prepare configuration for script" +TIMESTAMP=$(date +%F_%R) +BACKUP_FILE=${DB_NAME}-${TIMESTAMP}.sql +BACKUP_FILE_LATEST=${DB_NAME}-latest.sql.gz +DB_HOST=${DB_HOST:-localhost} +DB_PASSWORD=$(cat ${DB_PASSWORD_FILE}) + +if [[ -z "${STORAGE_BUCKET}" ]]; then + echo "Variable STORAGE_BUCKET must be set" + exit 1 +fi + +# create login credential file +echo "[mysqldump] +password=${DB_PASSWORD}" > ~/.my.cnf +chmod 0600 ~/.my.cnf + +echo "Start creating backup" +mariadb-dump -h ${DB_HOST} -u ${DB_USER} -P ${DB_PORT} --single-transaction --dump-date ${DB_NAME} > ${BACKUP_FILE} +if [[ $? -eq 0 ]]; then + gzip ${BACKUP_FILE} +else + echo >&2 "DB backup failed" + exit 1 +fi + +## copy to destination +echo "Upload to storage" +BACKUP_FILE_ARCHIVED=${BACKUP_FILE}.gz + +rclone copyto "./${BACKUP_FILE_ARCHIVED}" "storage://${STORAGE_BUCKET}/${DB_NAME}/${BACKUP_FILE_ARCHIVED}" +rclone copyto "./${BACKUP_FILE_ARCHIVED}" "storage://${STORAGE_BUCKET}/${DB_NAME}/${BACKUP_FILE_LATEST}" + +if test $? -ne 0 +then + exit 1; +fi