Skip to content

Migrating a Cron Job

If you already run a job as a cron entry on some server — a Python script, a Node.js task, a compiled binary, anything you can package into a container — you can move it into Runner as a Docker environment and schedule instead of rebuilding it as a KNIME workflow or shell script. This guide walks through that migration end to end.

Say you currently have a crontab entry like this on some server:

0 * * * * /opt/jobs/sync-inventory/run.sh

Package the job as an image

If you don't already have a Docker image for the job, write a minimal Dockerfile around it. For a Python script with a few dependencies:

dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY sync_inventory.py .
ENTRYPOINT ["python", "sync_inventory.py"]

Build and push it to a registry your Runner installation can reach — Docker Hub, a private registry, or one hosted alongside your other CI images:

sh
docker build -t registry.example.com/acme/sync-inventory:1.0 .
docker push registry.example.com/acme/sync-inventory:1.0

If you'd rather have Runner build the image itself, skip the push and upload the Dockerfile directly in the next step instead. In that case, also upload requirements.txt and sync_inventory.py as Additional Files on the environment (not the schedule) — Runner makes the environment's Additional Files available to the Dockerfile's COPY and ADD instructions during the build. Files added on the schedule instead are only mounted into the container at runtime and won't be there yet when the image builds. See Source in the Environments reference.

Create the Docker environment

In your project, click Add Environment, select Docker as the type, and fill in:

  • SourceImage, since you already built and pushed one.
  • Imageregistry.example.com/acme/sync-inventory:1.0.
  • Private Registries — add an entry for registry.example.com with the credentials that can pull the image, if the registry isn't public.

Save the environment. Runner doesn't build anything yet — the image is only pulled the first time a schedule using this environment runs.

Create the schedule

Click Add Schedule, select the environment you just created, and fill in:

  • Schedule0 * * * *, matching the original crontab entry. All cron expressions run in the time zone configured in Settings, so double-check it matches what the original cron job assumed.
  • Command — leave empty if your image's ENTRYPOINT already does the right thing, as in the example above. Otherwise, override it here.
  • Environment Variables — move over anything the script previously read from the shell environment or an .env file next to it, for example API keys or a target hostname.

If the job reads or writes files — a config file, credentials, an output directory — add them under AdvancedAdditional Files on the schedule (schedule-specific) or the environment (shared across schedules). Files are mounted at /nodepit/<filename>; anything the container writes there is collected into the run's artifact archive. See Schedules for the full field reference.

Verify

Save the schedule, then click Run Now to trigger it immediately instead of waiting for the next cron tick. Open the run and check the log output — this is your old cron job's stdout/stderr, now searchable and retained according to the schedule's Remove Runs After setting instead of scrolling through a log file on the original server.

Once you're confident the run behaves the same as the original job, decommission the crontab entry.

Parametrizing a build

If you went the Dockerfile route instead of a pre-built image, use Build Arguments to avoid hardcoding values like a base image version into the Dockerfile itself:

dockerfile
ARG PYTHON_VERSION=3.12
FROM python:${PYTHON_VERSION}-slim

Add a PYTHON_VERSION build argument on the environment to override it without editing the Dockerfile — useful for testing a version bump on a copy of the environment before rolling it out.

See Environments for the full list of Docker-specific settings.

Was this page helpful?