Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enable crond in an Alpine container

Context

I'm trying to schedule some ingestion jobs in an Alpine container. It took me a while to understand why my cron jobs did not start: crond doesn't seems to be running

rc-service -l | grep crond 

According to Alpine's documentation, crond must first be started with openrc (i.e. some kind of systemctl). Here is the Dockerfile

FROM python:3.7-alpine

# set work directory
WORKDIR /usr/src/collector

RUN apk update \
    && apk add curl openrc

# ======>>>> HERE !!!!! 
RUN rc-service crond start && rc-update add crond

# install dependencies
RUN pip install --upgrade pip
RUN pip install pipenv
COPY ./Pipfile /usr/src/collector/Pipfile
RUN pipenv install --skip-lock --system --dev

# copy entrypoint.sh
COPY ./entrypoint.sh /usr/src/collector/entrypoint.sh

# copy project
COPY . /usr/src/collector/

# run entrypoint.sh
ENTRYPOINT ["/usr/src/collector/entrypoint.sh"]

entrypoint.sh merely appends the jobs at the end of /etc/crontabs/root

Problem

I'm getting the following error:

 * rc-service: service `crond' does not exist
ERROR: Service 'collector' failed to build: The command '/bin/sh -c rc-service crond start && rc-update add crond' returned a non-zero code: 1

Things are starting to feel a bit circular. How can rc-service not recognizing a service while, in the same time:

  • sh seems to know the name crond,

  • there was a /etc/crontabs/root

What am I missing?

like image 804
zar3bski Avatar asked Jul 05 '19 10:07

zar3bski


2 Answers

Some Alpine Docker containers are missing the busybox-initscripts package. Just append that to the end of your apk add command, and crond should run as a service.

You might also need to remove the following line from your Dockerfile since it seems as if busybox-initscripts runs crond as a service immediately after installation:

RUN rc-service crond start && rc-update add crond
like image 132
Clark Brent Avatar answered Sep 27 '22 20:09

Clark Brent


I was able to fix this by adding the crond command to the docker-entrypoint.sh, prior to the actual script commands.

e.g.:

#!/bin/sh
set -e

crond &

...(rest of the original script)

This way the crond is reloaded as a detached process.

So all the steps needed was to

  • Find and copy the entrypoint.sh to the build folder. I did this from a running container:
docker cp <running container name>:<path to script>/entrypoint.sh <path to Dockerfile folder>/entrypoint.sh
  • Modify the entrypoint.sh as stated above
  • Include the entrypoint.sh again in the Dockerfile used for building the custom image. Dockerfile example:
...
COPY docker-entrypoint.sh <path to script>/entrypoint.sh
RUN chmod +x <path to script>/entrypoint.sh
...
  • And then just build and use the new custom image:
docker build -t <registry if used>/<image name>:<tag> .
like image 22
0074b60ae Avatar answered Sep 27 '22 18:09

0074b60ae