Docker: Why use the webcron and not a real cron task

Created on 28 Jul 2017  ·  27Comments  ·  Source: nextcloud/docker

Our owncloud has little access and the cron tasks are not run frequently.
Adding cron for this taks is an option?

question

Most helpful comment

I highly vote in favor of adding a cron utility in the Docker image for one reason: simplicity.

For example, one can run the Docker image "out of the box", and it works flawlessly...but adding the application News is useless because there is no cron. Forcing people to tweak the image and add another specific container just for cron is cumbersome.

All 27 comments

You could run the image on OpenShift which adds a Cron job to the image: https://github.com/tobru/nextcloud-openshift

We discussed that a while ago. The reason we didn't add the cron process into this image is that it would go against the docker strategy _one process per container_. There are the possibilities to get around this:

  1. Run Cron in a different container, for example start a second nextcloud container with the same volumes and let it run cron or a script instead of the webserver (example will be added soon, see #123 )
  2. Build your own derived Image and ignore the _one process per container_ strategy. You can use tools like supervisord to run multiple processes inside one container. (example in the examples folder )

There is another possibility, which is in my eyes not a good solution, so I wouldn't recommend is:

  1. Use the cron job on your docker host and let it execute the task via docker exec ....

@SnowMB I understand the docker strategy. What I want to prevent is that I have to build and update the image. Thats why I asked if there is a known and not custom build way of doing it with the current container.
Perhaps an option is to add a ENV to use the entrypoint script to be a cron service or a webserver.
Like this we keep the 1 process but we can reuse the container without building customs containers and maintaining them.

Perhaps an option is to add a ENV to use the entrypoint script to be a cron service or a webserver.
Like this we keep the 1 process but we can reuse the container without building customs containers and maintaining them.

That would probably be the simplest approach for people not familiar with Docker.

Run Cron in a different container, for example start a second nextcloud container with the same volumes and let it run cron or a script instead of the webserver (example will be added soon, see #123 )

This is what I'm using right now. However, since I'm using Rancher the container gets started every 15 minutes by Ranchers crontab service. For anyone looking, here's the cron sidekick I added:

cron:
    image: nextcloud:fpm
    entrypoint:
        - php
        - /var/www/html/cron.php
    links:
        - redis:redis
        - db:db
    volumes_from:
        - nextcloud
    user: www-data
    labels:
        io.rancher.container.start_once: 'true'
        io.rancher.container.pull_image: always
        cron.schedule: '@every 15m'

cron.schedule: '@every 15m' causes the container to be started automatically every 15 minutes.
io.rancher.container.start_once: 'true' stops the container from restarting after it ran the script.

This works perfectly so far and seems like a clean solution. A lot better than rebuilding the image just for cron and/or running supervisord.

https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/
"
You may have heard that there should be “one process per container”. While this mantra has good intentions, it is not necessarily true that there should be only one operating system process per container. In addition to the fact that containers can now be spawned with an init process, some programs might spawn additional processes of their own accord. For instance, Celery can spawn multiple worker processes, or Apache might create a process per request. While “one process per container” is frequently a good rule of thumb, it is not a hard and fast rule. Use your best judgment to keep containers as clean and modular as possible.
"

It seems the docker philosophy accomodates the execution of cron jobs alongside the mais process, as, in my opinion, this improves modularization - having one container instead of having two containers tighlty coupled.

I highly vote in favor of adding a cron utility in the Docker image for one reason: simplicity.

For example, one can run the Docker image "out of the box", and it works flawlessly...but adding the application News is useless because there is no cron. Forcing people to tweak the image and add another specific container just for cron is cumbersome.

:+1: for adding cron for simplicity sake.

In the mean time examples includes cron ;)

ping @tilosp and @pierreozoux.

I agree with that. But in my case it is just personal use with a few users.

I see that getting started with docker and this image causes a lot of confusion. Maybe we could go the other way round and offer a more complete base image as default and a stripped down / configurable option as option?

@SnowMB
Take a look at https://github.com/docker-library/docs/pull/1034
The current plan is to add cron and another startup script to the image (https://github.com/nextcloud/docker/pull/220).
You would still have two container one for apache/fpm and one for cron. For the cron container we would just change the the entrypoint to cron.sh in the docker-compose.yml

The problem:

  • small users want a one liner to get started (and just one container)
  • big users wants something nice and scalable
  • Docker is strict about official images - one container - one process

A possible solution:

  • use the dockerhub nextcloud namespace and deploy there an all-in-one image for small users.
  • Make sure that the Nextcloud documentation is really clear about the diff between the all-in-one and the official docker image and cross ref both of them
  • but then, the all in one, should basically do https and the coffee :) Get prepared!
  • actually then we can get rid of the .example folder (I don't like the direction this folder is taking ;) ) and move it to it's own repo, that become the all-in-one image
  • we'll have:

    • docker-official-image github repo -> nextcloud docker name

    • docker-all-in-one github repo -> nextcloud/all-in-one docker name (would be good if it uses the docker official image as a base)

What do you think?

Sounds good.

BTW, I did a Dockerfile with cron and smb client: https://github.com/romu70/self-hosting-containers/tree/master/nextcloud

It's based on the NC official image. 12.0.4, I'll try to update it soon. Enjoy!

@pierreozoux do we own the nextcloud namespace?

I don't but I guess @nextcloud does!
https://hub.docker.com/r/nextcloud/
(If not, would be easy to get it back)

@pierreozoux
I like the idea of the all in one image.
One problem is is that docker hub can only build amd64 images. This means that the all in one image will not support multiarch.

And we also need to decide which php dependencies to include in the all in one image.

I would like to point to @Wonderfall wonderfall/docker-nextcloud.

He is actively maintaining an all in one image since before the official image was created.

So I've been googling the heck out of this Cron issue, and I've found lots of discussions and lots of different examples, but not a single, easy answer to this problem. At the moment I have 2 containers, one for the DB and one for Nextcloud (Apache version). I use a 3rd, unrelated container as an Nginx proxy since I use that proxy for other services, I didn't want to tightly couple it to the Nextcloud container.

I am getting that warning in the admin panel about cron jobs not running:

Last job execution ran 2 days ago. Something seems wrong

I did see the example where someone is using a separate container for cron. I think this is overkill. Especially since all it does is rebuild and re-run a second instance of the nextcloud container. The overhead of this is just unacceptably high.

I'm not even asking for a turn-key solution here. I'm ok with some decomposition between containers, but AFAIC, the cron job is an implementation detail of Nextcloud; required as part of its normal operation. Why do I have to struggle for hours trying to fix this issue when arguably it should be part of the container itself?

Part of this is rant, but I'd really like to know if 11 months later this has been solved and I just haven't had much luck finding a solution. I see that a cron.sh script is in the v14 container, next to the entrypoint script, but when I do a ps aux inside the Nextcloud container, I only see apache2 processes running, no cron daemon.

How can I fix this warning?

How can I fix this warning?

You can call the cron.php script by using dockrer exec on the host, which did the job for me:

#Nextcloud Cron */30 * * * * root /usr/bin/docker exec nextcloud su - www-data -s /bin/bash -c 'php -f /var/www/html/cron.php' > /dev/null 2>&1
You should change from the setting from webcron to cron. Check https://crontab.guru in case cron syntax is not known to you.

I really don't want to modify the host for this. Is there no container-centric solution?

In the github repo there is an example for how to run cron with supervisord. It works fine like that, but you have to build your own image. I know about the one process per container discussion, but how do you define a process? In my point of view mysql and the webserver are 2 processes, and you need to run a cron task as part of the webserver-process. Now it is triggered by a page-call but I do not see any objections to use supervisord or crond as a default. The upstream Nextcloud cannot do that, but the Docker branch has its own complete webserver, so why not. Are we not too strict here? The official Gitlab image has a database, redis and a webserver in one image, I think that is too much (and 4 Gb in size). But adding a cron task to a webserver process should be possible (and very welcome).

I made a Docker image which include smbclient and crontab.
It's here: https://github.com/romu70/self-hosting-containers/tree/master/nextcloud.

I found out that, in fact, cron daemon is already in the Nextcloud docker container. There's even a crontab script installed for it. But oddly, for some reason, the cron daemon is not started from entrypoint.sh. I think it was originally added so a secondary container would start the cron.sh as an entrypoint script itself.

I created a PR (#535) to launch cron daemon in background mode in the Nextcloud container as part of its own entrypoint script.

I think it was originally added so a secondary container would start the cron.sh as an entrypoint script itself.

That's exactly how it's supposed to work, but that doesn't require any changes on the host, just a second container that uses cron.sh as entrypoint:

nextcloud:
    image: nextcloud:13-fpm
    volumes:
    - ...
cron:
    image: nextcloud:13-fpm
    entrypoint:
    - /cron.sh
    volumes_from:
    - nextcloud

Yeah but you have to start 2 instances of the nextcloud container, which is not acceptable IMHO. The overhead is just too large for a simple cron job. My PR makes the cron job run in the nextcloud container, which is the more appropriate solution here. This is a simple matter and shouldn't be over complicated based on principles. I like pragmatic solutions. This makes the solution transparent. No additional configuration and learning curve is required. Users already using the container will now have a working cronjob in the background.

Yeah but you have to start 2 instances of the nextcloud container, which is not acceptable IMHO. The overhead is just too large for a simple cron job.

There is none to minimal overhead, there is nothing running inside of the container besides php-fpm in the main container and a crond instance in the cron container. Which is the same as if you run it in the same container.

Assuming you use php-fpm of course, but it probably is similar with the Apache container.

My PR makes the cron job run in the nextcloud container, which is the more appropriate solution here.

The "appropriate" solution is a matter of taste, so there's no use in hardcoding the cronjob in the entrypoint. Not everybody is going to use that.

There is none to minimal overhead

There's overhead in configuration. Overhead in maintainability of the instance and execution of the docker compose script. Memory and CPU overhead inherent to docker containers for something unnecessary. Overhead spent learning unnecessary implementation details. Overhead of arguing with people about simplifying.

Why do people abuse docker so casually? These aren't simple threads you create to do things.

The "appropriate" solution is a matter of taste

You objectively can't deny the additional configuration required, which makes things more complex. Look, it's not my job to convince you and I'm not interested in doing so. If you don't like my change that's fine. And honestly it wouldn't negatively affect you. If I had to choose between less complex and error-prone configuration and someone's personal opinion on what single process per container means, I'm going to choose the former every time.

i hope we can rediscuss this topic

yes one container one process but the arguments in this thread are all valid, but where is the problem to just add/enable cron?
not anyone uses docker-compose .. me for example uses unraid and i must create a second container .. adding all the volumes etc to just run a cron job? this is as mentioned above much overhead in configuration and potentenal errors

we have a discussion about one container one process as the ONLY argument against this, in a world where massive containers are used in stable produktion that includes more than 3 and more processes, nobody cares about this.

and sure i dont like running containers that have own databases and other things built in, but its a cron job that needs to run for nextcloud, this is for me one process...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DisasteR picture DisasteR  ·  3Comments

all-the-good-ones-are-gone picture all-the-good-ones-are-gone  ·  3Comments

tanja84dk picture tanja84dk  ·  3Comments

waldner picture waldner  ·  3Comments

aanno picture aanno  ·  3Comments