diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5c1b04d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.trivy*
+.version
+.vscode/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..98c635f
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,8 @@
+include:
+ - project: 'docker/builder'
+ file: '/templates/.gitlab-ci.yml'
+
+variables:
+ BUILD_IMAGE_SCRIPT: .gitlab-ci/build-image.sh
+ BUILD_MANIFEST_SCRIPT: .gitlab-ci/build-manifest.sh
+ MULTIARCH: 1
diff --git a/.gitlab-ci/build-image.sh b/.gitlab-ci/build-image.sh
new file mode 100755
index 0000000..2ce22e4
--- /dev/null
+++ b/.gitlab-ci/build-image.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+source /usr/local/share/build-functions.sh
+
+exit_if_image_present
+
+export ARG_BORG_VERSION="${VERSION}"
+build-image.sh
diff --git a/.gitlab-ci/build-manifest.sh b/.gitlab-ci/build-manifest.sh
new file mode 100755
index 0000000..f9acaad
--- /dev/null
+++ b/.gitlab-ci/build-manifest.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+source /usr/local/share/build-functions.sh
+
+exit_if_image_present
+
+build-manifest.sh
+TAG=latest build-manifest.sh
diff --git a/.gitlab-ci/version.sh b/.gitlab-ci/version.sh
new file mode 100755
index 0000000..24209a5
--- /dev/null
+++ b/.gitlab-ci/version.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e -o pipefail
+
+curl -s "https://api.github.com/repos/borgbackup/borg/tags" \
+| jq -r '.[].name' \
+| grep -v '[a-zA-Z]' \
+| sort -V \
+| tail -1
diff --git a/Dockerfile b/Dockerfile
index 81064b2..cb6e3f1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,24 +1,42 @@
-FROM debian:9
+FROM tgbyte/ubuntu:24.04
-ENV BORG_VERSION=1.1.14
+ARG BORG_VERSION
RUN set -x \
- && apt-get update \
- && apt-get install -y curl \
- && sed -i "s/httpredir.debian.org/`curl -s -D - http://httpredir.debian.org/demo/debian/ | awk '/^Link:/ { print $2 }' | sed -e 's@;@\1@g'`/" /etc/apt/sources.list \
- && apt-get update \
- && apt-get install -y openssh-server python3-pip build-essential libssl-dev libssl1.0.2 liblz4-dev liblz4-1 libacl1-dev libacl1 \
+ && apt-get update -qq \
+ && DEBIAN_FRONTEND=noninteractive apt-get install -qq -y \
+ build-essential \
+ libacl1 \
+ libacl1-dev \
+ liblz4-1 \
+ liblz4-dev \
+ libssl3t64 \
+ libssl-dev \
+ libxxhash0 \
+ libxxhash-dev \
+ libzstd1 \
+ libzstd-dev \
+ openssh-server \
+ python3 \
+ python3-pip \
+ python3-pkgconfig \
+ python3-setuptools \
+ python3-setuptools-scm \
&& rm -f /etc/ssh/ssh_host_* \
- && pip3 install borgbackup==$BORG_VERSION \
- && apt-get remove -y --purge build-essential libssl-dev liblz4-dev libacl1-dev \
+ && python3 --version \
+ && pip3 install --break-system-packages -v "borgbackup==${BORG_VERSION}" \
+ && apt-get remove -y --purge \
+ build-essential \
+ libacl1-dev \
+ liblz4-dev \
+ libssl-dev \
+ libxxhash-dev \
+ libzstd-dev \
&& apt-get autoremove -y --purge \
&& adduser --uid 500 --disabled-password --gecos "Borg Backup" --quiet borg \
- && mkdir /var/run/sshd \
- && mkdir /var/backups/borg \
- && chown borg.borg /var/backups/borg \
- && mkdir /home/borg/.ssh \
+ && mkdir -p /var/run/sshd /var/backups/borg /var/lib/docker-borg/ssh mkdir /home/borg/.ssh \
+ && chown borg.borg /var/backups/borg /home/borg/.ssh \
&& chmod 700 /home/borg/.ssh \
- && chown borg.borg /home/borg/.ssh \
&& rm -rf /var/lib/apt/lists/*
RUN set -x \
@@ -29,7 +47,7 @@ RUN set -x \
-e 's/^#LogLevel .*$/LogLevel ERROR/g' \
/etc/ssh/sshd_config
-VOLUME /var/backups/borg
+VOLUME ["/var/backups/borg", "/var/lib/docker-borg"]
ADD ./entrypoint.sh /
diff --git a/README.md b/README.md
index 5a0d6b2..c268535 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# docker-borg-backup
-A dockerized Borg Backup server. For more information about Borg Backup, an excellent deduplicating backup, refer to: https://www.borgbackup.org/
+A dockerized Borg Backup server. For more information about Borg Backup, an excellent de-duplicating backup, refer to: https://www.borgbackup.org/
## Usage
@@ -10,16 +10,21 @@ docker run -e BORG_AUTHORIZED_KEYS= -e BORG_UID= -e BOR
Alternatively, use the Docker orchestrator of your choice.
-**Caution:** Do NOT forget to mount a volume into the Borg container. Otherwise your backups will vanish into thin air when you update the Borg container.
+**Caution:** Do NOT forget to mount a volume as `/var/backups/borg` to host the backups. Otherwise your backups will vanish into thin air when you update the Borg container.
+To persist the container's SSH host keys across container updates, mount a volume to `/var/lib/docker-borg`.
+
+## Supported Architectures
+
+This image is available for the `amd64` and `arm64` architectures.
## License
-The files contained in this Git repository are licensed under the following license. This license explicitly does not cover the Borg Backup and Debian software packaged when running the Docker build. For these componensts, separate licenses apply that you can find at:
+The files contained in this Git repository are licensed under the following license. This license explicitly does not cover the Borg Backup and Ubuntu software packaged when running the Docker build. For these components, separate licenses apply that you can find at:
* https://borgbackup.readthedocs.io/en/stable/authors.html#license
-* https://www.debian.org/legal/licenses/
+* https://ubuntu.com/licensing
-Copyright 2018 TG Byte Software GmbH
+Copyright 2018-2025 TG Byte Software GmbH
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/entrypoint.sh b/entrypoint.sh
index 50efa07..14041bb 100755
--- a/entrypoint.sh
+++ b/entrypoint.sh
@@ -1,23 +1,34 @@
#!/bin/bash
-dpkg-reconfigure openssh-server
+mkdir -p /var/lib/docker-borg/ssh > /dev/null 2>&1
+
+if [ ! -f /var/lib/docker-borg/ssh/ssh_host_rsa_key ]; then
+ echo "Creating SSH keys. To persist keys across container updates, mount a volume to /var/lib/docker-borg..."
+ ssh-keygen -A
+ mv /etc/ssh/ssh*key* /var/lib/docker-borg/ssh/
+fi
+
+# Ensure correct permissions for ssh keys
+chmod -R og-rwx /var/lib/docker-borg/ssh/
+
+ln -sf /var/lib/docker-borg/ssh/* /etc/ssh > /dev/null 2>&1
if [ -n "${BORG_UID}" ]; then
- usermod -u ${BORG_UID} borg
+ usermod -u "${BORG_UID}" borg
fi
if [ -n "${BORG_GID}" ]; then
- groupmod -o -g ${BORG_GID} borg
- usermod -g ${BORG_GID} borg
+ groupmod -o -g "${BORG_GID}" borg
+ usermod -g "${BORG_GID}" borg
fi
if [ ! -z ${BORG_AUTHORIZED_KEYS+x} ]; then
- echo -e $BORG_AUTHORIZED_KEYS > /home/borg/.ssh/authorized_keys
- chown borg.borg /home/borg/.ssh/authorized_keys
+ echo -e "${BORG_AUTHORIZED_KEYS}" > /home/borg/.ssh/authorized_keys
+ chown borg:borg /home/borg/.ssh/authorized_keys
chmod og-rwx /home/borg/.ssh/authorized_keys
fi
-chown -R borg.borg /home/borg
-chown -R borg.borg /home/borg/.ssh
+chown -R borg:borg /home/borg
+chown -R borg:borg /home/borg/.ssh
exec /usr/sbin/sshd -D -e