Run Nextflow pipelines on Flyte, with every Nextflow task as a child action of the calling task.
Nextflow
The Nextflow plugin runs Nextflow pipelines on Flyte. The Nextflow head runs inside a Flyte task, and the nf-flyte Nextflow plugin runs every Nextflow task as a child action of that task. A pipeline therefore shows up in Flyte as one run, with one action per Nextflow task:
- Each process runs in its own
container, with itscpus,memory,disk,accelerator, andtimedirectives. The image only needsbash: Flyte stages the task’s files. - Nextflow keeps its own retries (
errorStrategy) and-resume. Flyte caches task results across runs. - Aborting the Flyte run aborts the pipeline and its running tasks.
Use this plugin to run existing Nextflow pipelines, such as those from nf-core, without rewriting them, and to chain them with Python tasks in the same Flyte run.
Installation
pip install flyteplugins-nextflowQuick start
nextflow_image() builds the image for the task that runs the Nextflow head, with flyteplugins-nextflow installed. Call run_nextflow from an async task:
import flyte
from flyte.io import Dir
from flyteplugins.nextflow import nextflow_image, run_nextflow
env = flyte.TaskEnvironment(
name="nextflow",
image=nextflow_image(),
resources=flyte.Resources(cpu=2, memory="4Gi"),
)
@env.task
async def nf_core_demo(revision: str = "1.2.0") -> Dir:
# The `test` profile brings its own small samplesheet and resource limits
return await run_nextflow("nf-core/demo", revision=revision, profile="test", outdir="results")flyte run nf_core_demo.py nf_core_demoThis runs the nf-core/demo pipeline (FastQC, seqtk trim, and MultiQC). Each process runs as a child action of nf_core_demo, in its own biocontainers image, and the results directory comes back as a Dir.
The resources on the task environment apply only to the Nextflow head. Pipeline processes get their resources from their own directives.
run_nextflow arguments
| Argument | Description |
|---|---|
pipeline |
Repository (nf-core/rnaseq), URL or path to run. |
revision |
Git tag, branch or commit (-r). |
profile |
Comma-separated config profiles (-profile). |
params |
Pipeline parameters as a mapping, passed as a params file. |
outdir |
--outdir. A relative path goes under the task’s raw data prefix. The directory is returned as a Dir; without outdir, run_nextflow returns None. |
work_dir |
Work directory. Default: nextflow-work under the task’s raw data prefix. |
config |
Extra Nextflow config: config text, or an absolute path to a config file (a Path, or a string ending in .config). A string path is used only if the file exists; otherwise it is treated as config text. Relative paths don’t resolve, because Nextflow runs in a temporary launch directory. |
resume |
Resume the previous run that used the same work_dir. |
report |
Render Nextflow’s execution report, timeline, and DAG into the task’s Flyte report. The task must be declared with report=True. |
extra_args |
Any other nextflow run arguments. |
run_nextflow must be called from inside a Flyte task.
For example, to pass pipeline parameters and add a config override:
await run_nextflow(
"nf-core/rnaseq",
params={"input": "s3://my-bucket/samplesheet.csv", "genome": "GRCh38"},
config="process.errorStrategy = 'retry'\nprocess.maxRetries = 2",
outdir="results",
)Reports
With report=True, Nextflow’s execution report, timeline, and DAG appear as tabs in the task’s report in the Flyte UI. Declare the task with report=True as well:
@env.task(report=True)
async def rnaseq() -> Dir:
return await run_nextflow("nf-core/rnaseq", profile="test", outdir="results", report=True)The reports are published even when the pipeline fails.
Resume
Nextflow’s resume state lives in the work directory, not in the task pod:
- the task cache (the cloud cache on object stores;
.nextflow-cachein the work directory locally) - a session ID derived from the work directory
This has two effects:
-
Retries resume automatically. The default work directory is shared by all attempts of a task, so a retried task passes
-resumeand picks up where the failed attempt stopped. -
Resuming across runs needs a fixed
work_dir. Pass the samework_dirto each run, andresume=Truefrom the second run on:await run_nextflow("nf-core/rnaseq", work_dir="s3://my-bucket/rnaseq-work", resume=True)
Errors
If Nextflow exits with a non-zero status, run_nextflow raises a NextflowError. Its message contains the end of the Nextflow output and the end of .nextflow.log, and its exit_code attribute holds Nextflow’s exit status.
Local runs
When the task runs locally (flyte run --local), Nextflow uses its own executors instead of nf-flyte: local by default, or whatever profile or config selects, such as docker. This needs nextflow on the PATH.
Image
nextflow_image() contains a JRE, Nextflow, and the nf-flyte plugin. Pipeline processes don’t run in this image; each one runs in its own container.
| Argument | Description |
|---|---|
nextflow_version |
Nextflow release to install. Default: 25.10.6. |
nf_flyte |
nf-flyte plugin to install: a version from the Nextflow plugin registry, or the Path to a locally built plugin zip (nf-flyte-<version>.zip). |
base |
Image to add Nextflow to. Default: the Flyte Debian base image. |
name |
Image name, used only when base isn’t set. Default: nextflow. |
To use a locally built nf-flyte plugin, pass its zip:
from pathlib import Path
image = nextflow_image(
nf_flyte=Path("~/nf-flyte/build/distributions/nf-flyte-0.1.0.zip").expanduser(),
)Requirements
flyte2.12.0 or later, andflyteplugins-nextflow2.12.0 or later.- On a cluster, the work directory must be on an object store Flyte can read (S3, GCS, or Azure). The default, under the task’s raw data prefix, always is.
- Every process container needs
bash.