How to run a cron as a non-root user in Docker 🦾

Yesterday, I was looking to add a cron to an existing Docker image, but it took longer than I would like. Even though I previously had a recipe for adding a cron to a Docker image, I had new contraints that made this solution unsuitable... 😐

Let's go over all the constraints I had:

  • Using a Debian-based image
  • The user running the image is a unprivileged user
  • The cron is not the only process
  • There is an entrypoint script

After searching on the internet, I finally found a working solution with the help of this Stack Overflow answer. So if anyone needs it, this article could serve as a reference. 😁

I hope again it will helps you as well! 😎

Dockerfile

Make sure to replace APPLICATION by the directory you want and NON_ROOT_USER by the name of your unprivileged user. 😉

# https://hub.docker.com/_/debian
FROM debian:buster-20210511

WORKDIR /opt/APPLICATION

# https://packages.debian.org/search?suite=buster&keywords=cron
# Install packages for our application
RUN apt-get update && apt-get -y install \
    # Cron to periodically restart some services
    cron=3.0pl1-134+deb10u1 \
    && echo "*/5 * * * * /opt/APPLICATION/restart.sh > /proc/1/fd/1 2>&1" >> /etc/cron.d/restart-cron \
    # Give the necessary rights to the user to run the cron
    && crontab -u NON_ROOT_USER /etc/cron.d/restart-cron \
    && chmod u+s /usr/sbin/cron

COPY --chown=NON_ROOT_USER:NON_ROOT_USER . .

USER NON_ROOT_USER

ENTRYPOINT ["./entrypoint.sh"]

Enter fullscreen mode Exit fullscreen mode
Minimal code of a custom Docker image with a cron.

entrypoint.sh

#!/bin/bash
echo "Start cron"
cron
echo "cron started"

# Run forever
tail -f /dev/null
Enter fullscreen mode Exit fullscreen mode
A simple entrypoint script that launchs cron.

restart.sh

#!/bin/bash
echo "Restart the services..."

# ...

echo "Services restarted."
Enter fullscreen mode Exit fullscreen mode
A custom script that will be executed at a certain frequency.

16