TrafeX / docker-php-nginx

Docker image with PHP-FPM 8.3 & Nginx 1.26 on Alpine Linux
https://hub.docker.com/r/trafex/php-nginx
MIT License
1.37k stars 736 forks source link

running cron as nobody #110

Closed pixeline closed 10 months ago

pixeline commented 1 year ago

I am struggling to make cron work using supervisord as, if I understand correctly, crond needs to be ran by the root user.

crond: can't set groups: Operation not permitted

I tried to add this to supervisord.conf

[program:cron]
command=/usr/sbin/crond -f
user=nobody
autostart=true
autorestart=true

and in the dockerfile

RUN echo "* * * * * /usr/bin/wp cron event run --due-now" > /var/spool/cron/crontabs/nobody

Does someone have a configuration that works?


Full dockerfile content:

ARG ALPINE_VERSION=3.16

FROM alpine:${ALPINE_VERSION}

# Install packages and remove default server definition
RUN apk add --no-cache \
  curl \
  gettext \
  nginx \
  aws-cli \
  php8 \
  php8-ctype \
  php8-curl \
  php8-dom \
  php8-exif \
  php8-fileinfo \
  php8-fpm \
  php8-gd \
  php8-iconv \
  php8-intl \
  php8-mbstring \
  php8-mysqli \
  php8-opcache \
  php8-openssl \
  php8-pecl-imagick \
  php8-phar \
  php8-redis \
  php8-session \
  php8-simplexml \
  php8-tokenizer \
  php8-xml \
  php8-xmlreader \
  php8-xmlwriter \
  php8-zip \
  php8-zlib \
  supervisor

# Configure nginx
COPY config/nginx.conf /etc/nginx/nginx.conf

# Configure PHP-FPM
COPY config/fpm-pool.conf /etc/php8/php-fpm.d/www.conf
COPY config/php.ini /etc/php8/conf.d/custom.ini

# Configure supervisord
COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# Setup document root
# Then make sure files/folders needed by the processes are accessible when they run under the nobody user
RUN mkdir -p /var/www/html && \
    chown -R nobody.nobody /var/www/html /run /var/lib/nginx /var/log/nginx /usr/share /usr/bin

# Switch to use a non-root user from here on
USER nobody

# Add application
COPY --chown=nobody src/ /var/www/html/
WORKDIR /var/www/html

# Install composer from the official image
COPY --from=composer /usr/bin/composer /usr/bin/composer

# Expose the port nginx is reachable on
EXPOSE 80

# Add Wp-Cli
ENV WP_CLI_VERSION 2.7.1
RUN composer create-project wp-cli/wp-cli:$WP_CLI_VERSION /usr/share/wp-cli --no-dev && \
    ln -sf /usr/share/wp-cli/bin/wp /usr/bin/wp && \
    ln -sf /usr/share/wp-cli/bin/wp /usr/bin/wp-cli && \
    wp cli version

# Replace wp-cron with a cronjob
RUN echo "* * * * * /usr/bin/wp cron event run --due-now" > /var/spool/cron/crontabs/nobody

CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
TrafeX commented 1 year ago

Hi @pixeline ,

To make this work you need to remove the USER nobody line in the Dockerfile so that supervisord runs as root. And you also need to change the nobody user in supervisord.conf to root.

pixeline commented 1 year ago

I tried that but then it breaks the socket creation linking nginx and php-fpm

TrafeX commented 1 year ago

Hi @pixeline,

What's the exact error you get?

rauldeheer commented 1 year ago

@TrafeX I'm having the same issue. So the only way to run cronjobs is to execute everything as root, am I correct?

TrafeX commented 1 year ago

@rauldeheer That's correct. I would not advise running a cronjob service in a container, but if you have no other option, this should do it.

rauldeheer commented 1 year ago

@TrafeX What do you suggest instead? I don't think running everything as root is a good option to be honest.

rauldeheer commented 1 year ago

I was able to make it work without using root. This is part of my Dockerfile:

#Beginning of Dockerfile

RUN apk add --no-cache dcron libcap && \
    chown nobody:nobody /usr/sbin/crond && \
    setcap cap_setgid=ep /usr/sbin/crond

RUN echo '* * * * * php /var/www/html/bin/console system:worker' >> /etc/crontabs/nobody

RUN crontab -u nobody /etc/crontabs/nobody
RUN chown -R nobody /var/spool/cron/crontabs/nobody
RUN chmod 0644 /var/spool/cron/crontabs/nobody

COPY entrypoint.sh /scripts/entrypoint.sh
RUN chown -R nobody /scripts/entrypoint.sh
RUN chmod +x /scripts/entrypoint.sh

USER nobody

ENTRYPOINT ["/scripts/entrypoint.sh"]

entrypoint.sh:

#!/bin/sh
/usr/sbin/crond -b
/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf