Skip to main content

SciTeX Container

SciTeX

Unified container management for Apptainer/Singularity and Docker — versioned SIFs, atomic switch/rollback, and reproducible env snapshots.

Full Documentation · uv pip install scitex-container[all]

pypi python docs

tests install-check quality cov


Problem and Solution

# Problem Solution
1 "Reproducible" containers drift -- Dockerfile builds a different image each time because apt-get install python3 floats Versioned SIF -- scitex-container build pins the image content hash; switch-version 2.19.5 is an atomic symlink flip
2 Rollback requires docker tags + manual surgery -- something breaks in prod; reverting to yesterday's container is 15 minutes of yak-shaving rollback is one command -- previous active SIF restored; sandbox state preserved
3 Paper "env" is pip freeze -- useless without the python version, OS libs, CUDA driver env_snapshot() -- full reproducibility capsule: container tag + pip freeze + conda env + apt packages + git commits, serialized as a single file for manuscript attachments

Architecture

scitex-container/
├── src/scitex_container/
│   ├── __init__.py              # apptainer, docker, host, env_snapshot + MCP-parity re-exports
│   ├── apptainer/
│   │   ├── _build.py            # build SIF / sandbox from .def (pinned hash)
│   │   ├── _config.py           # reproducible-build config (retain, require_verified)
│   │   ├── _freeze.py           # extract pip/dpkg/npm lock files from built SIF
│   │   ├── _lockgen.py          # lock capture, locked-def generation, version-set comparison
│   │   ├── _reproducible.py     # self-verifying reproducible-build round-trip + use-time verify gate
│   │   ├── _store.py            # timestamped (sif, lock) artifact store
│   │   ├── _versioning.py       # list / switch / rollback / deploy SIF versions
│   │   ├── _sandbox.py          # sandbox create / maintain / update / to-sif
│   │   ├── _sandbox_versioning.py # sandbox list / switch / rollback / cleanup
│   │   ├── _status.py           # list available containers and build status
│   │   ├── _utils.py            # shared utilities (detect container cmd, find containers dir)
│   │   └── _verify.py           # SIF + lock-file integrity
│   ├── docker/                  # rebuild / restart compose services
│   │   ├── _compose.py          # compose helpers
│   │   └── _mounts.py           # bind mount helpers
│   ├── host/                    # TeX Live, ImageMagick, bind mounts
│   │   ├── _mounts.py           # mount configuration
│   │   └── _packages.py         # install / check host packages
│   ├── _snapshot.py             # env_snapshot(): container + host + git + lock files
│   ├── _mcp/                    # MCP handler implementations
│   │   └── handlers.py          # async handlers: build, list, switch, rollback, deploy, etc.
│   ├── _cli/                    # scitex-container CLI entrypoint
│   │   ├── __init__.py          # main click group with all subcommands
│   │   ├── _apptainer.py        # apptainer sub-commands (build, freeze, list, switch, etc.)
│   │   ├── _docker.py           # docker sub-commands (rebuild, restart)
│   │   ├── _host.py             # host sub-commands (install, check, show-mounts)
│   │   ├── _sandbox.py          # sandbox sub-commands (create, maintain, list, switch, etc.)
│   │   ├── _status.py           # show-status dashboard
│   │   ├── _env_snapshot.py     # save-env-snapshot command
│   │   ├── _mcp.py              # mcp sub-commands (start, doctor, list-tools, install)
│   │   └── _skills.py           # skills list / get / install
│   ├── _compat.py               # compatibility shim for optional scitex-dev dependency
│   ├── mcp_server.py            # MCP server (optional, via fastmcp)
│   └── _skills/scitex-container/# bundled agent skill files
└── tests/

Installation

Requires Python >= 3.10.

pip install scitex-container

With MCP server support (for AI agent integration):

pip install scitex-container[mcp]

Full installation:

pip install scitex-container[all]

Quick Start

# Unified status dashboard
scitex-container show-status

# Build Apptainer SIF from definition file
scitex-container apptainer build scitex-final

# Version management
scitex-container apptainer list
scitex-container apptainer switch 2.19.5
scitex-container apptainer rollback

# Show all commands
scitex-container --help-recursive

Four Interfaces

Python API
import scitex_container as ctr

# Apptainer container management
ctr.apptainer.build(def_name="scitex-final", sandbox=True)
ctr.apptainer.list_versions(containers_dir="/opt/containers")
ctr.apptainer.switch_version("2.19.5", containers_dir="/opt/containers")
ctr.apptainer.rollback(containers_dir="/opt/containers")

# Reproducible build round-trip (rough build + freeze + lock + verify)
result = ctr.apptainer.build_reproducible(
    layer="sac-base",
    root="/opt/containers",
    def_path="recipes/apptainer-base.def",
)
print(f"Verified: {result.verified}")

# Use-time verify gate
status = ctr.apptainer.check_verified("/opt/containers/sac-base.sif")
print(f"State: {status.state}")

# Host package management
ctr.host.check_packages()

# Docker operations
ctr.docker.rebuild(env="prod")
ctr.docker.restart(env="prod")

# Environment reproducibility snapshot
snapshot = ctr.env_snapshot()
Reproducible Build API
from pathlib import Path
import scitex_container

# Verify container integrity
result = scitex_container.apptainer.verify(
    sif_path="/opt/containers/scitex-final.sif"
)
# Returns: {sif, def_origin, pip_lock, dpkg_lock, overall}

# Full reproducible round-trip
rt_result = scitex_container.apptainer.build_reproducible(
    layer="sac-base",
    root="/opt/containers",
    def_name="apptainer-base",
    verify=True,
    keep=False,
)
# rt_result.verified is True/None; rt_result.diff shows any drift

# Use-time gate
status = scitex_container.apptainer.check_verified(
    "/opt/containers/sac-base.sif",
    require_verified=True,
)

Build storage

Container builds do not silently depend on the host's /tmp or home filesystem. scitex-container resolves Apptainer/Singularity build storage in this order:

  1. an explicit runtime override (APPTAINER_TMPDIR / SINGULARITY_TMPDIR),
  2. an explicit TMPDIR,
  3. scratch directories on the physical output-artifact filesystem.

Explicit APPTAINER_CACHEDIR / SINGULARITY_CACHEDIR values are also preserved; otherwise the cache is colocated with the selected build storage. The resolved paths are logged for every build and are preserved through sudo. A reproducible verification also checks that its temp filesystem has at least the rough SIF's size free before launching the replay. This is a lower bound: Apptainer needs enough space for the whole uncompressed image and temporary files.

CLI Commands
scitex-container show-status              # Unified dashboard
scitex-container apptainer build           # Build SIF from .def
scitex-container apptainer freeze          # Extract pip/dpkg/npm lock files
scitex-container apptainer list            # List versioned SIFs
scitex-container apptainer switch VERSION  # Switch active SIF version
scitex-container apptainer rollback        # Revert to previous version
scitex-container apptainer deploy          # Copy active SIF to production
scitex-container apptainer clean           # Remove old versions
scitex-container apptainer verify          # Verify SIF integrity
scitex-container save-env-snapshot         # Reproducibility snapshot
Sandbox Operations
scitex-container sandbox create --source scitex-final.sif
scitex-container sandbox maintain -s scitex-sandbox/ -- apt-get update
scitex-container sandbox list -d ./containers
scitex-container sandbox switch 20260301_120000
scitex-container sandbox rollback
scitex-container sandbox clean --keep 3
scitex-container sandbox update -s scitex-sandbox/
Host Package Management
scitex-container host install          # Install TeX Live + ImageMagick
scitex-container host check            # Verify host packages
scitex-container host show-mounts      # Show configured bind mounts
Docker Operations
scitex-container docker rebuild        # Rebuild Compose services
scitex-container docker restart        # Restart services
MCP Server

scitex-container exposes an MCP server so AI agents (Claude, etc.) can manage containers autonomously.

# Start MCP server
scitex-container-mcp

# Diagnostics and tool listing
scitex-container mcp doctor
scitex-container mcp list-tools -vv
Tool Description
container_build Build SIF or sandbox from .def file
container_list_versions List versioned SIFs with active marker
container_switch Switch active SIF version
container_rollback Roll back to previous SIF version
container_deploy Copy active SIF to production target dir
container_cleanup Remove old SIF versions (keep N most recent)
container_verify Verify SIF SHA256, .def origin, and lock files
container_status Unified dashboard: Apptainer + host + Docker
container_env_snapshot Capture environment snapshot
container_skills_get Get content of a bundled skill file
container_skills_list List bundled skill files
sandbox_create Convert SIF to writable timestamped sandbox
docker_rebuild Rebuild Docker images without cache
docker_restart Restart Docker containers
host_install Install TeXLive / ImageMagick on the host
host_check Check which host packages are installed
Skills

Skills provide workflow-oriented guides that AI agents query to discover capabilities and usage patterns.

scitex-container skills list              # List available skill pages
scitex-container skills get SKILL         # Show main skill page
scitex-dev skills export --package scitex-container  # Export to Claude Code
Skill Content
01_installation pip install + runtime deps + smoke verify
02_quick-start Build a SIF + snapshot environment
03_python-api Top-level Python surface (re-exports + submodules)
04_cli-reference Full scitex-container subcommand surface
11_mcp-tools MCP tools for AI agents
20_environment Environment variables

Demo

sequenceDiagram
    participant U as user
    participant SC as scitex-container
    participant FS as /opt/containers
    U->>SC: apptainer build --def-name scitex-final
    SC->>FS: scitex-final.sif (pinned)
    U->>SC: apptainer switch 2.19.5
    SC->>FS: current.sif -> scitex-final-2.19.5.sif
    U->>SC: apptainer rollback
    SC->>FS: current.sif -> scitex-final-2.19.6.sif
    U->>SC: save-env-snapshot
    SC-->>U: snapshot.json (SIF hash + pip + dpkg + git + host)

Part of SciTeX

scitex-container is part of SciTeX. Install via the umbrella with pip install scitex[container] to use as scitex.container (Python) or scitex container ... (CLI).

import scitex_container

# Capture snapshot for Clew integration
snapshot = scitex_container.env_snapshot()
# snapshot includes: container version, SIF hash, lock files, host packages

Four Freedoms for Research

  1. The freedom to run your research anywhere — your machine, your terms.
  2. The freedom to study how every step works — from raw data to final manuscript.
  3. The freedom to redistribute your workflows, not just your papers.
  4. The freedom to modify any module and share improvements with the community.

AGPL-3.0 — because we believe research infrastructure deserves the same freedoms as the software it runs on.

SciTeX

Metadata

Release files for scitex-container 0.4.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for scitex-container 0.4.4
File Size Uploaded
scitex_container-0.4.4.tar.gz 5.4 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for scitex-container 0.4.4
File Interpreter ABI Platform
scitex_container-0.4.4-py3-none-any.whl Python 3 none any Details

Total release size: 10.3 MB

Release files / scitex_container-0.4.4.tar.gz

Download URL scitex_container-0.4.4.tar.gz
Size 5.4 MB
Tags Source
SHA-256 checksum
How to use checksums
71868ecd7a7d56c4aab263165c952848440236dd446108d1d6c6a4ad5ee74a67
BLAKE2b-256 checksum
How to use checksums
e2d60796bb2f49bc4476e7aa9c4ca4ef121daa38627dd1a5953c3422939002c7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release files / scitex_container-0.4.4-py3-none-any.whl

Download URL scitex_container-0.4.4-py3-none-any.whl
Size 5.0 MB
Tags Python 3
SHA-256 checksum
How to use checksums
e2c2d08106bc9fec39af9a0c0afbdaae504d15be44be3f20dcdf0580cfb176b9
BLAKE2b-256 checksum
How to use checksums
65899df1d8999817b08f30f58b2a998bac33b3a6d94cf612c5c9033b03d393b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.4 This release

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.6

2 release files

0.1.3

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page