creativeprojects / resticprofile

Configuration profiles manager and scheduler for restic backup
https://creativeprojects.github.io/resticprofile/
GNU General Public License v3.0
603 stars 29 forks source link

Docker schedule as non root user #321

Open mglochsen opened 5 months ago

mglochsen commented 5 months ago

I tried this very good contribution of how to schedule jobs with Docker.

Unfortunately crond cannot be used when I'm using a non root user for the docker container, as it has no permissions to execute it.

Can this be solved withing the resticprofile docker image? I only see the solution to build my own image and modify the user permissions but it would be nice if I could use the image without modifying it.

creativeprojects commented 4 months ago

Hey!

I'm not sure I understand your issue, can you explain how you're trying to do your backups?

mglochsen commented 4 months ago

Sure, I try to explain what I'm about do to:

First of all I'm working with a Synology NAS and it should backup its own data to a restic repo. Therefore I want to use a Docker container running on the NAS.

Following the best practices of Docker this container should not run as root and I created an user for backup purposes. Then I'm using the following "Stack" with Portainer (this is similar to docker compose):

version: "3"
services:
  scheduled-backup:
    image: creativeprojects/resticprofile
    container_name: resticprofile_schedule
    hostname: resticprofile_schedule
    user: "${UID}:${GID}"
    entrypoint: '/bin/sh'
    command:
      - '-c'
      - 'resticprofile schedule --all && crond -f'
    volumes:
      - '${RESTICPROFILE_CONFIG_DIR}/profiles.toml:/etc/resticprofile/profiles.toml:ro'
      - '${RESTICPROFILE_CONFIG_DIR}/key:/etc/resticprofile/key:ro'
      - ${RESTIC_REPO_DIR}:/restic_repo
      - ${RESTIC_LOG_DIR}:/restic_logs
      - /xyz/abc:/source
    environment:
      - TZ=Etc/UTC

Some snippets from the profiles.toml:

[global]
  scheduler = "crond"

[local]
  repository = "local:/restic_repo"
  password-file = "key"
  initialize = true

[local-backup]
  inherit = "local"

  [local-backup.backup]
    schedule-permission = "system"
    schedule-lock-wait = "10m"

[local-test]
  inherit = "local-backup"

  [local-test.backup]
    source = [ "/source" ]
    schedule = [ "..." ]

This leads to the following logs in the container:

using configuration file: /etc/resticprofile/profiles.toml
error creating job local-test/backup: user is not allowed to create a system job: please restart resticprofile as root (with sudo)

As far as I understand, the user I provide is not allowed to run crond. Therefore I asked if it is possible to modify your Dockerfile to give the container user access to crond.

Disclaimer: Being no docker expert, I might miss another approach to solve the issue.

mglochsen commented 4 months ago

Update:

I also tried to set schedule-permission to "user" in the profiles.toml. The result is another error:

using configuration file: /etc/resticprofile/profiles.toml

Analyzing backup schedule 1/1
=================================
...

error creating job local-test/backup: exit status 1: crontab: must be suid to work properly
creativeprojects commented 4 months ago

Thank you for your detailed description.

The problem is because I'm using alpine Linux as a base image.

I'm going to try if it works with adding the package busybox-suid. With this package, crontab would be able to install a user cron file.

Then I need to test if resticprofile/restic do work fine with a non-root user.

If it fails I guess I can also provide a Debian base image.

mglochsen commented 4 months ago

Thanks a lot, I really appreciate your willingness to change the image. I also came across the busybox-suid suggestion, that might work. Let me know if you need further information or someone to test the image whenever you're ready.

creativeprojects commented 3 months ago

So, in the end I didn't like the idea of having suid on all the busybox binaries.

I prepared a contribution based on supercronic instead. I'm now thinking of proposing two docker images, one running as root (not to break anything) and another one running as non-root.

See here: https://github.com/creativeprojects/resticprofile/pull/348