Open Moltey opened 2 years ago
This might be a duplicate of https://github.com/nextcloud/docker/issues/359
I have a similar issue and I have tried different images, removed and reinstalled multiple times and cron doesn't run as it's supposed to. Here are the details of my setup (please excused me as I'm new to self hosting but have spent huge number of hours trying to solve this issue)
OS - Windows Distro - WSL2 kernel and Ubuntu Nextcloud - Latest version with mariadb and redis Issue - Selecting Cron in setting doesn't do anything Solutions tried -
I'm finally reaching out here to see if anyone could help
Thanks,
@J0WI: #359 fixes the UID/GID issue with apache (in the "app" container), but the "cron" container that runs the cron jobs, the user is hard coded as www-data
:
So what ends up happening is, apache
runs as a non-root user as per the UID:GID, but cron
runs as www-data
and fails repeatedly with permission errors.
@Moltey: I have implemented another solution:
I override the cron.sh
to change the www-data
hardcoding:
#!/bin/sh
set -eu
adduser --disabled-password --gecos "" --uid "$APACHE_UID" user
mv /var/spool/cron/crontabs/www-data /var/spool/cron/crontabs/user
exec busybox crond -f -l 0 -L /dev/stdout
then I mount it (read-only) within my "app" container, and pass the appropriate APACHE_UID
to my "cron" container:
services:
...
app:
...
volumes:
- ./cron.sh:/cron.sh:ro
...
cron:
...
volumes_from:
- app:rw
environment:
APACHE_UID: 1008
That's the key idea, but I implemented a couple of other hacks to be able to edit the crontab file directly from the host -- it's reloaded automatically in the "cron" container.
@J0WI: I think the app (not cron) entrypoint should create a new user with the UID:GID and add move the cron job (from www-data
) to that user. Then the cron container would work as expected without any additional hacks
I tried to move a simple echo "*/5 * * * * php -f /var/www/html/cron.php" | busybox crontab -
script to the cron.sh
entrypoint itself, but unfortunately busybox does not allow to run crontab
as non-root: https://git.busybox.net/busybox/tree/miscutils/crontab.c?h=1_35_stable#n110
Yes, busybox requires crond
to run as root.
The current entrypoint script does run it as root. The problem is just that the crontab file (at /var/spool/cron/crontabs
) is under the wrong user (www-data
). When the nextcloud container runs with a non-root UID (using --user
), the crontab file should actually be renamed to that user's name in place of www-data
, to avoid permission issues.
As you have noticed, it's currently not possible to run the cron container as a non-root user, although nextcloud container can run as a non-root user. Currently, even when the cron container is run as root, the cron jobs fail with permission errors.
As for security, the cron container only runs the crond
process as root. The actual cron tasks (php
) are run with the respective user's UID, which is www-data
currently.
At this point, I think it's easier to just run your own docker run -v my_nextcloud:/var/www/html --user my_user nextcloud:fpm-alpine sh -c 'while true; do php -f /var/www/html/cron.php; sleep 5m; done'
. Or, as already mentioned above, just use a timer on your host that runs docker exec ...
.
There is no trivial way to run the cron script as non-root and detect whatever user is used in the other container.
The bug report is about making cron.php
be executed by the right UID, not crond
.
I think you are mixing up the cron daemon with cron scripts (or crontabs).
There is no trivial way to run the cron script as non-root
False. They (var/spool/cron/crontabs/www-data
) already do, just as the wrong user.
If you run the cron container as root, it can run crond
and manage crontabs
for all users. However, the cron container has no knowledge of the user that runs in the other PHP container. You have to specify the user. The above example executes cron.php
as my_user
.
At this point, I think it's easier to just run your own
docker run -v my_nextcloud:/var/www/html --user my_user nextcloud:fpm-alpine sh -c 'while true; do php -f /var/www/html/cron.php; sleep 5m; done'
. Or, as already mentioned above, just use a timer on your host that runsdocker exec ...
.There is no trivial way to run the cron script as non-root and detect whatever user is used in the other container.
Can we please agree that this is a very nasty workaround? 😄
I ended up calling cron.php via the crontab of the host machine which is not satisfying, neither.
IMHO, this is a design issue you might want to consider in one of the next major releases.
This is somewhat covered in https://github.com/nextcloud/docker/pull/1901
Running crond
(the daemon) as non-root and running the cron.php
file (the cron job) as non-root are two different things.
I attempted to use the nextcloud cron container, but it didn't work as described in this issue. The container was configured to run as a non-root user using the user option with a specific UID and GID, but the cronjob failed. I believe it is not worth using it as it needs to run as root. Running containers as root is generally not recommended due to security reasons.
I decided to set up a cronjob on my LXC host. I added a cronjob for a non-root user who is also not part of the sudo group, to run the cron script inside the nextcloud container using docker exec.
*/5 * * * * docker exec -u 1000:1000 nextcloud_container php ./cron.php
To check that the cronjob ran successfully, I searched the syslog for the cron script using this command:
grep -a "cron.php" /var/log/syslog
This solution will work for me until Nextcloud decides to address the issue.
I ended up building a custom image with supercronic, couldn't get crond to work as non-root either.
ARG NEXTCLOUD_VERSION
FROM nextcloud:${NEXTCLOUD_VERSION}-apache
ENV SUPERCRONIC_VERSION="v0.2.25"
ENV SUPERCRONIC_PACKAGE="supercronic-linux-amd64"
ENV SUPERCRONIC_SHA1SUM="642f4f5a2b67f3400b5ea71ff24f18c0a7d77d49"
ENV SUPERCRONIC_URL="https://github.com/aptible/supercronic/releases/download/$SUPERCRONIC_VERSION/$SUPERCRONIC_PACKAGE"
RUN curl --fail --silent --show-error --location --output /supercronic "${SUPERCRONIC_URL}" && \
echo "${SUPERCRONIC_SHA1SUM} /supercronic" | sha1sum -c - && \
chmod +x /supercronic
RUN echo "${CRON:-"*/10 * * * *"} php -f /var/www/html/cron.php" > /crontab
ENTRYPOINT ["/supercronic", "/crontab"]
To summarize this, it is currently impossible to run the docker container as a different user?
Expectation:
Cron should execute cron.php with the UID the container is started with (in case a UID is provided).
Status Quo:
Cron.php is executed with www-data, which is UID 33 / 34 (depends on distribution) in the container.
Result: Cron fails to execute cron.php withe the appropriate user.
Details:
Due to security reasons, I am running all my containers rootless and with seperated user accounts. I think rootless non-root execution will be the future of containerization anyways.
I utilize user 1008 for nextcloud.
Nextcloud recognizes this fact and reminds the user that cron is to be executed by the same user in the web interface:
Therefore, I want to start the cron container with the same UID as the app:
The containers works, file access is fine for UID 1008 - however, the execution of cron.php fails:
Nevermind, as "www-data" would be UID 33 and not the appropriate user anyways (should be 1008, as announced by nextcloud). File access for UID 1008 is working fine though.
If I change the UID of www-data in passwd to the designated UID 1008 and passthrough the passwd to the container, the execution fails:
Passwd line:
Additional passthrough of passwd for the start of podman:
Output of the cron-log:
There is a solution, but it is crap: The execution of cron-php via host works fine:
Desperate users could execute this line via crond of the host but hopefully you agree that this is not what we want to see ;)