diff --git a/Dockerfile b/Dockerfile index 3cf6f0b..7e7ec8e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,8 @@ FROM alpine:3.19 WORKDIR /root -RUN apk add --no-cache ca-certificates +RUN apk add --no-cache ca-certificates && \ + chmod a+rw /var/lock COPY --from=builder /app/cmd/backup/backup /usr/bin/backup diff --git a/docs/how-tos/replace-deprecated-backup-from-snapshot.md b/docs/how-tos/replace-deprecated-backup-from-snapshot.md index 036cf40..17ff161 100644 --- a/docs/how-tos/replace-deprecated-backup-from-snapshot.md +++ b/docs/how-tos/replace-deprecated-backup-from-snapshot.md @@ -2,7 +2,7 @@ title: Replace deprecated BACKUP_FROM_SNAPSHOT usage layout: default parent: How Tos -nav_order: 16 +nav_order: 17 --- # Replace deprecated `BACKUP_FROM_SNAPSHOT` usage diff --git a/docs/how-tos/replace-deprecated-backup-stop-container-label.md b/docs/how-tos/replace-deprecated-backup-stop-container-label.md index f8841cb..adaa463 100644 --- a/docs/how-tos/replace-deprecated-backup-stop-container-label.md +++ b/docs/how-tos/replace-deprecated-backup-stop-container-label.md @@ -2,7 +2,7 @@ title: Replace deprecated BACKUP_STOP_CONTAINER_LABEL setting layout: default parent: How Tos -nav_order: 19 +nav_order: 20 --- # Replace deprecated `BACKUP_STOP_CONTAINER_LABEL` setting diff --git a/docs/how-tos/replace-deprecated-exec-labels.md b/docs/how-tos/replace-deprecated-exec-labels.md index 7f7841a..050acd3 100644 --- a/docs/how-tos/replace-deprecated-exec-labels.md +++ b/docs/how-tos/replace-deprecated-exec-labels.md @@ -2,7 +2,7 @@ title: Replace deprecated exec-pre and exec-post labels layout: default parent: How Tos -nav_order: 17 +nav_order: 18 --- # Replace deprecated `exec-pre` and `exec-post` labels diff --git a/docs/how-tos/update-deprecated-email-config.md b/docs/how-tos/update-deprecated-email-config.md index af1b2b5..132524d 100644 --- a/docs/how-tos/update-deprecated-email-config.md +++ b/docs/how-tos/update-deprecated-email-config.md @@ -2,7 +2,7 @@ title: Update deprecated email configuration layout: default parent: How Tos -nav_order: 18 +nav_order: 19 --- # Update deprecated email configuration diff --git a/docs/how-tos/use-as-non-root.md b/docs/how-tos/use-as-non-root.md new file mode 100644 index 0000000..1d2cb38 --- /dev/null +++ b/docs/how-tos/use-as-non-root.md @@ -0,0 +1,36 @@ +--- +title: Use the image as a non-root user +layout: default +parent: How Tos +nav_order: 16 +--- + +# Use the image as a non-root user + +{: .important } +Running as a non-root user limits interaction with the Docker Daemon. +If you want to stop and restart containers and services during backup, and the host's Docker daemon is running as root, you will also need to run this tool as root. + +By default, this image executes backups using the `root` user. +In case you prefer to use a different user, you can use Docker's [`user`](https://docs.docker.com/engine/reference/run/#user) option, passing the user and group id: + +```console +docker run --rm \ + -v data:/backup/data \ + --env AWS_ACCESS_KEY_ID="" \ + --env AWS_SECRET_ACCESS_KEY="" \ + --env AWS_S3_BUCKET_NAME="" \ + --entrypoint backup \ + --user 1000:1000 \ + offen/docker-volume-backup:v2 +``` + +or in a compose file: + +```yml +services: + backup: + image: offen/docker-volume-backup:v2 + user: 1000:1000 + # further configuration omitted ... +``` diff --git a/docs/recipes/index.md b/docs/recipes/index.md index 5a2220c..3b4045e 100644 --- a/docs/recipes/index.md +++ b/docs/recipes/index.md @@ -371,3 +371,24 @@ volumes: data_1: data_2: ``` + +## Running as a non-root user + +```yml +version: '3' + +services: + # ... define other services using the `data` volume here + backup: + image: offen/docker-volume-backup:v2 + user: 1000:1000 + environment: + AWS_S3_BUCKET_NAME: backup-bucket + AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE + AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + volumes: + - data:/backup/my-app-backup:ro + +volumes: + data: +``` diff --git a/test/nonroot/01conf.env b/test/nonroot/01conf.env new file mode 100644 index 0000000..07fe3df --- /dev/null +++ b/test/nonroot/01conf.env @@ -0,0 +1,7 @@ +AWS_ACCESS_KEY_ID="test" +AWS_SECRET_ACCESS_KEY="GMusLtUmILge2by+z890kQ" +AWS_ENDPOINT="minio:9000" +AWS_ENDPOINT_PROTO="http" +AWS_S3_BUCKET_NAME="backup" +BACKUP_CRON_EXPRESSION="0 0 5 31 2 ?" +BACKUP_FILENAME="test.tar.gz" diff --git a/test/nonroot/docker-compose.yml b/test/nonroot/docker-compose.yml new file mode 100644 index 0000000..f3ee99a --- /dev/null +++ b/test/nonroot/docker-compose.yml @@ -0,0 +1,33 @@ +version: '3' + +services: + minio: + image: minio/minio:RELEASE.2020-08-04T23-10-51Z + environment: + MINIO_ROOT_USER: test + MINIO_ROOT_PASSWORD: test + MINIO_ACCESS_KEY: test + MINIO_SECRET_KEY: GMusLtUmILge2by+z890kQ + entrypoint: /bin/ash -c 'mkdir -p /data/backup && minio server /data' + volumes: + - ${LOCAL_DIR:-local}:/data + + backup: + image: offen/docker-volume-backup:${TEST_VERSION:-canary} + user: 1000:1000 + depends_on: + - minio + restart: always + volumes: + - app_data:/backup/app_data:ro + - ./01conf.env:/etc/dockervolumebackup/conf.d/01conf.env + + offen: + image: offen/offen:latest + labels: + - docker-volume-backup.stop-during-backup=true + volumes: + - app_data:/var/opt/offen + +volumes: + app_data: diff --git a/test/nonroot/run.sh b/test/nonroot/run.sh new file mode 100755 index 0000000..79fbb94 --- /dev/null +++ b/test/nonroot/run.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +set -e + +cd "$(dirname "$0")" +. ../util.sh +current_test=$(basename $(pwd)) + +export LOCAL_DIR=$(mktemp -d) + +docker compose up -d --quiet-pull +sleep 5 + +docker compose logs backup + +# conf.d is used to confirm /etc files are also accessible for non-root users +docker compose exec backup /bin/sh -c 'set -a; source /etc/dockervolumebackup/conf.d/01conf.env; set +a && backup' + +sleep 5 + +expect_running_containers "3" + +if [ ! -f "$LOCAL_DIR/backup/test.tar.gz" ]; then + fail "Could not find archive." +fi +pass "Archive was created." + diff --git a/test/util.sh b/test/util.sh index 6de8606..ee7aedf 100644 --- a/test/util.sh +++ b/test/util.sh @@ -22,7 +22,7 @@ skip () { expect_running_containers () { if [ "$(docker ps -q | wc -l)" != "$1" ]; then - fail "Expected $1 containers to be running, instead seen: "$(docker ps -a | wc -l)"" + fail "Expected $1 containers to be running, instead seen: "$(docker ps -q | wc -l)"" fi pass "$1 containers running." }