New to Kestra?
Use blueprints to kickstart your first workflows.
Kestra flow running identical scripts on Python 3.9 and 3.13 in separate pinned containers, proving per-task runtime isolation for safe version upgrades and side-by-side evaluation.
Upgrading a language runtime is scary when every job shares one interpreter: bump Python for one pipeline and you may break ten others. This Kestra blueprint shows why that constraint disappears with containerized task isolation. The same script runs twice in one flow, once on python:3.9-slim and once on python:3.13-slim, each task in its own container. You can evaluate a new version next to the old one, in the same execution, without touching anything already running in production.
run_on_python_3_9 task (io.kestra.plugin.scripts.python.Script) executes a small script that prints sys.version, with containerImage: python:3.9-slim pinning the runtime.run_on_python_3_13 task runs the identical script with containerImage: python:3.13-slim.confirm_isolation task (io.kestra.plugin.core.log.Log) points you at the two log outputs, where the different interpreter versions are visible side by side.Each script task gets a fresh container from its pinned image, so dependencies, interpreter version, and OS packages are scoped to the task, not the worker, not the flow, not the instance.
containerImage, so upgrades are one line per task and roll back just as easily.On a shared cron box or a monolithic scheduler worker, the interpreter is global state: one pyenv slip breaks unrelated jobs, and evaluating a new version means standing up a second environment. In Kestra, the runtime is a task property. Declare containerImage and the worker spins up exactly that environment for exactly that task, with logs and outputs captured per run. Kestra Enterprise extends the same idea to plugins themselves with Versioned Plugins, running two versions of the same plugin side by side (for example Ansible 2.16 in production while 2.19 is under evaluation), and custom plugin development covers connectors that do not exist yet.
python:3.9-slim and python:3.13-slim images.No secrets are required. If you swap in private registry images, configure registry credentials on the Docker task runner using {{ secret('REGISTRY_USERNAME') }} and {{ secret('REGISTRY_PASSWORD') }}.
company.team namespace.run_on_python_3_9 and run_on_python_3_13 and compare the printed sys.version values.containerImage to another tag (for example python:3.14-rc-slim) and rerun to test a future release.dependencies per task to test library compatibility across versions.io.kestra.plugin.core.flow.Parallel to compare wall-clock behavior concurrently.