Search code examples
dockercronshdevopsalpine-linux

How To Run Cron As Non Root In Alpine


I am trying to run a container with the following scripts:

Dockerfile

FROM alpine:latest

USER root

RUN apk update \
    && apk upgrade \
    && apk --no-cache add busybox-suid su-exec
RUN chmod u+s /sbin/su-exec

RUN groupadd -r -g 2001 myuser \
    && useradd -r -u 1001 -g myuser myuser

RUN mkdir /home/myuser \
    && chown myuser /home/myuser

COPY --chown=myuser:myuser entrypoint.sh /home/myuser/entrypoint.sh
COPY --chown=myuser:myuser cronjob /home/myuser/cronjob

USER myuser

RUN crontab /home/myuser/cronjob
WORKDIR /home/myuser
ENTRYPOINT["./entrypoint.sh"]

entrypoint.sh

#!/bin/sh

# Start cron daemon.
su-exec root crond -f -l 8

# Start application.

I have read that elevating privileges is not good practice. Therefore, I wish to eliminate usage of su-exec + chmod u+s /sbin/su-exec in my script. I tried su and sudo as well but they were asking for root password so I switched to su-exec instead. I needed to elevate privilege because crond does not run properly without starting it as root. This container will be run in Kubernetes.

Is there a better way to do this?


Solution

  • crond is now running as myuser after following the answer below.

    https://github.com/gliderlabs/docker-alpine/issues/381#issuecomment-621946699

    Dockerfile

    FROM alpine:latest
    
    USER root
    
    RUN apk update \
        && apk upgrade \
        && apk --no-cache add dcron libcap
    
    RUN groupadd -r -g 2001 myuser \
        && useradd -r -u 1001 -g myuser myuser
    
    RUN mkdir /home/myuser \
        && chown myuser /home/myuser
    
    RUN chown myuser:myuser /usr/sbin/crond \
        && setcap cap_setgid=ep /usr/sbin/crond
    
    COPY --chown=myuser:myuser cronjob /home/myuser/cronjob
    RUN crontab /home/myuser/cronjob
    
    COPY --chown=myuser:myuser entrypoint.sh /home/myuser/entrypoint.sh
    
    USER myuser
    
    WORKDIR /home/myuser
    ENTRYPOINT["./entrypoint.sh"]
    

    entrypoint.sh

    #!/bin/sh
    
    # Start cron daemon.
    crond -b -l 8
    
    # Start application.