Why Is Crond Failing to Run a Non-Root Crontab on Alpine Linux

How To Run Cron As Non Root In Alpine

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.

How to run a cron job as a non-root user and log the job's output?

The Alpine base images are based on a compact tool set called BusyBox and when you run crond here you're getting the BusyBox cron and not any other implementation. Its documentation is a little sparse, but if you look at the crond source (in C) what you'll find is that there is not any redirection at all when it goes to run a job (see the non-sendmail version of start_one_job); the job's stdout and stderr are crond's stdout and stderr. In Docker, since crond is the container primary process, that in turn becomes the container's output stream.

Anything that shows up in docker logs definitionally went to stdout or stderr or the container's main process. If this cron implementation wrote your job's output directly there, there's nothing wrong or insecure with taking advantage of that.

In heavier-weight container orchestration systems, there is some way to run a container on a schedule (Kubernetes CronJobs, Nomad periodic jobs). You might find it easier and more consistent with these systems to set up a container that runs your job once and then exits, and then to set up the host's cron to run your container (necessarily, as root).

Alpine: service `crond' does not exist

The issue was that some Alpine Docker containers come without the busybox-initscripts package installed. After installing this, crond is running as a service. One other hiccup I ran into is that run-parts, the command the executes the files in the /etc/periodic folders expects there to be no extension, so I stripped that, and everything is working now.

The working Dockerfile looks like this:

FROM node:12.13.0-alpine

RUN apk upgrade --available

RUN apk add --no-cache tini openrc busybox-initscripts

WORKDIR /opt/app

COPY runScraper /etc/periodic/15min/

RUN chmod a+x /etc/periodic/15min/runScraper

COPY . .

RUN chmod a+x startup

ENTRYPOINT ["/sbin/tini", "--"]

CMD ["./startup"]

Failed to edit crontab (linux Alpine)

The solution is:

apk add --update busybox-suid


Related Topics



Leave a reply



Submit