Skip to content

Commit

Permalink
Merge pull request #303 from modem7/s6
Browse files Browse the repository at this point in the history
Move to S6
  • Loading branch information
grantbevis authored Apr 1, 2024
2 parents 1959c61 + 7837fe8 commit 451b98d
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 53 deletions.
117 changes: 80 additions & 37 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,41 +1,84 @@
# syntax = docker/dockerfile:latest
FROM python:3.11.5-alpine3.18
LABEL maintainer='github.com/borgmatic-collective'
VOLUME /mnt/source
VOLUME /mnt/borg-repository

FROM python:3.12.2-alpine3.19 as base
ARG TARGETARCH

LABEL maintainer='borgmatic-collective'

FROM base AS base-amd64
ENV S6_OVERLAY_ARCH=x86_64

FROM base AS base-arm64
ENV S6_OVERLAY_ARCH=aarch64

FROM base-${TARGETARCH}${TARGETVARIANT}

ARG S6_OVERLAY_VERSION=3.1.6.2

# Add S6 Overlay
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.xz /tmp/s6-overlay.tar.xz
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp

# Add S6 optional symlinks
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-symlinks-noarch.tar.xz /tmp
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-symlinks-arch.tar.xz /tmp

ENV LANG='en_US.UTF-8' \
LANGUAGE='en_US.UTF-8' \
TERM='xterm' \
S6_LOGGING="1" \
S6_VERBOSITY="0" \
S6_CMD_WAIT_FOR_SERVICES_MAXTIME="0" \
TZ="Europe/London"

RUN <<EOF
set -xe
apk upgrade --update --no-cache
tar -C / -Jxpf /tmp/s6-overlay.tar.xz
tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz
tar -C / -Jxpf /tmp/s6-overlay-symlinks-noarch.tar.xz
tar -C / -Jxpf /tmp/s6-overlay-symlinks-arch.tar.xz

apk add --no-cache -U \
bash \
bash-completion \
bash-doc \
ca-certificates \
curl \
findmnt \
fuse \
libacl \
libxxhash \
logrotate \
lz4-libs \
mariadb-client \
mariadb-connector-c \
mongodb-tools \
openssl \
pkgconfig \
postgresql-client \
sqlite \
sshfs \
tzdata
apk upgrade --no-cache
EOF

COPY --link requirements.txt /

RUN --mount=type=cache,id=pip,target=/root/.cache,sharing=locked \
<<EOF
set -xe
python3 -m pip install -U pip
python3 -m pip install -Ur requirements.txt
borgmatic --bash-completion > "$(pkg-config --variable=completionsdir bash-completion)"/borgmatic
EOF

COPY --link root/ /

VOLUME /root/.borgmatic
VOLUME /etc/borgmatic.d
VOLUME /root/.config/borg
VOLUME /root/.ssh
VOLUME /root/.cache/borg
RUN apk add --update --no-cache \
bash \
bash-completion \
bash-doc \
ca-certificates \
curl \
findmnt \
fuse \
libacl \
logrotate \
lz4-libs \
mariadb-client \
mariadb-connector-c \
mongodb-tools \
openssl1.1-compat \
postgresql-client \
sqlite \
sshfs \
supercronic \
tzdata \
&& rm -rf \
/var/cache/apk/* \
/.cache

COPY --chmod=755 entry.sh /entry.sh
COPY requirements.txt /

RUN python3 -m pip install --no-cache -Ur requirements.txt
RUN borgmatic --bash-completion > /usr/share/bash-completion/completions/borgmatic && echo "source /etc/bash/bash_completion.sh" > /root/.bashrc

ENTRYPOINT ["/entry.sh"]

HEALTHCHECK --interval=30s --timeout=10s --start-period=20s --retries=3 CMD borgmatic config validate

ENTRYPOINT [ "/init" ]
38 changes: 24 additions & 14 deletions data/borgmatic.d/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,41 @@ repositories:
- path: /mnt/borg-repository
one_file_system: true


# Passphrase is set in variable $BORG_PASSPHRASE
# encryption_passphrase: "DoNotMissToChangeYourPassphrase"
# Passphase is set in varibable $BORG_PASSPHRASE
# encryption_passphrase: "DoNotForgetToChangeYourPassphrase"
compression: lz4
archive_name_format: 'backup-{now}'


keep_hourly: 2
keep_daily: 7
keep_weekly: 4
keep_monthly: 12
keep_yearly: 10



checks:
- name: repository
- name: archives
check_last: 3



before_backup:
- name: repository
frequency: 2 weeks
- name: archives
frequency: always
- name: extract
frequency: 2 weeks
- name: data
frequency: 1 month

hooks:
before_backup:
- echo "Starting a backup job."
after_backup:
- echo "Backup created."
on_error:
- echo "Error while creating a backup."

before_everything:
- echo "Starting a backup job."
after_backup:
after_everything:
- echo "Backup created."
on_error:
- echo "Error while creating a backup."

healthchecks:
ping_url: ${BORG_HEALTHCHECK_URL}
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
--extra-index-url https://dl.cloudsmith.io/public/borgmatic-collective/borgmatic/python/simple/

apprise==1.7.3
borgbackup==1.2.8
borgmatic==1.8.9
borgmatic[apprise]==1.8.9
llfuse==1.5.0
10 changes: 10 additions & 0 deletions root/etc/s6-overlay/s6-rc.d/svc-cron/finish
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

if test "$1" -eq 256 ; then
e=$((128 + $2))
else
e="$1"
fi

echo "Received exit code $e."
echo "$e" > /run/s6-linux-init-container-results/exitcode
115 changes: 115 additions & 0 deletions root/etc/s6-overlay/s6-rc.d/svc-cron/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/with-contenv bash

# Install DockerCLI if true
if [ "${DOCKERCLI:-}" == "true" ]; then
echo "Installing Docker CLI..."
apk add -U --quiet docker-cli
dockerver=$(docker --version | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+')
else
dockerver="not installed"
fi

# Version variables
borgver=$(borg --version)
borgmaticver=$(borgmatic --version)
apprisever=$(apprise --version | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+')
pythonver=$(python3 --version | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+')

# Software versions
echo "Software Versions:
-----------------------------------
apprise $apprisever
$borgver
borgmatic $borgmaticver
dockercli $dockerver
python $pythonver
-----------------------------------
Time Zone: $TZ
-----------------------------------
"

# Enable initial debug logging based on the DEBUG_SECRETS environment variable.
# Logs the initial values of BORG_PASSPHRASE and BORG_PASSPHRASE_FILE.
if [ "${DEBUG_SECRETS}" = "true" ] || [ "${DEBUG_SECRETS}" = "1" ]; then
echo "Before: BORG_PASSPHRASE: ${BORG_PASSPHRASE}"
echo "Before: BORG_PASSPHRASE_FILE: ${BORG_PASSPHRASE_FILE}"
echo "Before: YOUR_PASSPHRASE: ${YOUR_PASSPHRASE}"
echo "Before: YOUR_PASSPHRASE_FILE: ${YOUR_PASSPHRASE_FILE}"
fi

# Loop through all environment variables that start with 'BORG'.
for var_name in $(set | grep -E '^BORG|^YOUR' | awk -F= '{print $1}'); do
# Retrieve the current value of each environment variable.
var_value=$(eval echo \$$var_name)

# Check if the variable's name ends with '_FILE'.
if [[ "$var_name" =~ _FILE$ ]]; then
# Strip the '_FILE' suffix to obtain the corresponding variable name.
original_var_name=${var_name%_FILE}

# Retrieve the value of the original environment variable, if it exists.
original_var_value=$(eval echo \$$original_var_name)

# Ensure the *_FILE variable is valid, and the referenced file exists and is not empty.
if [ -n "$var_value" ] && [ -s "$var_value" ]; then
# Notify user if original variable is being overwritten.
if [ -n "$original_var_value" ]; then
echo "Note: $original_var_name was already set but is being overwritten by $var_name"
fi

# Update the original variable with the content of the file.
export "$original_var_name"=$(cat "$var_value")
echo "Setting $original_var_name from the content of $var_value"

# Unset the *_FILE environment variable.
unset "$var_name"
echo "Unsetting $var_name"
else
# Issue an error if the *_FILE variable is not properly set, or the file does not exist or is empty.
echo "Error: File $var_value does not exist or is empty."
fi
fi
done

# Enable final debug logging based on the DEBUG_SECRETS environment variable.
# Logs the final values of BORG_PASSPHRASE and BORG_PASSPHRASE_FILE.
if [ "${DEBUG_SECRETS}" = "true" ] || [ "${DEBUG_SECRETS}" = "1" ]; then
echo "Before: BORG_PASSPHRASE: ${BORG_PASSPHRASE}"
echo "Before: BORG_PASSPHRASE_FILE: ${BORG_PASSPHRASE_FILE}"
echo "Before: YOUR_PASSPHRASE: ${YOUR_PASSPHRASE}"
echo "Before: YOUR_PASSPHRASE_FILE: ${YOUR_PASSPHRASE_FILE}"
fi

# Disable cron if it's set to disabled.
if [[ "$CRON" = "false" ]]; then
echo "Disabling cron, removing configuration"
# crontab -r # quite destructive
# echo -n > /etc/crontabs/root # Empty config, doesn't look as nice with "crontab -l"
echo "# Cron disabled" > /etc/crontabs/root
echo "Cron is now disabled"
# Apply default or custom cron if $CRON is unset or set (not null):
elif [[ -v CRON ]]; then
CRON="${CRON:-"0 1 * * *"}"
CRON_COMMAND="${CRON_COMMAND:-"borgmatic --stats -v 0 2>&1"}"
echo "$CRON $CRON_COMMAND" > /etc/crontabs/root
echo "Applying custom cron"
# If nothing is set, revert to default behaviour
else
echo "Applying crontab.txt"
crontab /etc/borgmatic.d/crontab.txt
fi

# Apply extra cron if it's set
if [ -v EXTRA_CRON ]
then
echo "$EXTRA_CRON" >> /etc/crontabs/root
fi

# Current crontab var
crontab=$(crontab -l)

# Output cron settings to console
printf "Cron job set as: \n$crontab\n"

# Start Cron
exec /usr/sbin/crond -f -L /dev/stdout
1 change: 1 addition & 0 deletions root/etc/s6-overlay/s6-rc.d/svc-cron/type
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
longrun
Empty file.

0 comments on commit 451b98d

Please sign in to comment.