How to Add Custom apt Packages or pip Packages to LabNow AI Base Docker Images

Add custom apt packages by editing .apt list files under docker_atom/work/ or docker_core/work/, add pip packages by editing .pip files in docker_core/work/, then rebuild the image using the standard Docker build commands.

The LabNow AI foundation repository (labnow-ai/lab-foundation) provides a modular Docker build system that lets you extend base Ubuntu 22.04 images with custom system-level dependencies and Python libraries. Understanding how to add custom apt packages or pip packages to LabNow AI base Docker images allows you to tailor the environment for specific scientific computing, data science, or machine learning workflows without modifying the underlying Dockerfile logic.

Understanding the LabNow AI Docker Build Architecture

The build system organizes images into three logical layers: docker_atom (minimal utilities), docker_base (core Ubuntu system), and docker_core (Python environment with conda). The helper functions install_apt and install_pip defined in docker_atom/work/script-utils.sh drive the installation process by reading plain-text list files.

During the build, the Dockerfile in docker_base/ sources these utilities and calls install_apt /opt/utils/install_list_base.apt to install system packages. Similarly, docker_core/Dockerfile invokes install_pip against various .pip list files to populate the conda-managed Python environment at /opt/conda.

Adding Custom apt Packages to LabNow AI Images

Locate the Correct .apt List File

Identify which layer needs the package. For system utilities required by all downstream images, edit docker_atom/work/install_list_base.apt. For flavor-specific dependencies (e.g., CUDA tools, database clients), locate the relevant .apt file under docker_core/work/ or specific sub-folders like docker_db_postgres/rootfs/opt/utils/.

Edit the Package List

Open the target file and append your package names. The format accepts one package per line with optional comments after a % symbol:

ffmpeg libavcodec-dev libavformat-dev    % multimedia processing libraries
libgdal-dev                              % geospatial data abstraction

Do not include version pinning in the list file; the install_apt function runs apt-get install --no-install-recommends -y for each entry.

Rebuild the Docker Image

Navigate to the appropriate directory and trigger the build:

cd docker_base
docker build -t labnow/base:custom .

The build automatically sources script-utils.sh and executes install_apt against your modified list.

Verify the Installation

Run a container from the new image and check for the package:

docker run --rm labnow/base:custom dpkg -l | grep ffmpeg

The output should list the installed version of ffmpeg and its dependencies.

Adding Custom pip Packages to LabNow AI Images

Choose the Right .pip List File

The docker_core/work/ directory contains multiple .pip files organized by flavor:

  • install_list_PY_base.pip – Core Python libraries used across all images
  • install_list_PY_datascience.pip – Data science specific packages
  • install_list_PY_nlp.pip – Natural language processing libraries

Select the file that corresponds to the image variant you are building.

Append Python Packages

Add your package names following the same comment syntax:

sentence-transformers                % state-of-the-art sentence embeddings
polars                               % fast DataFrame library

The install_pip function reads this file and executes pip install --no-cache-dir -U --pre for each line, installing packages into the conda environment at /opt/conda.

Build and Verify

Build the core image:

cd docker_core
docker build -t labnow/core:custom .

Test the installation by importing the module:

docker run --rm labnow/core:custom python -c "import sentence_transformers; print(sentence_transformers.__version__)"

Key Files and Helper Functions Reference

File Path Purpose
docker_atom/work/script-utils.sh Defines install_apt and install_pip helper functions used across all builds.
docker_atom/work/install_list_base.apt Base system packages installed in every image.
docker_base/Dockerfile Core image definition that sources utilities and calls install_apt.
docker_core/work/install_list_PY_base.pip Core Python packages for the conda environment.
docker_core/work/install_list_PY_datascience.pip Data science flavor Python packages.
docker_core/Dockerfile Builds the Python environment and invokes install_pip.

Summary

  • Edit .apt files under docker_atom/work/ or docker_core/work/ to add system packages, then rebuild the base image.
  • Edit .pip files under docker_core/work/ to add Python libraries, then rebuild the core image.
  • Use the helper functions install_apt and install_pip defined in docker_atom/work/script-utils.sh to ensure consistent installation behavior.
  • Verify installations by running containers and checking package versions before pushing to production registries.

Frequently Asked Questions

Can I add packages without rebuilding the entire image?

No. The LabNow AI build system processes package lists at build time through the install_apt and install_pip functions. To include new dependencies, you must modify the relevant .apt or .pip file and run docker build again. For temporary testing, you can manually install packages inside a running container using apt-get or pip, but these changes will not persist in the image.

What is the difference between docker_atom and docker_core?

docker_atom contains the minimal utility layer including script-utils.sh and install_list_base.apt, providing the foundational install_apt helper used by all downstream images. docker_core builds upon this to create the Python environment using conda, managing .pip package lists for specific flavors like data science or NLP. Think of docker_atom as the system foundation and docker_core as the Python runtime layer.

How do I specify package versions in the list files?

The standard list files support simple package names without version pinning, relying on the latest available version in the Ubuntu or PyPI repositories. If you require specific versions, you can append the version constraint directly in the list file using standard pip or apt syntax, such as numpy==1.24.0 for pip or postgresql-client-14=14.9-0ubuntu0.22.04.1 for apt. The install_pip function passes these strings directly to pip install, while install_apt passes them to apt-get install.

Where are the install_apt and install_pip functions defined?

Both helper functions are defined in docker_atom/work/script-utils.sh. The install_apt function updates the apt cache and installs packages without recommended extras using apt-get install --no-install-recommends -y. The install_pip function installs Python packages into the conda environment at /opt/conda using pip install --no-cache-dir -U --pre. These functions are sourced early in the Docker build process to ensure consistent package management across all LabNow AI image variants.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →