systemd, crond and Docker Container

Photo by Lukas on Unsplash

systemd, crond and Docker Container

This blog explores the ability to run cron, and other system services, thus mirroring the production setup inside VS Code DevContainer and Docker

Recently, I was in a situation where I needed cron jobs to run inside my DevContainer, to mimic the behaviour of my production machine. Specifically, in the context of log rotation. And, given that the default container images do not contain the systemd process on AmazonLinux 2023, a CentOS 8 based distribution ( my environment of choice ), I had to find a way to make it work.

Thankfully, ChatGPT came to my rescue. It gave me a good starting point and allowed me to create a repository for this, in a more polished and "best practices friendly" structure.

First, the objectives. I wanted to have a systemd run environment, that would run cron jobs, and other services, inside my DevContainer.

This required me to create a Dockerfile that would install the systemd service, and cronie to run cron jobs.

FROM amazonlinux:2023

# Install required packages
RUN yum -y update && \
    yum -y install systemd cronie tar gzip git && \
    systemctl enable crond.service

After this, I can now initialize my image to have the cron configurations:

# Configure crond
COPY cron.d/* /etc/cron.d

And finally, start the systemd process as the CMD for the container. This is a blocking process and ensures the container is not killed immediately:

# Start cron and systemd
CMD /usr/sbin/init

There you go. We are now ready to run the container. Just one more thing.

To enable systemd to do its job, this container needs to run in privileged mode. So, my docker-compose.yml looks like this:

services:
  crond-service:
    build:
      context: docker-context
      dockerfile: Dockerfile
    privileged: true

A sample cron config file, to just print a log message when the system reboots, sits inside the cron.d directory in my docker build context directory.

@reboot root echo "in crond after reboot"

To run the container:

docker compose up -d

To check that the cron service is running:

docker compose exec crond-service systemctl status crond.service

And to connect into the container, while the service is running:

docker compose exec crond-service bash

Note that the name of the service in the docker-compose file is: crond-service

Code use in this blog, including the .devcontainer.json and more, is available at: https://github.com/navneetkarnani/docker-crond

This blog originally published at blog.mandraketech.in/systemd-and-docker-con.. on 25/May/2023 by Navneet Karnani ( linkedin.com/in/navneetkarnani )

Did you find this article valuable?

Support MandrakeTech Blog by becoming a sponsor. Any amount is appreciated!