Reproducible compute starter kit — containers, CI, provenance
Practical templates, patterns, and a checklist to run, version, audit, and scale containerized compute pipelines with workflow engines and captured provenance.
Purpose
This starter kit gives researchers and teams a compact, practical set of patterns and templates to make compute pipelines reproducible, auditable, and cost-aware. It focuses on containerized environments, CI for automated runs, workflow engine skeletons with checkpointing, and explicit provenance capture so results can be reproduced and audited later.
When to use this kit
- You're running multi-step analyses that must be repeatable by others (or by you months later).
- You want a minimal, portable environment that can run on laptop, cluster, or cloud.
- You need provenance (what code, inputs, parameters, environment) recorded for audit or publication.
1) Container strategy & environment locking
Prefer immutable containers for compute code and a separate dependency lockfile for reproducible environments. Choose based on your environment:
- Docker — best for cloud and many CI systems.
- Singularity/Apptainer — useful on HPC where Docker isn't allowed.
- Keep small base images and install only required runtime packages; pin package versions and include hashes when possible.
Example Dockerfile (starter)
<!-- Dockerfile --> FROM ubuntu:22.04 RUN apt-get update && apt-get install -y python3 python3-venv build-essential && rm -rf /var/lib/apt/lists/* COPY environment.lock.txt /opt/env-lock/ RUN python3 -m venv /opt/venv && /opt/venv/bin/pip install --upgrade pip && /opt/venv/bin/pip install -r /opt/env-lock/environment.txt WORKDIR /workspace COPY src/ /workspace/src/ CMD ["/opt/venv/bin/python", "src/run_pipeline.py"]
Example Singularity definition (starter)
%post
apt-get update && apt-get install -y python3 python3-venv
mkdir /opt/venv
python3 -m venv /opt/venv
/opt/venv/bin/pip install -r /workspace/environment.txt
%runscript
exec /opt/venv/bin/python /workspace/src/run_pipeline.py "$@"
Include a separate environment lockfile (pip/conda/renv/packrat) and commit it. For R or Python, include explicit package versions with hashes where supported.
2) Workflow engine skeleton & checkpointing
Use a workflow engine (Nextflow, Snakemake, CWL, Airflow, or similar) to encode steps, dataflow, resource requests, and checkpoints. Key practices:
- Make each step idempotent and side-effect-minimizing.
- Write outputs to explicit, versioned artifact locations (not ephemeral temp). Include a manifest file for produced artifacts.
- Enable resume/retry behavior so interrupted runs can continue from last successful checkpoint.
- Record engine runtime metadata (start/end times, exit codes, node/VM IDs).
Skeleton: Nextflow example
// nextflow.config
process { executor = 'local' }
workflow.onComplete { workflow -> println "Workflow ${workflow}") }
// main.nf
process stepA {
container 'ghcr.io/your-org/analysis:1.0'
input:
path sample
output:
path 'outA'
script:
"""
python /workspace/src/stepA.py --in $sample --out outA
"""
}
3) CI / automation for testable runs
Automate small test runs in CI so changes to code/environment are validated. Use GitHub Actions, GitLab CI, or your preferred system to:
- Build and tag container images (include image digest/hash in release notes).
- Run a minimal end-to-end test using a small test dataset.
- On successful test, optionally push artifacts and container images to registries.
CI snippet (high-level)
- build-image: build container → run unit tests
- test-pipeline: spin up test environment → run workflow with small dataset → upload logs/artifacts
- publish: on tag, push container with immutable tag + digest to registry
4) Provenance capture checklist
Capture enough metadata so another engineer can reproduce the run deterministically. Record:
- Code: Git repo URL + commit SHA.
- Container: image name + digest (sha256) and Dockerfile/Singularity def contents.
- Environment: lockfile(s) for language dependencies, OS package list if relevant.
- Inputs: dataset identifiers, checksums (sha256), and storage locations plus any query/filter parameters used to subset data.
- Parameters: full parameter file or command line used (exact values, random seeds, and config files).
- Workflow run metadata: engine name/version, run id, start/end times, exit codes, hardware used (node ids, instance types).
- Outputs: checksum manifest for all published outputs and a RO-crate/Research Object or simple manifest.json describing produced artifacts.
- Logs: capture stdout/stderr and engine logs; store alongside artifacts.
5) Artifact registries & storage patterns
- Containers → container registry (GitHub Container Registry, Docker Hub, private registry). Pin releases by digest.
- Large datasets → object storage with versioning (S3 with versioning, institutional data repository), and provide stable identifiers (DOI) when publishing.
- Small artifacts and metadata → attach to releases in GitHub/GitLab or push to Zenodo/figshare for archival DOI.
6) Cost & performance considerations
- Use caching where possible (workflow-level caches, container layer caches, data caches).
- Prefer spot/preemptible instances for non-critical batch jobs; design for graceful restart.
- Limit parallelism during exploratory runs; scale up for large production runs after validation.
- Tag cloud resources and link run ids to billing tags so cost per run is traceable.
- Instrument with lightweight metrics (runtime, memory, I/O) and export to Prometheus/Grafana or central logs for bottleneck analysis.
7) Quick reproducibility checklist (practical)
- Commit code and push a tag (record commit SHA).
- Build container and capture image digest; push to registry.
- Run workflow on a small test dataset via CI; collect output checksums and logs.
- Publish artifacts: container tag + digest, manifest.json with inputs/parameters/checksums, and run metadata.
- Create a minimal README that describes exact reproduction steps and required credentials/access.
8) Next steps & templates
This toolkit should be paired with a small repo of templates: Dockerfile & Singularity def, Nextflow/Snakemake skeleton, GitHub Action workflows for build/test/publish, and a provenance manifest template (manifest.json/ro-crate). If you adopt this kit for a team or project, create a standard release checklist that includes an archival step (e.g., push artifacts to Zenodo) for archival reproducibility evidence.
9) Common pitfalls to avoid
- Committing large raw data to Git – instead store checksums and dataset pointers.
- Relying on unpinned base images or floating package versions.
- Not recording random seeds or non-deterministic configuration options.
- Assuming local developer environments match cluster production without testing in containerized runtimes.
Use this starter kit as a practical baseline: keep templates small, test often, and record provenance at every run. That combination makes compute work reproducible, auditable, and easier to scale.
Discussion
Comments and conversation will live here.