├── .github ├── FUNDING.yml └── workflows │ └── ci.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── docker-compose.yml └── exec.sh /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [umputun] 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: [push, pull_request] 3 | jobs: 4 | 5 | build: 6 | name: build 7 | runs-on: ubuntu-latest 8 | steps: 9 | 10 | - name: check out code 11 | uses: actions/checkout@v2 12 | 13 | - name: set up QEMU 14 | uses: docker/setup-qemu-action@v1 15 | 16 | - name: set up Docker Buildx 17 | id: buildx 18 | uses: docker/setup-buildx-action@v1 19 | 20 | - name: available platforms 21 | run: echo ${{ steps.buildx.outputs.platforms }} 22 | 23 | - name: build docker image 24 | run: docker build . 25 | 26 | - name: build and deploy master image to ghcr.io and dockerhub 27 | if: ${{ github.ref == 'refs/heads/master' }} 28 | env: 29 | GITHUB_PACKAGE_TOKEN: ${{ secrets.PKG_TOKEN }} 30 | DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }} 31 | USERNAME: ${{ github.actor }} 32 | GITHUB_SHA: ${{ github.sha}} 33 | GITHUB_REF: ${{ github.ref}} 34 | run: | 35 | ref="$(echo ${GITHUB_REF} | cut -d'/' -f3)" 36 | echo GITHUB_REF - $ref 37 | echo ${GITHUB_PACKAGE_TOKEN} | docker login ghcr.io -u ${USERNAME} --password-stdin 38 | echo ${DOCKER_HUB_TOKEN} | docker login -u ${USERNAME} --password-stdin 39 | docker buildx build --push \ 40 | --build-arg CI=github --build-arg GITHUB_SHA=${GITHUB_SHA} --build-arg GIT_BRANCH=${ref} \ 41 | --platform linux/amd64,linux/arm/v7,linux/arm64 \ 42 | -t ghcr.io/${USERNAME}/github-backup-docker:${ref} -t ${USERNAME}/github-backup-docker:${ref} . 43 | 44 | - name: deploy tagged (latest) to ghcr.io and dockerhub 45 | if: ${{ startsWith(github.ref, 'refs/tags/') }} 46 | env: 47 | GITHUB_PACKAGE_TOKEN: ${{ secrets.PKG_TOKEN }} 48 | DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }} 49 | USERNAME: ${{ github.actor }} 50 | GITHUB_SHA: ${{ github.sha}} 51 | GITHUB_REF: ${{ github.ref}} 52 | run: | 53 | ref="$(echo ${GITHUB_REF} | cut -d'/' -f3)" 54 | echo GITHUB_REF - $ref 55 | echo ${GITHUB_PACKAGE_TOKEN} | docker login ghcr.io -u ${USERNAME} --password-stdin 56 | echo ${DOCKER_HUB_TOKEN} | docker login -u ${USERNAME} --password-stdin 57 | docker buildx build --push \ 58 | --build-arg CI=github --build-arg GITHUB_SHA=${GITHUB_SHA} --build-arg GIT_BRANCH=${ref} \ 59 | --platform linux/amd64,linux/arm/v7,linux/arm64 \ 60 | -t ghcr.io/${USERNAME}/github-backup-docker:${ref} -t ghcr.io/${USERNAME}/github-backup-docker:latest \ 61 | -t ${USERNAME}/github-backup-docker:${ref} -t ${USERNAME}/github-backup-docker:latest . 62 | 63 | 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /var 2 | .env 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.15 2 | 3 | RUN apk add --update --no-cache tzdata git python3 py-pip tzdata 4 | RUN pip3 install github-backup && github-backup -v 5 | COPY exec.sh /srv/exec.sh 6 | RUN chmod +x /srv/exec.sh 7 | CMD ["/srv/exec.sh"] 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Umputun 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # github-backup-docker [![Docker Automated build](https://img.shields.io/docker/automated/jrottenberg/ffmpeg.svg)](https://hub.docker.com/r/umputun/github-backup/) 2 | 3 | Dockerized version of [python-github-backup](https://github.com/josegonzalez/python-github-backup) with extra automation. This container makes a backup daily and keeps up to defined number of backups. 4 | 5 | ## Install and run 6 | 7 | 1. Generate github [access token](https://github.com/settings/tokens). Give it a `repo` scope with full access to repositories. 8 | 2. Get provided `docker-compose.yml`. If needed change the mapping for `volumes` and `MAX_BACKUPS` number 9 | 3. Change TZ (see the [list](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)) 10 | 4. Set `TOKEN` (in environment or directly in `docker-compose.yml`) 11 | 5. Set `GITHUB_USER` (Github user accounts) and/or `GITHUB_ORG` (Github Organizations; make sure the user token has access to the organization). If you have multiple users/organizations, you can list thme separating names by a comma. 12 | 6. Run `docker-compose up -d` to initiate daily backup 13 | 14 | ## Customize Backup Options 15 | 16 | The underlying [python-github-backup](https://github.com/josegonzalez/python-github-backup) library [has a lot of options](https://github.com/josegonzalez/python-github-backup#usage) to customize what is backed up from github. 17 | 18 | We can customize this by using the `BACKUP_OPTIONS` environment variable. By default, the container will backup everything and uses `--private --all --gist`. That will backup the repositories, issues, pull requests, labels, etc. 19 | 20 | If you wanted to customize this to only backup the repository code (including private repositories), you could define the following on your `docker-compose.yml` file's environment: 21 | 22 | ``` 23 | BACKUP_OPTIONS=--private --repositories 24 | ``` 25 | 26 | ## Prepared images 27 | 28 | - [docker hub](https://hub.docker.com/r/umputun/github-backup-docker/tags) 29 | - [github packages](https://github.com/umputun/github-backup-docker/pkgs/container/github-backup-docker) 30 | 31 | ## Build from the source 32 | 33 | 1. Clone this repo 34 | 2. run `docker-compose build` 35 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | 3 | services: 4 | github-backup: 5 | build: . 6 | image: ghcr.io/umputun/github-backup-docker:latest 7 | container_name: "github-backup" 8 | hostname: "github-backup" 9 | restart: always 10 | 11 | logging: 12 | driver: json-file 13 | options: 14 | max-size: "10m" 15 | max-file: "5" 16 | 17 | environment: 18 | - GITHUB_USER 19 | - TOKEN=${GITHUB_ACCESS_TOKEN} 20 | - MAX_BACKUPS=10 21 | - TIME_ZONE=America/Chicago 22 | - BACKUP_OPTIONS=--all --private --gists 23 | volumes: 24 | - ./var:/srv/var 25 | -------------------------------------------------------------------------------- /exec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TIME_ZONE=${TIME_ZONE:=UTC} 4 | echo "timezone=${TIME_ZONE}" 5 | 6 | BACKUP_OPTIONS=${BACKUP_OPTIONS:='--all --private --gists'} 7 | echo "backup options=${BACKUP_OPTIONS}" 8 | 9 | cp /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime 10 | echo "${TIME_ZONE}" >/etc/timezone 11 | 12 | echo "$(date) - start backup scheduler" 13 | while :; do 14 | DATE=$(date +%Y%m%d-%H%M%S) 15 | 16 | if [ -z "$GITHUB_USER" ] 17 | then 18 | echo "No Github users defined." 19 | else 20 | for u in $(echo $GITHUB_USER | tr "," "\n"); do 21 | echo "$(date) - execute backup for User ${u}, ${DATE}" 22 | github-backup ${u} --token=$TOKEN --output-directory=/srv/var/${DATE}/${u} ${BACKUP_OPTIONS} 23 | done 24 | fi 25 | 26 | if [ -z "$GITHUB_ORG" ] 27 | then 28 | echo "No Github organization defined." 29 | else 30 | for o in $(echo $GITHUB_ORG | tr "," "\n"); do 31 | echo "$(date) - execute backup for Organization ${u}, ${DATE}" 32 | github-backup ${o} --organization --token=$TOKEN --output-directory=/srv/var/${DATE}/${o} ${BACKUP_OPTIONS} 33 | done 34 | fi 35 | 36 | if [ -z "$GITHUB_USER" ] && [ -z "$GITHUB_ORG" ] 37 | then 38 | echo "No entities (user, organization) defined. No backup performed." 39 | else 40 | echo "Backup performed." 41 | fi 42 | 43 | echo "$(date) - cleanup" 44 | 45 | ls -d1 /srv/var/* | head -n -${MAX_BACKUPS} | xargs rm -rf 46 | 47 | echo "$(date) - sleep for 1 day" 48 | sleep 1d 49 | done 50 | --------------------------------------------------------------------------------