diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..fa64aae --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,45 @@ +name: Docker + +on: + release: + types: [published] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8ee90e9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +FROM golang:1.25 AS builder + +WORKDIR /src + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . + +RUN CGO_ENABLED=0 go build -o /gitbackup . + +FROM debian:bookworm-slim + +RUN apt-get update \ + && apt-get install -y --no-install-recommends git ca-certificates \ + && rm -rf /var/lib/apt/lists/* \ + && groupadd -g 65532 nonroot \ + && useradd -r -u 65532 -g nonroot -d /home/nonroot -m nonroot + +COPY --from=builder /gitbackup /gitbackup + +USER nonroot:nonroot + +ENTRYPOINT ["/gitbackup"] diff --git a/README.md b/README.md index d229421..1fb7fcb 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Contact us for any custom on-prem or cloud deployment, new feature requests or e - [gitbackup - Backup your GitHub, GitLab, Bitbucket, and Forgejo repositories](#gitbackup---backup-your-github-gitlab-and-bitbucket-repositories) - [Introduction](#introduction) - [Installing `gitbackup`](#installing-gitbackup) + - [Docker image](#docker-image) - [Using `gitbackup`](#using-gitbackup) - [GitHub Specific oAuth App Flow](#github-specific-oauth-app-flow) - [OAuth Scopes/Permissions required](#oauth-scopespermissions-required) @@ -56,6 +57,112 @@ and architecture and copy the binary somewhere in your ``$PATH``. It is recommen If you are on MacOS, a community member has created a [Homebrew formula](https://formulae.brew.sh/formula/gitbackup). +### Docker image + +Docker images are published to [GitHub Container Registry](https://github.com/amitsaha/gitbackup/pkgs/container/gitbackup) on every release: + +```bash +docker pull ghcr.io/amitsaha/gitbackup: +``` + +Replace `` with the desired release tag (e.g. `0.9.1`). + +The container runs as a non-root user (`nonroot`, UID `65532`). HTTPS cloning (`-use-https-clone`) is recommended inside containers because it requires no SSH key management. + +#### Linux + +On Linux, Docker runs natively so container UIDs map directly to host UIDs. Before mounting a backup directory, grant write access to UID `65532`: + +```bash +mkdir -p /data/gitbackup +chown 65532:65532 /data/gitbackup +``` + +Run with HTTPS cloning (recommended): + +```bash +docker run --rm \ + -e GITHUB_TOKEN= \ + -v /data/gitbackup:/backup \ + ghcr.io/amitsaha/gitbackup: \ + -service github -backupdir /backup -use-https-clone +``` + +If you need SSH cloning, make a copy of your private key readable by UID `65532` and mount it: + +```bash +cp $HOME/.ssh/id_rsa /tmp/gitbackup_id_rsa +chown 65532 /tmp/gitbackup_id_rsa +chmod 600 /tmp/gitbackup_id_rsa + +docker run --rm \ + -e GITHUB_TOKEN= \ + -v /data/gitbackup:/backup \ + -v /tmp/gitbackup_id_rsa:/home/nonroot/.ssh/id_rsa:ro \ + -v $HOME/.ssh/known_hosts:/home/nonroot/.ssh/known_hosts:ro \ + ghcr.io/amitsaha/gitbackup: \ + -service github -backupdir /backup +``` + +#### macOS + +Docker Desktop for Mac runs containers inside a Linux VM and translates volume mounts through its filesystem layer (VirtioFS). Because of this translation, the container UID (`65532`) is mapped automatically — you do **not** need to `chown` the host directory. Paths use the same Unix syntax as Linux. + +```bash +mkdir -p $HOME/gitbackup + +docker run --rm \ + -e GITHUB_TOKEN= \ + -v $HOME/gitbackup:/backup \ + ghcr.io/amitsaha/gitbackup: \ + -service github -backupdir /backup -use-https-clone +``` + +SSH cloning on macOS requires the same key-ownership step as Linux. Although VirtioFS handles write permissions for the backup directory automatically, `git` performs a strict ownership check on the SSH private key inside the container — the key file must be owned by the user running inside the container (UID `65532`). Host UIDs on macOS are unrelated to container UIDs, so the ownership must be set explicitly on a copy of the key: + +```bash +cp $HOME/.ssh/id_rsa /tmp/gitbackup_id_rsa +chown 65532 /tmp/gitbackup_id_rsa +chmod 600 /tmp/gitbackup_id_rsa + +docker run --rm \ + -e GITHUB_TOKEN= \ + -v $HOME/gitbackup:/backup \ + -v /tmp/gitbackup_id_rsa:/home/nonroot/.ssh/id_rsa:ro \ + -v $HOME/.ssh/known_hosts:/home/nonroot/.ssh/known_hosts:ro \ + ghcr.io/amitsaha/gitbackup: \ + -service github -backupdir /backup +``` + +#### Windows + +Docker Desktop for Windows (WSL2 backend recommended) translates volume mounts through the WSL2 VM, so no `chown` is needed on the host directory. Use PowerShell syntax for environment variables and paths: + +```powershell +# PowerShell +New-Item -ItemType Directory -Force "$env:USERPROFILE\gitbackup" + +docker run --rm ` + -e GITHUB_TOKEN=$env:GITHUB_TOKEN ` + -v "${env:USERPROFILE}\gitbackup:/backup" ` + ghcr.io/amitsaha/gitbackup: ` + -service github -backupdir /backup -use-https-clone +``` + +If you prefer Command Prompt: + +```cmd +mkdir %USERPROFILE%\gitbackup + +docker run --rm ^ + -e GITHUB_TOKEN=%GITHUB_TOKEN% ^ + -v "%USERPROFILE%\gitbackup:/backup" ^ + ghcr.io/amitsaha/gitbackup: ^ + -service github -backupdir /backup -use-https-clone +``` + +SSH cloning on Windows requires your SSH key to be accessible from WSL2 or Docker Desktop. The recommended approach is to store your key under WSL2 and mount it using a WSL path, or use HTTPS cloning to avoid SSH key management altogether. + ## Using `gitbackup` ``gitbackup`` requires a [GitHub API access token](https://github.com/blog/1509-personal-api-tokens) for