Manifest Format
A manifest (or cratefile) is a YAML file that defines the commands in a crate. It specifies which Docker images to use, how to run them, and what other crates to include.
Top-level structure
Section titled “Top-level structure”manifest: name: myorg/my-tools # Required: namespace/crate name version: "1.0" # Optional: version string commands: # List of containerized commands - command: samtools docker_image: quay.io/biocontainers/samtools:1.9--h91753b0_8 host_commands: # Optional: host binaries to include - python3 - git imports: # Optional: other crates to include - bulker/coreutils - databio/bedstuffCommand fields
Section titled “Command fields”| Field | Type | Default | Description |
|---|---|---|---|
command | string | required | Executable name created on PATH |
docker_image | string | required | Docker image reference (registry/repo:tag) |
entrypoint | string | value of command | Binary to run inside the container. Emits --entrypoint=<value> under Docker and is used as the exec command under Apptainer. See Entrypoints. |
docker_args | string | none | Extra docker run flags (note: -i/-t are auto-managed by bulker) |
apptainer_args | string | none | Extra Apptainer flags |
docker_command | string | — | Deprecated, use entrypoint. |
apptainer_command | string | — | Deprecated, use entrypoint. |
singularity_command | string | — | Deprecated, use entrypoint. |
volumes | list | [] | Additional mount paths (details) |
envvars | list | [] | Environment variable allowlist for --strict-env mode (details) |
no_user | bool | false | If true, run as root (skip --user mapping) |
no_network | bool | false | If true, don’t add --network=host |
no_default_volumes | bool | false | Skip config-level volume mounts (details) |
workdir | string | $(pwd) | Working directory inside the container |
Host commands
Section titled “Host commands”Commands listed under host_commands are not containerized — they create symlinks to the host binary in the crate directory. Use these for tools that don’t need containerization or that need direct host access.
manifest: name: my-pipeline host_commands: - python3 - perl - git commands: - command: samtools docker_image: quay.io/biocontainers/samtools:1.9--h91753b0_8Host commands are especially important for strict mode, where the PATH is completely replaced.
Imports
Section titled “Imports”Imports include commands from other crates when this crate is activated. Imports are resolved at runtime — updating an imported crate propagates automatically. No rebuilding or reinstalling needed.
manifest: name: my-pipeline imports: - bulker/coreutils - databio/bedstuff commands: - command: my-tool docker_image: my-org/my-tool:latestExamples
Section titled “Examples”Minimal — one tool
Section titled “Minimal — one tool”manifest: name: samtools commands: - command: samtools docker_image: quay.io/biocontainers/samtools:1.9--h91753b0_8Multi-tool with interactive commands
Section titled “Multi-tool with interactive commands”manifest: name: biotools version: "1.0" commands: - command: samtools docker_image: quay.io/biocontainers/samtools:1.9--h91753b0_8 - command: bedtools docker_image: quay.io/biocontainers/bedtools:2.29.2--hc088bd4_0 - command: python docker_image: python:3.11 entrypoint: pythonBulker auto-detects TTY and always keeps stdin open, so -i and -t in docker_args are not needed (they are stripped automatically if present).
Advanced — volumes, envvars, overrides
Section titled “Advanced — volumes, envvars, overrides”manifest: name: advanced commands: - command: redis-server docker_image: redis:7 entrypoint: redis-server docker_args: "--name redis -p 6379:6379" workdir: /data no_user: true no_network: false - command: firefox docker_image: jess/firefox envvars: - DISPLAY - XAUTHORITY - command: jq docker_image: ghcr.io/jqlang/jq entrypoint: jqPipeline with imports and host commands
Section titled “Pipeline with imports and host commands”manifest: name: pepatac version: "1.0.14" imports: - bulker/coreutils - databio/bedstuff host_commands: - python3 - perl - git commands: - command: samtools docker_image: quay.io/biocontainers/samtools:1.9--h91753b0_8 - command: bowtie2 docker_image: quay.io/biocontainers/bowtie2:2.4.5--py39hd2f7db1_2How mounting works
Section titled “How mounting works”Volume mounts come from three sources, merged together at runtime:
1. Config-level volumes (always applied)
Set globally in your bulker config (default: $HOME). Every containerized command gets these mounts.
2. Per-command volumes (from the manifest)
The volumes field on a command adds extra mounts for that command only:
- command: my-tool docker_image: org/my-tool:latest volumes: - /data - /scratchEach entry becomes --volume "/path:/path" — same path inside and outside the container.
3. Auto-mount (automatic, no configuration needed)
When you pass a file path as a command argument, bulker detects it and automatically mounts the containing directory. For example:
samtools view /projects/mydata/sample.bamBulker sees /projects/mydata/sample.bam, resolves it to an absolute path, and mounts /projects/mydata into the container. This happens for any argument that is not a flag (does not start with -) and refers to an existing path or a path whose parent directory exists.
Auto-mount also handles output files that do not yet exist — if the parent directory exists, it is mounted so the command can write there.
Other details
- The working directory inside the container is always set to
$(pwd)so relative paths work. - User ID mapping is automatic (
--user=$(id -u):$(id -g)). - System mounts (
/etc/passwd,/etc/group,/tmp/.X11-unix) are added whensystem_volumesis enabled in config. - Setting
no_default_volumes: trueon a command skips config-level volumes for that command. Auto-mount and per-command volumes still apply.