78 Commits

Author SHA1 Message Date
dependabot[bot]
29efee9147 Bump sigstore/cosign-installer from 3.8.2 to 4.0.0
Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.8.2 to 4.0.0.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.8.2...v4.0.0)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 4.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-01 04:14:14 +00:00
Max Konrädi
47d29529e9 chore: Changelog 2025-08-13 15:19:14 +02:00
Max Konrädi
97c74a94a7 Revert "feat: add restic check after forget with prune"
This reverts commit 5f2b322e54.
2025-08-13 15:15:37 +02:00
Max Konrädi
901cd5487f chore: Changelog 2025-08-13 14:58:23 +02:00
Max Konrädi
a66e72cb7e Merge pull request #103 from lobaro/feat/check_after_forget_prune
feat: add restic check after forget with prune
2025-08-13 14:56:17 +02:00
Max Konrädi
5f2b322e54 feat: add restic check after forget with prune 2025-08-13 13:43:48 +02:00
Max Konrädi
50e6fdbdf2 chore: Update CHANGELOG.md
v1.4.0
2025-04-23 15:04:50 +02:00
Max Konrädi
281c77f000 Merge pull request #88 from modem/patch-1
Update README.md
2025-04-23 14:54:58 +02:00
Max Konrädi
2dd2b9ec2f Merge pull request #94 from lobaro/dependabot/github_actions/sigstore/cosign-installer-3.8.2
Bump sigstore/cosign-installer from 3.8.1 to 3.8.2
2025-04-23 14:53:11 +02:00
Max Konrädi
d864717eca Merge pull request #95 from lobaro/chore/restic_upgrade
chore: remove arm64 specific dockerfile - platform target now impleme…
2025-04-23 14:52:04 +02:00
dependabot[bot]
5b057f7554 Bump sigstore/cosign-installer from 3.8.1 to 3.8.2
Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.8.1 to 3.8.2.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.8.1...v3.8.2)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 3.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-23 12:51:07 +00:00
Max Konrädi
aac1a371e1 Merge pull request #90 from krombel/master
Update restic, rclone and workflow dependencies
2025-04-23 14:50:28 +02:00
Max Konrädi
ff27b6e0c4 Merge branch 'master' into master 2025-04-23 14:48:20 +02:00
Max Konrädi
424d4552cc Update dependabot.yml 2025-04-23 14:47:22 +02:00
Max Konrädi
30df2e301a chore: remove arm64 specific dockerfile - platform target now implemented in main dockerfile 2025-04-23 14:38:57 +02:00
Max Konrädi
4a3487bc1a Merge pull request #87 from zimbres/master
Multiarch Docker images / Backup_Sources Folder option
2025-04-23 14:31:28 +02:00
Max Konrädi
61e741240d Merge branch 'master' into master 2025-04-23 14:31:04 +02:00
Max Konrädi
646a4ffc40 Merge pull request #93 from lobaro/chore/restic_upgrade
Chore/restic upgrade
2025-04-22 11:16:36 +02:00
Max Konrädi
db48b9982a Merge branch 'master' into chore/restic_upgrade 2025-04-22 11:15:58 +02:00
Max Konrädi
3c113ab2f4 feat: add shadow package for simple user management 2025-04-22 11:14:25 +02:00
Max Konrädi
f695ea5253 Chore/restic upgrade (#92)
* chore: update restic to 0.18.0

* feat: add arm64 specific dockerfile

* fix: for podman compatibility prefix image with'docker.io/'
2025-04-16 18:13:33 +02:00
Max Konrädi
e38f19c6d2 fix: default dockerfile uses amd64 arch 2025-04-16 18:12:21 +02:00
Max Konrädi
214edc2721 fix: for podman compatibility prefix image with'docker.io/' 2025-04-16 15:25:17 +02:00
Max Konrädi
e75e026e92 feat: add arm64 specific dockerfile 2025-04-16 15:03:33 +02:00
Max Konrädi
740b897581 chore: update restic to 0.18.0 2025-04-16 13:35:23 +02:00
Matthias Kesler
e7b7efa431 Merge pull request #2 from krombel/dependabot/docker/restic/restic-0.18.0
Bump restic/restic from 0.17.3 to 0.18.0
2025-04-01 14:58:28 +02:00
dependabot[bot]
53aba762e2 Bump restic/restic from 0.17.3 to 0.18.0
Bumps restic/restic from 0.17.3 to 0.18.0.

---
updated-dependencies:
- dependency-name: restic/restic
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-01 10:38:59 +00:00
Matthias Kesler
dbd3e9c459 Merge pull request #1 from krombel/dependabot/github_actions/sigstore/cosign-installer-3.8.1
Bump sigstore/cosign-installer from 3.7.0 to 3.8.1
2025-03-05 14:16:49 +01:00
Matthias Kesler
36e90b55e1 Update cosign version accordingly 2025-03-05 14:15:49 +01:00
dependabot[bot]
04fa95a5be Bump sigstore/cosign-installer from 3.7.0 to 3.8.1
Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.7.0 to 3.8.1.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.7.0...v3.8.1)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-01 10:29:46 +00:00
Matthias Kesler
0fd1e1da91 Create dependabot.yml 2025-01-16 18:52:25 +01:00
Matthias Kesler
157bc07533 Update to restic 0.17.3 2024-11-15 18:51:46 +01:00
Matthias Kesler
1b7d44a85e update github workflow dependencies 2024-10-07 17:58:08 +02:00
Matthias Kesler
b2c209cbc0 update restic 2024-10-07 17:48:42 +02:00
modem
9967b3fb2a Update README.md
Fix image in docker compose example
2024-04-17 14:54:16 +01:00
Marcio Zimbres
2f0ce618b8 Adjust file name of rclone zip in Dockerfile 2023-12-07 20:23:09 -03:00
Marcio Zimbres
b2616ef2dc Adjust Dockerfile in order to download rclone that matches container architecture 2023-12-07 19:55:23 -03:00
Marcio Zimbres
9b829f90e0 Change Action to add multi-platform image build 2023-12-07 19:25:36 -03:00
Marcio Zimbres
bf2dabd2c7 Added option to set the target folder backup 2023-12-07 14:02:36 -03:00
Tobias Kaupat
c2ae895ed8 Update README.md 2023-08-06 00:02:38 +02:00
Tobias Kaupat
47b30e90b1 Update CHANGELOG.md 2023-08-06 00:00:45 +02:00
Tobias Kaupat
e25f09d0ce Update README.md 2023-08-06 00:00:18 +02:00
Tobias Kaupat
a018fdc2ec Fix mailx setup for latest restic image that is based on latest alpine
- mailx is known as mail in alpine
2023-08-05 23:54:01 +02:00
Tobias Kaupat
1d222b9798 Update CHANGELOG.md
fix typos
2023-08-05 23:08:21 +02:00
Tobias Kaupat
e09de3ee18 Update README.md 2023-08-05 23:04:31 +02:00
Tobias Kaupat
33d48e8e0d Update CHANGELOG.md 2023-08-05 22:53:40 +02:00
Tobias Kaupat
412a96877f Update to restic 0.16.0 2023-08-05 22:40:12 +02:00
Tobias Kaupat
ffcf548155 Link new docker container in readme 2023-08-05 22:34:25 +02:00
Tobias Kaupat
5fab635af0 Create docker-publish.yml 2023-08-05 22:26:48 +02:00
Felix Sherrington-Kendall
389fcaa995 📚 Fix minor typos and formatting in README. 2023-08-02 22:53:46 +02:00
Alex Joedt
beb5fa841c Fix shebang in entry.sh 2023-08-02 22:51:20 +02:00
Tobias Kaupat
bc000ef4f8 Merge pull request #73 from lojutaan/check
Update restic to version 0.14.0 and add option to check data integrity
2023-01-03 08:29:15 +01:00
Tobias Kaupat
5155c3b351 Merge branch 'master' into check 2023-01-03 08:27:34 +01:00
Haneef
fa34734660 Restic updated 2023-01-03 08:23:19 +01:00
Niko
7e0b0706c1 Update restic to version 0.13.1 and add option to check data integrity 2022-08-17 19:14:39 +03:00
0chroma
820fabb1e6 add RESTIC_INIT_ARGS docs 2022-01-19 22:14:46 +01:00
0chroma
e94df72518 add init args env variable 2022-01-19 22:14:46 +01:00
Tobias Kaupat
36f771b781 Remove duplicate ENV 2021-08-07 19:20:09 +02:00
Kevin Köllmann
f308eca25b Fix minor typos in log output of backup.sh 2021-05-05 20:15:34 +02:00
Victor Fauth
0b72ec94a7 Update to restic 0.12.0 2021-04-07 12:58:55 +02:00
Victor Fauth
84c8ed0c0d Update to restic 0.11.0 2020-12-27 14:30:31 +01:00
Tobias Kaupat
a118fb5594 Merge pull request #56 from enuuros/add-webhook
Add support for webhooks
2020-12-27 14:29:57 +01:00
Tobias Kaupat
0c32b273e9 Merge branch 'master' into add-webhook 2020-12-27 14:28:14 +01:00
Erfan Sahafnejad
5110483351 Add Microsoft Teams notifier 2020-12-27 14:26:14 +01:00
Christian Studer
93e76c46fe README: Adds additional info for rclone backends 2020-12-27 14:21:00 +01:00
Esa Nuuros
4d2034ccd4 Pass backup exit code to post-backup.sh hook
We can write our own hook that can choose what to do based on the exit code.
For example, we may only want to sent notifications on failures.
2020-10-26 15:13:37 +02:00
Esa Nuuros
265c33f2d9 Do not exit on backup failure
Exit caused email notifications to be not sent when backup fails. We especially
want to be notified if a backup fails.
2020-10-26 15:12:19 +02:00
Esa Nuuros
268987fd8e Install curl for webhooks 2020-10-26 15:00:49 +02:00
Tobias Kaupat
4f60e830af Some README about common usecases 2020-09-28 11:18:18 +02:00
Tobias Kaupat
925930000c use exit instead of kill to end script 2020-08-06 08:44:18 +02:00
Dan Rabinowitz
ed609ae89d Ensure that only a single backup runs at one time 2020-08-06 08:43:28 +02:00
Dan Rabinowitz
317ecba765 Remove unused code 2020-08-06 08:42:28 +02:00
Lucas Breton
46df366e4c Add pre and post backup hooks 2020-08-06 08:39:07 +02:00
Lucas Breton
23a05d88b9 Update README.md 2020-08-06 08:39:07 +02:00
Lucas Breton
d3297615e2 Add environment variables to allow backup via OpenStack Swift 2020-08-06 08:39:07 +02:00
Aldo D'Aquino
a07b831d78 Fix missing permissions also on .cache 2020-07-07 18:02:03 +02:00
Aldo D'Aquino
b85c6d9603 Fix permission denied on OpenShift
Refer to https://docs.openshift.com/container-platform/4.4/openshift_images/create-images.html#use-uid_create-images
2020-07-07 18:02:03 +02:00
Tobias Kaupat
5b4d050643 add CHANGELOG.md 2020-05-18 18:17:55 +02:00
8 changed files with 479 additions and 60 deletions

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# Docs: <https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/customizing-dependency-updates>
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule: {interval: monthly}
- package-ecosystem: docker
directory: /
schedule: {interval: monthly}

96
.github/workflows/docker-publish.yml vendored Normal file
View File

@@ -0,0 +1,96 @@
name: Docker
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
on:
push:
branches: [ "master" ]
# Publish semver tags as releases.
tags: [ 'v*.*.*' ]
pull_request:
branches: [ "master" ]
env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/cosign-installer@v4.0.0
with:
cosign-release: 'v2.4.3'
# Workaround: https://github.com/docker/build-push-action/issues/461
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v3
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
# repository is public to avoid leaking data. If you would like to publish
# transparency data even for private images, pass --force to cosign below.
# https://github.com/sigstore/cosign
- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
TAGS: ${{ steps.meta.outputs.tags }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}

61
CHANGELOG.md Normal file
View File

@@ -0,0 +1,61 @@
# Changelog
## v1.4.2
### Removed
* Execute a repository check after prune was passed as a parameter in the forget call - use RESTIC_CHECK_CRON Var instead
## v1.4.1
### Changed
* Execute a repository check after prune was passed as a parameter in the forget call
## v1.4.0
### Added
* Option to set the target folder backup
* Multi-platform image build
## v1.3.2 (restic 0.16.0)
### Changed
* Base image directly on official restic image
* [Semver](https://semver.org/) aligned version naming including restic version
* Updated to restic 0.16.0
### Added
* rclone to docker image
* Implemented a simple mail notification after backups using mailx
* MAILX_ARGS environment variable
## v1.3.1-0.9.6
### Changed
* Update to Restic v0.9.5
* Reduced the number of layers in the Docker image
### Fixed
* Check if a repo already exists works now for all repository types
### Added
* shh added to container
* fuse added to container
* support to send mails using external SMTP server after backups
## v1.2-0.9.4
### Added
* AWS Support
## v1.1
### Fixed
* `--prune` must be passed to `RESTIC_FORGET_ARGS` to execute prune after forget.
### Changed
* Switch to base Docker container to `golang:1.7-alpine` to support latest restic build.
## v1.0
Initial release.
The container has proper logs now and was running for over a month in production.
There are still some features missing. Sticking to semantic versioning we do not expect any breaking changes in the 1.x releases.

View File

@@ -1,13 +1,21 @@
FROM alpine:latest as rclone
FROM --platform=$TARGETPLATFORM docker.io/alpine:latest as rclone
ARG TARGETPLATFORM
RUN apk add wget
# Get rclone executable
ADD https://downloads.rclone.org/rclone-current-linux-amd64.zip /
RUN unzip rclone-current-linux-amd64.zip && mv rclone-*-linux-amd64/rclone /bin/rclone && chmod +x /bin/rclone
RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
wget https://downloads.rclone.org/rclone-current-linux-amd64.zip && unzip rclone-current-linux-amd64.zip && mv rclone-*-linux-amd64/rclone /bin/rclone && chmod +x /bin/rclone; \
elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
wget https://downloads.rclone.org/rclone-current-linux-arm64.zip && unzip rclone-current-linux-arm64.zip && mv rclone-*-linux-arm64/rclone /bin/rclone && chmod +x /bin/rclone; \
elif [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \
wget https://downloads.rclone.org/rclone-current-linux-arm-v7.zip && unzip rclone-current-linux-arm-v7.zip && mv rclone-*-linux-arm-v7/rclone /bin/rclone && chmod +x /bin/rclone; \
fi
FROM restic/restic:0.9.6
# install mailx
RUN apk add --update --no-cache heirloom-mailx fuse
FROM docker.io/restic/restic:0.18.0
RUN apk add --update --no-cache curl mailx shadow
COPY --from=rclone /bin/rclone /bin/rclone
@@ -20,18 +28,41 @@ ENV RESTIC_PASSWORD=""
ENV RESTIC_TAG=""
ENV NFS_TARGET=""
ENV BACKUP_CRON="0 */6 * * *"
ENV CHECK_CRON=""
ENV RESTIC_INIT_ARGS=""
ENV RESTIC_FORGET_ARGS=""
ENV RESTIC_JOB_ARGS=""
ENV RESTIC_DATA_SUBSET=""
ENV MAILX_ARGS=""
ENV OS_AUTH_URL=""
ENV OS_PROJECT_ID=""
ENV OS_PROJECT_NAME=""
ENV OS_USER_DOMAIN_NAME="Default"
ENV OS_PROJECT_DOMAIN_ID="default"
ENV OS_USERNAME=""
ENV OS_PASSWORD=""
ENV OS_REGION_NAME=""
ENV OS_INTERFACE=""
ENV OS_IDENTITY_API_VERSION=3
ENV BACKUP_SOURCES=""
# openshift fix
RUN mkdir /.cache && \
chgrp -R 0 /.cache && \
chmod -R g=u /.cache && \
chgrp -R 0 /mnt && \
chmod -R g=u /mnt && \
chgrp -R 0 /var/spool/cron/crontabs/root && \
chmod -R g=u /var/spool/cron/crontabs/root && \
chgrp -R 0 /var/log/cron.log && \
chmod -R g=u /var/log/cron.log
# /data is the dir where you have to put the data to be backed up
VOLUME /data
COPY backup.sh /bin/backup
COPY check.sh /bin/check
COPY entry.sh /entry.sh
WORKDIR "/"
ENTRYPOINT ["/entry.sh"]
CMD ["tail","-fn0","/var/log/cron.log"]

176
README.md
View File

@@ -7,45 +7,60 @@ This container runs restic backups in regular intervals.
* Support for different targets (tested with: Local, NFS, SFTP, AWS)
* Support `restic mount` inside the container to browse the backup files
**Container**: [lobaro/restic-backup-docker](https://hub.docker.com/r/lobaro/restic-backup-docker/)
**Container**:
* [ghcr.io/lobaro/restic-backup-docker](https://github.com/lobaro/restic-backup-docker/pkgs/container/restic-backup-docker)
* Old: [lobaro/restic-backup-docker](https://hub.docker.com/r/lobaro/restic-backup-docker/)
Stable
Latest master (experimental):
```
docker pull lobaro/restic-backup-docker:1.2-0.9.4
docker pull ghcr.io/lobaro/restic-backup-docker:master
```
Latest (experimental)
Latest release:
```
docker pull lobaro/restic-backup-docker:latest
docker pull ghcr.io/lobaro/restic-backup-docker:latest
```
Please don't hesitate to report any issue you find. **Thanks.**
# Contributing
Pull Requests to improve the image are always wellcome. Please create an issue about the PR first.
When behaviour of the image changes (Features, Bugfixes, Changes in the API) please update the "Unreleased" section of the [CHANGELOG.md](https://github.com/lobaro/restic-backup-docker/blob/master/CHANGELOG.md)
## Hooks
If you need to execute a script before or after each backup or check, you need to add your hook scripts in the container folder `/hooks`:
```
-v ~/home/user/hooks:/hooks
```
Call your pre-backup script `pre-backup.sh` and post-backup script `post-backup.sh`. You can also have separate scripts when running data verification checks `pre-check.sh` and `post-check.sh`.
Please don't hesitate to report any issues you find. **Thanks.**
# Test the container
Clone this repository
Clone this repository:
```
git clone https://github.com/Lobaro/restic-backup-docker.git
cd restic-backup-docker
```
Build the container. The container is named `backup-test`
Build the container (the container is named `backup-test`):
```
./build.sh
```
Run the container.
Run the container:
```
./run.sh
```
This will run the container `backup-test` with the name `backup-test`. Existing containers with that names are completly removed automatically.
This will run the container `backup-test` with the name `backup-test`. Existing containers with that name are completely removed automatically.
The container will backup `~/test-data` to a repository with password `test` at `~/test-repo` every minute. The repository is initialized automatically by the container.
To enter your container execute
The container will back up `~/test-data` to a repository with password `test` at `~/test-repo` every minute. The repository is initialized automatically by the container. If you'd like to change the arguments passed to `restic init`, you can do so using the `RESTIC_INIT_ARGS` env variable.
To enter your container execute:
```
docker exec -ti backup-test /bin/sh
```
@@ -53,31 +68,81 @@ docker exec -ti backup-test /bin/sh
Now you can use restic [as documented](https://restic.readthedocs.io/en/stable/), e.g. try to run `restic snapshots` to list all your snapshots.
## Logfiles
Logfiles are inside the container. If needed you can create volumes for them.
Logfiles are inside the container. If needed, you can create volumes for them.
```
docker logs
```
Shows `/var/log/cron.log`
Shows `/var/log/cron.log`.
Additionally you can see the the full log, including restic output, of the last execution in `/var/log/backup-last.log`. When the backup fails the log is copied to `/var/log/restic-error-last.log`. If configured, you can find the full output of the mail notification in `/var/log/mail-last.log`.
Additionally you can see the full log, including restic output, of the last execution in `/var/log/backup-last.log`. When the backup fails, the log is copied to `/var/log/restic-error-last.log`. If configured, you can find the full output of the mail notification in `/var/log/mail-last.log`.
# Use the running container
Assuming the container name is `restic-backup-var`, you can execute restic with:
docker exec -ti restic-backup-var restic
## Backup
To execute a backup manually, independent of the CRON, run:
docker exec -ti restic-backup-var /bin/backup
Back up a single file or directory:
docker exec -ti restic-backup-var restic backup /data/path/to/dir --tag my-tag
## Data verification check
To verify backup integrity and consistency manually, independent of the CRON, run:
docker exec -ti restic-backup-var /bin/check
## Restore
You might want to mount a separate host volume at e.g. `/restore` to not override existing data while restoring.
Get your snapshot ID with:
docker exec -ti restic-backup-var restic snapshots
e.g. `abcdef12`
docker exec -ti restic-backup-var restic restore --include /data/path/to/files --target / abcdef12
The target is `/` since all data backed up should be inside the host mounted `/data` dir. If you mount `/restore` you should set `--target /restore` and the data will end up in `/restore/data/path/to/files`.
# Customize the Container
The container is setup by setting [environment variables](https://docs.docker.com/engine/reference/run/#/env-environment-variables) and [volumes](https://docs.docker.com/engine/reference/run/#volume-shared-filesystems).
The container is set up by setting [environment variables](https://docs.docker.com/engine/reference/run/#/env-environment-variables) and [volumes](https://docs.docker.com/engine/reference/run/#volume-shared-filesystems).
## Environment variables
* `RESTIC_REPOSITORY` - the location of the restic repository. Default `/mnt/restic`. For S3: `s3:https://s3.amazonaws.com/BUCKET_NAME`
* `RESTIC_PASSWORD` - the password for the restic repository. Will also be used for restic init during first start when the repository is not initialized.
* `RESTIC_TAG` - Optional. To tag the images created by the container.
* `NFS_TARGET` - Optional. If set the given NFS is mounted, i.e. `mount -o nolock -v ${NFS_TARGET} /mnt/restic`. `RESTIC_REPOSITORY` must remain it's default value!
* `BACKUP_CRON` - A cron expression to run the backup. Note: cron daemon uses UTC time zone. Default: `0 */6 * * *` aka every 6 hours.
* `RESTIC_FORGET_ARGS` - Optional. Only if specified `restic forget` is run with the given arguments after each backup. Example value: `-e "RESTIC_FORGET_ARGS=--prune --keep-last 10 --keep-hourly 24 --keep-daily 7 --keep-weekly 52 --keep-monthly 120 --keep-yearly 100"`
* `RESTIC_JOB_ARGS` - Optional. Allows to specify extra arguments to the back up job such as limiting bandwith with `--limit-upload` or excluding file masks with `--exclude`.
* `NFS_TARGET` - Optional. If set, the given NFS is mounted, i.e. `mount -o nolock -v ${NFS_TARGET} /mnt/restic`. `RESTIC_REPOSITORY` must remain its default value!
* `BACKUP_CRON` - A cron expression to run the backup. Note: The cron daemon uses UTC time zone. Default: `0 */6 * * *` aka every 6 hours.
* `CHECK_CRON` - Optional. A cron expression to run data integrity check (`restic check`). If left unset, data will not be checked. Note: The cron daemon uses UTC time zone. Example: `0 23 * * 3` to run 11PM every Tuesday.
* `RESTIC_FORGET_ARGS` - Optional. Only if specified, `restic forget` is run with the given arguments after each backup. Example value: `-e "RESTIC_FORGET_ARGS=--prune --keep-last 10 --keep-hourly 24 --keep-daily 7 --keep-weekly 52 --keep-monthly 120 --keep-yearly 100"`
* `RESTIC_INIT_ARGS` - Optional. Allows specifying extra arguments to `restic init` such as a password file with `--password-file`.
* `RESTIC_JOB_ARGS` - Optional. Allows specifying extra arguments to the backup job such as limiting bandwith with `--limit-upload` or excluding file masks with `--exclude`.
* `RESTIC_DATA_SUBSET` - Optional. You can pass a value to `--read-data-subset` when a repository check is run. If left unset, only the structure of the repository is verified. Note: `CHECK_CRON` must be set for check to be run automatically.
* `AWS_ACCESS_KEY_ID` - Optional. When using restic with AWS S3 storage.
* `AWS_SECRET_ACCESS_KEY` - Optional. When using restic with AWS S3 storage.
* `MAILX_ARGS` - Optional. If specified, the content of `/var/log/backup-last.log` is sent via mail after each backup using an *external SMTP*. To have maximum flexibility, you have to specify the mail/smtp parameters by your own. Have a look at the [mailx manpage](https://linux.die.net/man/1/mailx) for further information. Example value: `-e "MAILX_ARGS=-r 'from@example.de' -s 'Result of the last restic backup run' -S smtp='smtp.example.com:587' -S smtp-use-starttls -S smtp-auth=login -S smtp-auth-user='username' -S smtp-auth-password='password' 'to@example.com'"`.
* `TEAMS_WEBHOOK_URL` - Optional. If specified, the content of `/var/log/backup-last.log` and `/var/log/check-last.log` is sent to your Microsoft Teams channel after each backup and data integrity check.
* `MAILX_ARGS` - Optional. If specified, the content of `/var/log/backup-last.log` and `/var/log/check-last.log` is sent via mail after each backup and data integrity check using an *external SMTP*. To have maximum flexibility, you have to specify the mail/smtp parameters on your own. Have a look at the [mailx manpage](https://linux.die.net/man/1/mailx) for further information. Example value: `-e "MAILX_ARGS=-r 'from@example.de' -s 'Result of the last restic run' -S smtp='smtp.example.com:587' -S smtp-use-starttls -S smtp-auth=login -S smtp-auth-user='username' -S smtp-auth-password='password' 'to@example.com'"`.
* `OS_AUTH_URL` - Optional. When using restic with OpenStack Swift container.
* `OS_PROJECT_ID` - Optional. When using restic with OpenStack Swift container.
* `OS_PROJECT_NAME` - Optional. When using restic with OpenStack Swift container.
* `OS_USER_DOMAIN_NAME` - Optional. When using restic with OpenStack Swift container.
* `OS_PROJECT_DOMAIN_ID` - Optional. When using restic with OpenStack Swift container.
* `OS_USERNAME` - Optional. When using restic with OpenStack Swift container.
* `OS_PASSWORD` - Optional. When using restic with OpenStack Swift container.
* `OS_REGION_NAME` - Optional. When using restic with OpenStack Swift container.
* `OS_INTERFACE` - Optional. When using restic with OpenStack Swift container.
* `OS_IDENTITY_API_VERSION` - Optional. When using restic with OpenStack Swift container.
* `BACKUP_SOURCES` - Optional. Set the folder that will be backed up.
## Volumes
@@ -85,13 +150,13 @@ The container is setup by setting [environment variables](https://docs.docker.co
## Set the hostname
Since restic saves the hostname with each snapshot and the hostname of a docker container is derived from it's id you might want to customize this by setting the hostname of the container to another value.
Since restic saves the hostname with each snapshot and the hostname of a docker container is derived from its id, you might want to customize this by setting the hostname of the container to another value.
Set `--hostname` in the [network settings](https://docs.docker.com/engine/reference/run/#network-settings)
## Backup via SFTP
Since restic needs a **password less login** to the SFTP server make sure you can do `sftp user@host` from inside the container. If you can do so from your host system, the easiest way is to just mount your `.ssh` folder conaining the authorized cert into the container by specifying `-v ~/.ssh:/root/.ssh` as argument for `docker run`.
Since restic needs a **passwordless login** to the SFTP server, make sure you can do `sftp user@host` from inside the container. If you can do so from your host system, the easiest way is to just mount your `.ssh` folder containing the authorized cert into the container by specifying `-v ~/.ssh:/root/.ssh` as an argument for `docker run`.
Now you can simply specify the restic repository to be an [SFTP repository](https://restic.readthedocs.io/en/stable/Manual/#create-an-sftp-repository).
@@ -99,16 +164,63 @@ Now you can simply specify the restic repository to be an [SFTP repository](http
-e "RESTIC_REPOSITORY=sftp:user@host:/tmp/backup"
```
## Backup via OpenStack Swift
Restic can back up data to an OpenStack Swift container. Because Swift supports various authentication methods, credentials are passed through environment variables. In order to help integration with existing OpenStack installations, the naming convention of those variables follows the official Python Swift client.
Now you can simply specify the restic repository to be a [Swift repository](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#openstack-swift).
```
-e "RESTIC_REPOSITORY=swift:backup:/"
-e "RESTIC_PASSWORD=password"
-e "OS_AUTH_URL=https://auth.cloud.ovh.net/v3"
-e "OS_PROJECT_ID=xxxx"
-e "OS_PROJECT_NAME=xxxx"
-e "OS_USER_DOMAIN_NAME=Default"
-e "OS_PROJECT_DOMAIN_ID=default"
-e "OS_USERNAME=username"
-e "OS_PASSWORD=password"
-e "OS_REGION_NAME=SBG"
-e "OS_INTERFACE=public"
-e "OS_IDENTITY_API_VERSION=3"
```
## Backup via rclone
To use rclone as a backend for restic, simply add the rclone config file as a volume with `-v /absolute/path/to/rclone.conf:/root/.config/rclone/rclone.conf`.
# Versioning & Changelog
Note that for some backends (Among them Google Drive and Microsoft OneDrive), rclone writes data back to the `rclone.conf` file. In this case it needs to be writable by Docker.
If the container fails to write the new `rclone.conf` file with the error message `Failed to save config after 10 tries: Failed to move previous config to backup location`, add the entire `rclone` directory as a volume: `-v /absolute/path/to/rclone-dir:/root/.config/rclone`.
## Example docker-compose
This is an example `docker-compose.yml`. The container will back up two directories to an SFTP server and check data integrity once a week.
```
version: '3'
services:
restic:
image: ghcr.io/lobaro/restic-backup-docker:latest
hostname: nas # This will be visible in restic snapshot list
restart: always
privileged: true
volumes:
- /volume1/Backup:/data/Backup:ro # Backup /volume1/Backup from host
- /home/user:/data/home:ro # Backup /home/user from host
- ./post-backup.sh:/hooks/post-backup.sh:ro # Run script post-backup.sh after every backup
- ./post-check.sh:/hooks/post-check.sh:ro # Run script post-check.sh after every check
- ./ssh:/root/.ssh # SSH keys and config so we can login to "storageserver" without password
environment:
- RESTIC_REPOSITORY=sftp:storageserver:/storage/nas # Backup to server "storageserver"
- RESTIC_PASSWORD=passwordForRestic # Password restic uses for encryption
- BACKUP_CRON=0 22 * * 0 # Start backup every Sunday 22:00 UTC
- CHECK_CRON=0 22 * * 3 # Start check every Wednesday 22:00 UTC
- RESTIC_DATA_SUBSET=50G # Download 50G of data from "storageserver" every Wednesday 22:00 UTC and check the data integrity
- RESTIC_FORGET_ARGS=--prune --keep-last 12 # Only keep the last 12 snapshots
```
# Versioning
Starting from v1.3.0 versioning follows [Semantic versioning](http://semver.org/)
Build metadata is used to declare the Restic version.
**Example:** 1.3.0+0.9.5 (includes Restic 0.9.5)
For changelog see: https://github.com/lobaro/restic-backup-docker/releases

View File

@@ -2,6 +2,13 @@
lastLogfile="/var/log/backup-last.log"
lastMailLogfile="/var/log/mail-last.log"
lastMicrosoftTeamsLogfile="/var/log/microsoft-teams-last.log"
if [ -n "$BACKUP_SOURCES" ]; then
backupSources="$BACKUP_SOURCES"
else
backupSources="/data"
fi
copyErrorLog() {
cp ${lastLogfile} /var/log/backup-error-last.log
@@ -11,6 +18,13 @@ logLast() {
echo "$1" >> ${lastLogfile}
}
if [ -f "/hooks/pre-backup.sh" ]; then
echo "Starting pre-backup script ..."
/hooks/pre-backup.sh
else
echo "Pre-backup script not found ..."
fi
start=`date +%s`
rm -f ${lastLogfile} ${lastMailLogfile}
echo "Starting Backup at $(date +"%Y-%m-%d %H:%M:%S")"
@@ -23,25 +37,24 @@ logLast "RESTIC_REPOSITORY: ${RESTIC_REPOSITORY}"
logLast "AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}"
# Do not save full backup log to logfile but to backup-last.log
restic backup /data ${RESTIC_JOB_ARGS} --tag=${RESTIC_TAG?"Missing environment variable RESTIC_TAG"} >> ${lastLogfile} 2>&1
rc=$?
restic backup ${backupSources} ${RESTIC_JOB_ARGS} --tag=${RESTIC_TAG?"Missing environment variable RESTIC_TAG"} >> ${lastLogfile} 2>&1
backupRC=$?
logLast "Finished backup at $(date)"
if [[ $rc == 0 ]]; then
echo "Backup Successfull"
if [[ $backupRC == 0 ]]; then
echo "Backup Successful"
else
echo "Backup Failed with Status ${rc}"
echo "Backup Failed with Status ${backupRC}"
restic unlock
copyErrorLog
kill 1
fi
if [ -n "${RESTIC_FORGET_ARGS}" ]; then
if [[ $backupRC == 0 ]] && [ -n "${RESTIC_FORGET_ARGS}" ]; then
echo "Forget about old snapshots based on RESTIC_FORGET_ARGS = ${RESTIC_FORGET_ARGS}"
restic forget ${RESTIC_FORGET_ARGS} >> ${lastLogfile} 2>&1
rc=$?
logLast "Finished forget at $(date)"
if [[ $rc == 0 ]]; then
echo "Forget Successfull"
echo "Forget Successful"
else
echo "Forget Failed with Status ${rc}"
restic unlock
@@ -52,11 +65,30 @@ fi
end=`date +%s`
echo "Finished Backup at $(date +"%Y-%m-%d %H:%M:%S") after $((end-start)) seconds"
if [ -n "${TEAMS_WEBHOOK_URL}" ]; then
teamsTitle="Restic Last Backup Log"
teamsMessage=$( cat ${lastLogfile} | sed 's/"/\"/g' | sed "s/'/\'/g" | sed ':a;N;$!ba;s/\n/\n\n/g' )
teamsReqBody="{\"title\": \"${teamsTitle}\", \"text\": \"${teamsMessage}\" }"
sh -c "curl -H 'Content-Type: application/json' -d '${teamsReqBody}' '${TEAMS_WEBHOOK_URL}' > ${lastMicrosoftTeamsLogfile} 2>&1"
if [ $? == 0 ]; then
echo "Microsoft Teams notification successfully sent."
else
echo "Sending Microsoft Teams notification FAILED. Check ${lastMicrosoftTeamsLogfile} for further information."
fi
fi
if [ -n "${MAILX_ARGS}" ]; then
sh -c "mailx -v -S sendwait ${MAILX_ARGS} < ${lastLogfile} > ${lastMailLogfile} 2>&1"
sh -c "mail -v -S sendwait ${MAILX_ARGS} < ${lastLogfile} > ${lastMailLogfile} 2>&1"
if [ $? == 0 ]; then
echo "Mail notification successfully sent."
else
echo "Sending mail notification FAILED. Check ${lastMailLogfile} for further information."
fi
fi
if [ -f "/hooks/post-backup.sh" ]; then
echo "Starting post-backup script ..."
/hooks/post-backup.sh $backupRC
else
echo "Post-backup script not found ..."
fi

76
check.sh Executable file
View File

@@ -0,0 +1,76 @@
#!/bin/sh
lastLogfile="/var/log/check-last.log"
lastMailLogfile="/var/log/check-mail-last.log"
lastMicrosoftTeamsLogfile="/var/log/check-microsoft-teams-last.log"
copyErrorLog() {
cp ${lastLogfile} /var/log/check-error-last.log
}
logLast() {
echo "$1" >> ${lastLogfile}
}
if [ -f "/hooks/pre-check.sh" ]; then
echo "Starting pre-check script ..."
/hooks/pre-check.sh
else
echo "Pre-check script not found ..."
fi
start=`date +%s`
rm -f ${lastLogfile} ${lastMailLogfile}
echo "Starting Check at $(date +"%Y-%m-%d %H:%M:%S")"
echo "Starting Check at $(date)" >> ${lastLogfile}
logLast "CHECK_CRON: ${CHECK_CRON}"
logLast "RESTIC_DATA_SUBSET: ${RESTIC_DATA_SUBSET}"
logLast "RESTIC_REPOSITORY: ${RESTIC_REPOSITORY}"
logLast "AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}"
# Do not save full check log to logfile but to check-last.log
if [ -n "${RESTIC_DATA_SUBSET}" ]; then
restic check --read-data-subset=${RESTIC_DATA_SUBSET} >> ${lastLogfile} 2>&1
else
restic check >> ${lastLogfile} 2>&1
fi
checkRC=$?
logLast "Finished check at $(date)"
if [[ $checkRC == 0 ]]; then
echo "Check Successful"
else
echo "Check Failed with Status ${checkRC}"
restic unlock
copyErrorLog
fi
end=`date +%s`
echo "Finished Check at $(date +"%Y-%m-%d %H:%M:%S") after $((end-start)) seconds"
if [ -n "${TEAMS_WEBHOOK_URL}" ]; then
teamsTitle="Restic Last Check Log"
teamsMessage=$( cat ${lastLogfile} | sed 's/"/\"/g' | sed "s/'/\'/g" | sed ':a;N;$!ba;s/\n/\n\n/g' )
teamsReqBody="{\"title\": \"${teamsTitle}\", \"text\": \"${teamsMessage}\" }"
sh -c "curl -H 'Content-Type: application/json' -d '${teamsReqBody}' '${TEAMS_WEBHOOK_URL}' > ${lastMicrosoftTeamsLogfile} 2>&1"
if [ $? == 0 ]; then
echo "Microsoft Teams notification successfully sent."
else
echo "Sending Microsoft Teams notification FAILED. Check ${lastMicrosoftTeamsLogfile} for further information."
fi
fi
if [ -n "${MAILX_ARGS}" ]; then
sh -c "mail -v -S sendwait ${MAILX_ARGS} < ${lastLogfile} > ${lastMailLogfile} 2>&1"
if [ $? == 0 ]; then
echo "Mail notification successfully sent."
else
echo "Sending mail notification FAILED. Check ${lastMailLogfile} for further information."
fi
fi
if [ -f "/hooks/post-check.sh" ]; then
echo "Starting post-check script ..."
/hooks/post-check.sh $checkRC
else
echo "Post-check script not found ..."
fi

View File

@@ -1,25 +1,19 @@
#!bin/sh
#!/bin/sh
echo "Starting container ..."
RESTIC_CMD=restic
if [ -n "${ROOT_CERT}" ]; then
RESTIC_CMD="${RESTIC_CMD} --cert ${ROOT_CERT}"
fi
if [ -n "${NFS_TARGET}" ]; then
echo "Mounting NFS based on NFS_TARGET: ${NFS_TARGET}"
mount -o nolock -v ${NFS_TARGET} /mnt/restic
fi
restic snapshots &>/dev/null
restic snapshots ${RESTIC_INIT_ARGS} &>/dev/null
status=$?
echo "Check Repo status $status"
if [ $status != 0 ]; then
echo "Restic repository '${RESTIC_REPOSITORY}' does not exists. Running restic init."
restic init
restic init ${RESTIC_INIT_ARGS}
init_status=$?
echo "Repo init status $init_status"
@@ -33,7 +27,13 @@ fi
echo "Setup backup cron job with cron expression BACKUP_CRON: ${BACKUP_CRON}"
echo "${BACKUP_CRON} /bin/backup >> /var/log/cron.log 2>&1" > /var/spool/cron/crontabs/root
echo "${BACKUP_CRON} /usr/bin/flock -n /var/run/backup.lock /bin/backup >> /var/log/cron.log 2>&1" > /var/spool/cron/crontabs/root
# If CHECK_CRON is set we will enable automatic backup checking
if [ -n "${CHECK_CRON}" ]; then
echo "Setup check cron job with cron expression CHECK_CRON: ${CHECK_CRON}"
echo "${CHECK_CRON} /usr/bin/flock -n /var/run/backup.lock /bin/check >> /var/log/cron.log 2>&1" >> /var/spool/cron/crontabs/root
fi
# Make sure the file exists before we start tail
touch /var/log/cron.log