Micromamba container
How to package projects into Docker/Podman containers using micromamba for fast, reliable dependency management. Use this skill ANY time the user mentions or implies any of the following: containerizing a project, building a Docker image, creating a Dockerfile, packaging an app for deployment, making a container for a Python/R/Node project, conda in Docker, micromamba in containers, environment.yml for builds, mixing conda and pip packages, optimizing container size, setting up non-root users in containers, or building images for data science/ML/bioinformatics projects. Also trigger when the user asks about Docker best practices for conda environments, troubleshooting conda package resolution in containers, or mentions bioinformatics tools (samtools, bedtools, etc.) that need to go into a container. Even if the user just says 'dockerize this' or 'make a container for my project' without specifying conda or micromamba, trigger this skill if the project appears to use conda, has an environment.yml, or involves data science/ML/bioinformatics dependencies.From its SKILL.md
npx -y skills add soappp9527/micromamba-container --skill micromamba-containerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
12.8 KB, ~3.0k tokens by cl100k_base, as published. Nobody here has run it
Docker + Micromamba Skill
Package projects into Docker containers using micromamba for fast, reliable dependency management.
⚠️ Critical Rules
These two rules cause the hardest-to-debug failures if ignored. Read them before writing any files.
- NEVER include
channelsinenvironment.yml— mirror URLs are configured via.condarcin the Dockerfile only. Puttingchannelsinenvironment.ymloverrides.condarcand causes micromamba to fall back toconda.anaconda.org, resulting in SSL errors, DNS failures, and timeouts. - NEVER install deep learning frameworks (PyTorch, TensorFlow, JAX) via conda — conda pulls the complete CUDA toolkit (4-6GB), duplicating any CUDA in the base image. Always use pip. If unsure whether a package pulls pytorch, use
scripts/detect_cuda_pull.sh <pkg1> [pkg2] ...to verify. See deep-learning.md.
Workflow
Step 1: Verify Package Names
Before writing environment.yml, verify every package name and source. Never guess package names — always search conda-forge, bioconda, or PyPI to confirm each package exists and get its correct name. Substituting a similar-sounding package can cause silent runtime failures.
For each dependency the user requests:
- Search conda-forge first: check
https://anaconda.org/conda-forge/<package-name>or usemicromamba search <package-name> - Search bioconda if needed: check
https://anaconda.org/bioconda/<package-name> - Search PyPI if it's a Python-only package: check
https://pypi.org/project/<package-name>/ - If not found in any channel, ask the user for direction — do NOT substitute similar-sounding packages
Naming conventions to remember:
- R packages from CRAN on conda-forge use
r-prefix:r-seurat,r-qs2,r-data.table - R packages from Bioconductor on bioconda use
bioconductor-prefix:bioconductor-genomeinfodb,bioconductor-DESeq2 - Python packages use their PyPI name:
scanpy,anndata,pandas - Some packages exist on both conda and PyPI — prefer conda for binary packages (numpy, scipy, etc.)
When to STOP and ASK:
- Package not found: ask the user for the correct name or alternative.
- Multiple possibilities: present options and ask for clarification.
- Secondary conda channel required: present options (secondary channel vs pip vs GitHub). When a secondary channel IS used, the
environment.ymlMUST specify the channel prefix (e.g.genomedk::r-doubletfinder=2.0.4). - R package not available on conda: see the R Projects section for the source install workflow.
Step 2: Pre-Build Validation
Before writing environment.yml, run these two checks to catch build failures early. Each takes only a few seconds and saves 15-20 minutes of wasted rebuild time.
2a. Python Version Compatibility Check
For every package, verify its Python version constraint is compatible with the selected Python version. A package may exist on conda-forge or PyPI but require a newer Python than what you're using.
# PyPI packages — check requires_python via JSON API
curl -s https://pypi.org/pypi/<package>/json | python -c "import sys,json; d=json.load(sys.stdin); print(d['info']['requires_python'])"
If incompatible: STOP and ask the user which Python version to target, or add a version pin (e.g., scanpy<1.10 for Python 3.8).
2b. Pip Package Import Dependency Scan
For packages installed via pip (not conda), scan their source for top-level import statements to find undeclared dependencies:
bash scripts/scan_pip_imports.sh <package-name>
If missing dependencies found: add them to environment.yml (prefer conda).
If system libraries needed: If the build fails with libxxx.so not found, use apt-file search libxxx.so to find the package name, then add apt-get install to the Dockerfile.
Note: The scan is a heuristic — it may produce false positives (imports inside if TYPE_CHECKING: blocks, optional features). Use judgment to determine which missing imports are actual hard dependencies vs. optional extras.
Step 3: Create environment.yml
Every micromamba Docker build starts with an environment.yml. This file declares all conda dependencies.
name: myapp
dependencies:
- python=3.11
- pip
# Add conda packages here
- numpy
- pandas
# pip packages go in a nested pip section
- pip:
- some-pypi-package
Key rules:
- Always include
python - Do NOT include
channelsinenvironment.yml— see Critical Rule 1 for why - Pin Python version explicitly (e.g.,
python=3.11) - Put pip-only packages under
- pip:as a nested list
Step 4: Choose a Dockerfile Pattern
Choose the right template for your project:
| Pattern | Use when | Template |
|---|---|---|
| Basic | Simple Python/conda project | assets/templates/basic/Dockerfile |
| Mixed pip | conda + pip packages | assets/templates/mixed-pip/Dockerfile |
| Mixed npm | conda + Node.js packages | assets/templates/mixed-npm/Dockerfile |
| Jupyter | Data science notebooks | assets/templates/jupyter/Dockerfile |
| GPU | PyTorch/TensorFlow with CUDA | assets/templates/gpu/Dockerfile |
User rules when adapting templates:
- ALWAYS use
USER rootfor all installation steps — the base image defaults tomambauserwhich cannot write to/etc/or/usr/. KeepUSER rootfor everyRUNthat installs software, switch toUSER mambauseronly as the final step. Do NOT create a new user withuseradd—mambauseralready exists. - ALWAYS order Dockerfile instructions by change frequency — put stable layers first (mirror config,
environment.yml), heavy pip packages (PyTorch) in their own RUN step, and application code last. This way, changing application code doesn't invalidate the dependency installation cache. - NEVER use
git cloneinside the Dockerfile — base micromamba images do NOT havegitinstalled. Clone on the host first, thenCOPYthe source into the build context.
Auto-detect mirror region: templates use Tsinghua mirrors by default. Run the following to automatically remove mirror configs if you are outside China:
# If outside China, remove mirror config lines to use default repositories
if [ "$(curl -s --connect-timeout 2 https://ipinfo.io/country 2>/dev/null)" != "CN" ]; then
sed -i "/configs\/tsinghua/d" Dockerfile
fi
Mirror rules:
- Mirror URLs go in
.condarconly;environment.ymlshould NOT have achannelskey (it overrides.condarcand causes fallback toconda.anaconda.org) - Order matters:
conda-forgebeforebioconda(bioconda depends on conda-forge) channel_priority: strictis critical — without it, micromamba runs inflexiblemode and will still attempt to reachconda.anaconda.orgas a fallback, causing SSL errors in restricted networks- Mirror fallback order: Tsinghua → Aliyun → USTC → default. For resilience, add these env vars to the Dockerfile:
ENV MAMBA_DOWNLOAD_RETRIES=15 ENV MAMBA_REMOTE_FETCH_TIMEOUT_SECS=180
Before building, automatically create a .dockerignore file. This reduces build context size and speeds up builds:
.git
__pycache__
*.pyc
.env
.venv
node_modules
*.md
tests/
docs/
Add project-specific exclusions based on what you find in the directory — look for large data files (*.h5, *.fastq, *.bam), output directories (data/, results/, output/), and local config files (.env.local, secrets/).
All patterns use one of two base images depending on GPU needs:
- GPU (CUDA 12.4):
mambaorg/micromamba:cuda12.4.1-ubuntu22.04 - CPU only:
mambaorg/micromamba:debian12-slim— note:icu>=76requires a newerlibstdc++.so.6than Debian 12 provides. If you seeCXXABI_1.3.15 not found, pinicu<76inenvironment.yml.
R Projects
If the project uses R, you need to modify the chosen Dockerfile template. Follow the complete R Source Install Checklist, which covers:
- Scanning R package dependencies from DESCRIPTION files (
scripts/scan_r_deps.sh) - Configuring CRAN mirrors dynamically based on location
- Installing R packages from GitHub/CRAN/Bioconductor source with
dependencies=FALSE - The correct Dockerfile step ordering (conda packages → Rprofile.site → source install)
Quick checklist before building:
- All conda-resolvable R deps are in
environment.yml(withr-/bioconductor-prefixes, see Step 1) - CRAN mirror URL is set in the Dockerfile (not inherited from host shell)
- Source installs use
dependencies=FALSE— conda already installed the deps
Step 5: Build, Lock, Verify, and Clean
Execute these sub-steps in order. Do NOT skip any.
5.1 Detect Runtime and Determine Tag
source scripts/detect_runtime.sh
IMAGE_NAME=$(basename "$(pwd)")
TAG="$(date +%Y%m%d)-$(git rev-parse --short HEAD 2>/dev/null || echo local)"
IMAGE_TAG="${IMAGE_NAME}:${TAG}"
Tag naming rules:
- Format:
<image-name>:YYYYMMDD-<short-hash>(orlocalif no git repo) - Do NOT add a
latesttag - If the user provides an image reference, parse it intelligently:
myapp→myapp:20260401-localmyapp:v1.0→myapp:v1.0(user's tag takes precedence)myrepo/myapp→myrepo/myapp:20260401-localmyrepo/myapp:v1.0→myrepo/myapp:v1.0
- If no image name is provided, derive from the project directory name
5.2 Build the Image
timeout 7200 $RUNTIME build $BUILD_FLAGS -t "${IMAGE_TAG}" .
ALWAYS execute the build — do not just show the commands.
The timeout 7200 wrapper ensures the build fails after 2 hours instead of hanging indefinitely.
5.3 Lock Resolved Versions (MANDATORY — do NOT skip)
After a successful build, export the resolved package versions and update environment.yml. This is what makes the build reproducible — without it, the next build may pull different package versions and break.
# Extract pinned versions for the packages the user requested
# Example: user asked for samtools, bedtools, numpy, r-ggplot2
bash scripts/lock_versions.sh "$RUNTIME" "${IMAGE_TAG}" samtools bedtools numpy r-ggplot2 > /tmp/locked-deps.txt
Then update environment.yml by replacing the unpinned package names with the pinned versions from the script output. For example, replace - numpy with - numpy=1.26.4. Keep the name, python, and pip: sections intact — only replace the package lines with their pinned equivalents.
5.4 Verify Installation
Run verification commands for each user-requested package inside the container to confirm they import correctly.
ALWAYS prefix commands with micromamba run — the base image defaults to mambauser without an active conda environment, so bare commands like python script.py or R -e "..." will fail.
# For Python packages:
$RUNTIME run --rm "${IMAGE_TAG}" micromamba run python -c "import numpy; import pandas; print('Python packages OK')"
# For R packages:
$RUNTIME run --rm "${IMAGE_TAG}" micromamba run R -e "library(ggplot2); library(ggpubr); cat('R packages OK\n')"
# If the image has multiple package types, run ALL applicable verification commands.
Rules:
- Include all user-requested packages (Python:
import, R:library()withoutr-prefix) - End with a success message (
print()orcat()) so the output is unambiguous - For R packages that print long banners (e.g. ComplexHeatmap), wrap in
suppressPackageStartupMessages()
5.5 Clean Dangling Images (MANDATORY — do NOT skip)
$RUNTIME image prune -f
5.6 Report to User
Report the following to the user:
- Image name and tag
- Key package versions (from the locked
environment.yml) - Verification result (pass/fail)
- Build failures (if multiple attempts were needed, summarize error, root cause, and fix)
What ships with it: 25 files
25.5 KB alongside SKILL.md, 5 of them executable
assets/
- configs/aliyun/.condarc172 B
- configs/aliyun/pip.conf94 B
- configs/tsinghua/.condarc192 B
- configs/tsinghua/pip.conf118 B
- configs/ustc/.condarc174 B
- configs/ustc/pip.conf100 B
- templates/basic/Dockerfile755 B
- templates/basic/environment.yml80 B
- templates/gpu/Dockerfile974 B
- templates/gpu/environment.yml108 B
- templates/jupyter/Dockerfile796 B
- templates/jupyter/environment.yml161 B
- templates/mixed-npm/Dockerfile857 B
- templates/mixed-npm/environment.yml136 B
- templates/mixed-npm/package.json240 B
- templates/mixed-pip/Dockerfile695 B
- templates/mixed-pip/environment.yml204 B
references/
- deep-learning.md5.0 KB
- r-source-install.md4.6 KB
scripts/
- detect_cuda_pull.shruns1.7 KB
- detect_runtime.shruns462 B
- lock_versions.shruns1.4 KB
- scan_pip_imports.shruns1.4 KB
- scan_r_deps.shruns1.3 KB
- README.md3.9 KB
Gives 1 of the 12 instructions most containers cloud skills give in ~3.0k tokens
Counted across 607 of the 657 authors here whose files we hold, read 2026-08-07
- Run containers as a non-root userin 66 of 607, across 46 files
- Use multi-stage buildsin 53 of 607, across 44 files
- Use Promise.all for independent operationsin 47 of 607, across 13 files
- Import directly instead of barrel filesin 46 of 607, across 12 files
- Use ternary instead of AND for conditionalsin 45 of 607, across 12 files
- Use Set or Map for O(1) lookupsin 42 of 607, across 10 files
- Create a .dockerignore filehere, and in 41 of 607, across 31 files
- Read individual rule files for detailsin 39 of 607, across 9 files
- Copy dependency files before source codein 36 of 607, across 23 files
- Authenticate server actions like API routesin 35 of 607, across 7 files
- Use next/dynamic for heavy componentsin 34 of 607, across 9 files
- Use React.cache for per-request deduplicationin 34 of 607, across 10 files
Said here and by no other author read
- never include channels in environment.yml
- never install deep learning frameworks via conda
- verify every package name and source before writing environment.yml
- check python version compatibility for every package
- run a pip package import dependency scan
- always use root for all installation steps
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.