docker icon indicating copy to clipboard operation
docker copied to clipboard

Cron container now requires Redis parameters to function

Open eric-pierce opened this issue 3 years ago • 1 comments

I'm running two containers as part of my install, one for the main application and one for the cron job. With the latest update (either of Redis to 7.0 or of Nextcloud to 24.0.1, I'm not sure) the cron container crashes unless the two REDIS environment variables are passed into it or present in the env file, so no background jobs are run.

Without the environment variables I had the following output from my cron container:

crond: crond (busybox 1.30.1) started, log level 0
crond: user:www-data entry:(null)
100001000010000100001000010000100001000010000100001000010000
111111111111111111111111
11111111111111111111111111111111
111111111111
1111111
crond: user:www-data entry:(null)
100001000010000100001000010000100001000010000100001000010000
111111111111111111111111
11111111111111111111111111111111
111111111111
1111111
crond: wakeup dt=5
crond: file www-data:
crond:  line php -f /var/www/html/cron.php
crond: wakeup dt=60
crond: file www-data:
crond:  line php -f /var/www/html/cron.php
crond: wakeup dt=60
crond: file www-data:
crond:  line php -f /var/www/html/cron.php
crond:  job: 0 php -f /var/www/html/cron.php
crond: child running /bin/bash
crond: USER www-data pid   8 cmd php -f /var/www/html/cron.php
RedisException: WRONGPASS invalid username-password pair or user is disabled. in /var/www/html/lib/private/RedisFactory.php:143
Stack trace:
#0 /var/www/html/lib/private/RedisFactory.php(143): Redis->auth('REDACTED')
#1 /var/www/html/lib/private/RedisFactory.php(178): OC\RedisFactory->create()
#2 /var/www/html/lib/private/Memcache/Redis.php(43): OC\RedisFactory->getInstance()
#3 /var/www/html/lib/private/Memcache/Factory.php(118): OC\Memcache\Redis->__construct('abfea223e9b5247...')
#4 /var/www/html/lib/private/Server.php(1106): OC\Memcache\Factory->createLocking('lock')
#5 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(162): OC\Server->OC\{closure}(Object(OC\Server))
#6 /var/www/html/3rdparty/pimple/pimple/src/Pimple/Container.php(122): OC\AppFramework\Utility\SimpleContainer->OC\AppFramework\Utility\{closure}(Object(Pimple\Container))
#7 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(129): Pimple\Container->offsetGet('OCP\\Lock\\ILocki...')
#8 /var/www/html/lib/private/ServerContainer.php(136): OC\AppFramework\Utility\SimpleContainer->query('OCP\\Lock\\ILocki...', false)
#9 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(57): OC\ServerContainer->query('OCP\\Lock\\ILocki...')
#10 /var/www/html/lib/private/Server.php(2082): OC\AppFramework\Utility\SimpleContainer->get('OCP\\Lock\\ILocki...')
#11 /var/www/html/lib/private/Files/View.php(122): OC\Server->getLockingProvider()
#12 /var/www/html/lib/private/Server.php(454): OC\Files\View->__construct()
#13 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(162): OC\Server->OC\{closure}(Object(OC\Server))
#14 /var/www/html/3rdparty/pimple/pimple/src/Pimple/Container.php(122): OC\AppFramework\Utility\SimpleContainer->OC\AppFramework\Utility\{closure}(Object(Pimple\Container))
#15 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(129): Pimple\Container->offsetGet('OC\\Files\\Node\\H...')
#16 /var/www/html/lib/private/ServerContainer.php(136): OC\AppFramework\Utility\SimpleContainer->query('OC\\Files\\Node\\H...', false)
#17 /var/www/html/lib/private/AppFramework/Utility/SimpleContainer.php(57): OC\ServerContainer->query('OC\\Files\\Node\\H...')
#18 /var/www/html/lib/private/Server.php(1445): OC\AppFramework\Utility\SimpleContainer->get('OC\\Files\\Node\\H...')
#19 /var/www/html/lib/base.php(602): OC\Server->boot()
#20 /var/www/html/lib/base.php(1104): OC::init()
#21 /var/www/html/cron.php(43): require_once('/var/www/html/l...')
#22 {main}

By adding the Redis environment variables, the cron job runs as expected.

My docker compose is below - the last two lines were what I added to fix the issue.

  nextcloud:
    container_name: nextcloud
    image: nextcloud:latest
    restart: always
    networks:
      - traefik
      - internal
    security_opt:
      - no-new-privileges:true
    depends_on:
      - postgres
      - redis
    volumes:
      - $DOCKERDIR/nextcloud:/var/www/html
      - $DOCKERDIR/nextcloud/changes.ini:/usr/local/etc/php/conf.d/changes.ini
    secrets:
      - postgres_nextcloud_password
    ports:
      - 8008:80
    environment:
      - TZ=$TZ
      - PUID=$PUID
      - PGID=$PGID
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
      - POSTGRES_PASSWORD_FILE=/run/secrets/postgres_nextcloud_password
      - POSTGRES_HOST=postgres
      - NEXTCLOUD_TRUSTED_DOMAINS=nextcloud.$DOMAINNAME
      - REDIS_HOST=redis
      - REDIS_HOST_PASSWORD=$REDIS_PASSWORD
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.nextcloud-rtr.entrypoints=https"
      - "traefik.http.routers.nextcloud-rtr.rule=Host(`nextcloud.$DOMAINNAME`)"
      - "traefik.http.routers.nextcloud-rtr.tls=true"
      ## Middlewares
      - "traefik.http.routers.nextcloud-rtr.middlewares=chain-no-auth@file"
      ## HTTP Services
      - "traefik.http.routers.nextcloud-rtr.service=nextcloud-svc"
      - "traefik.http.services.nextcloud-svc.loadbalancer.server.port=80"
      - "traefik.http.middlewares.nextcloud-dav.replacepathregex.regex=^/.well-known/ca(l|rd)dav"
      - "traefik.http.middlewares.nextcloud-dav.replacepathregex.replacement=/remote.php/dav/"

  nextcloud-cron:
    container_name: nextcloud-cron
    image: nextcloud:latest
    entrypoint: /cron.sh
    restart: always
    networks:
      - internal
    security_opt:
      - no-new-privileges:true
    depends_on:
      - nextcloud
      - redis
    volumes:
      - $DOCKERDIR/nextcloud:/var/www/html
    environment:
      - TZ=$TZ
      - PUID=$PUID
      - PGID=$PGID
      - REDIS_HOST=redis
      - REDIS_HOST_PASSWORD=$REDIS_PASSWORD

eric-pierce avatar Jun 04 '22 19:06 eric-pierce

For what it's worth, I found it much cleaner/easier to build my own Docker image (following the examples included in this repo) and run cron in the main nextcloud container using supervisor/supervisord.

Reasons here: https://github.com/nextcloud/docker/issues/253#issuecomment-1229049856

meonkeys avatar Aug 27 '22 00:08 meonkeys

Hi @eric-pierce Thanks for your report. It would have been very interesting to see your /var/www/html/config.php when this happened (and possibly still today).

Do you have a redis line in your config.php? (note: in the actual file, not in the output of occ config:list system)

My best guess is that somehow your config.php never got rewritten during installation (this should happen automatically). When it gets rewritten it ends up containing your full redis config (based on the REDIS_* passed at install time). If that didn't happen, your NC has been relying solely on /var/www/html/config/redis.config.php and, in turn, those environment variables always being present.

This would have "worked" but required REDIS_* variables to be passed to both your app and cron containers (rather than the cron container picking up the appropriate config from your shared volume's /var/www/html/config/config.php).

The main scenario I can think of this happening in is if you didn't originally install NC with REDIS_* variables, but later added them.

joshtrichards avatar Jul 22 '23 16:07 joshtrichards

Closing due to inability to replicate and insufficient info to proceed at the moment.

Your config.php contents would be insightful. It sounds like your REDIS config was added after installation. Unless the REDIS_ variables are specified at install time, they won't get integrated into your main config.php. Since your main config.php is all that's shared between the cron and app containers, your cron container would have lacked the appropriate REDIS configuration unless the environment variables are specified.

To avoid this either:

  1. install with the REDIS variables at the start
  2. specify all environment variables consistently across containers that are supposed to have matching settings

I personally tend to stick with approach two, since things are often changed later and not all environment variables propagate the same way. This is also necessary for other runtime only variables like the NC_* ones supported upstream.

joshtrichards avatar Nov 05 '23 14:11 joshtrichards