# How to Contribute to the LabNow AI Container Image Project: A Complete Guide

> Learn how to contribute to the LabNow AI container image project. Fork the repository, modify files, and submit a pull request for CI builds to Quay.io and Docker Hub.

- Repository: [LabNow.ai/lab-foundation](https://github.com/labnow-ai/lab-foundation)
- Tags: how-to-guide
- Published: 2026-03-05

---

**Contributing to the LabNow AI container image project involves forking the repository, modifying install-list files or the core Dockerfile in `docker_core/`, and submitting a pull request that triggers automated CI builds publishing to Quay.io and Docker Hub.**

The **lab-foundation** repository from LabNow AI provides a collection of Docker images bundling complete data-science and AI environments. Built around a modular profile architecture, the project allows contributors to extend the stack by adding new language toolchains, patching existing package lists, or creating entirely new image variants that inherit from the core base image.

## Understanding the Lab Foundation Architecture

The project architecture centers on a **core base image** defined in `docker_core/Dockerfile`. This foundation extends through **profiles**—groups of packages tailored to specific languages or toolchains such as NodeJS, Python, R, Java, and Julia.

Each profile is driven by **install-list files** located under `docker_core/work/` (e.g., `install_list_PY_datascience.pip`, `install_list_R_base.apt`). The build system consumes these lists via `ARG_PROFILE_*` variables, iterating through comma-separated values to install apt or pip dependencies dynamically. Additional specialized images—for PostgreSQL, CUDA, or Atom—extend the core using `FROM` directives and supply their own profile arguments.

The continuous integration pipeline in [`.github/workflows/build-docker.yml`](https://github.com/labnow-ai/lab-foundation/blob/main/.github/workflows/build-docker.yml) automatically executes builds on both CPU-only and GPU runners, pushing successful images to container registries without manual intervention.

## Step-by-Step Contribution Workflow

Follow these steps to submit a successful contribution to the LabNow AI container image project:

1. **Fork and clone** the repository to your GitHub account, then run `git clone https://github.com/<your-user>/lab-foundation.git` locally.

2. **Create a feature branch** using `git checkout -b my-new-profile` to isolate your changes from the main branch.

3. **Extend the core image** by adding install-list files under `docker_core/work/` and referencing them in the `ARG_PROFILE_*` blocks within `docker_core/Dockerfile` (lines 58–94).

4. **Update helper scripts** if custom setup logic is required. Add reusable functions to [`docker_core/work/script-setup.sh`](https://github.com/labnow-ai/lab-foundation/blob/main/docker_core/work/script-setup.sh) and invoke them from the Dockerfile's `RUN` steps.

5. **Adjust CI configuration** (optional) by editing [`.github/workflows/build-docker.yml`](https://github.com/labnow-ai/lab-foundation/blob/main/.github/workflows/build-docker.yml) to add new matrix entries for additional build variants or CUDA versions.

6. **Test locally** by running `docker build` with the specific `--build-arg` parameters you intend to ship, such as `--build-arg ARG_PROFILE_PYTHON=base,datascience,myutils`.

7. **Commit and push** your changes using `git add . && git commit -m "Add my-new-profile"` followed by `git push origin my-new-profile`.

8. **Open a Pull Request** against `LabNow-ai/lab-foundation:main` through the GitHub UI, filling out the template with descriptions of your new profile and linking to relevant CI runs.

9. **Respond to review feedback** by iterating on maintainer comments and pushing additional commits to your feature branch.

10. **Merge** occurs automatically after approval; the CI pipeline then builds and publishes your changes to the public container registries.

## Practical Example: Adding a Custom Python Package

To add a package like `myutils==0.1.0` to the datascience profile, create a new install-list file and wire it into the build arguments.

First, create the install-list:

```bash

# docker_core/work/install_list_PY_myutils.pip

myutils==0.1.0  % Custom utility for data pipelines

```

Next, reference the profile in the Dockerfile. The `docker_core/Dockerfile` processes profiles through a shell loop that checks for `.apt` and `.pip` files:

```dockerfile

# In docker_core/Dockerfile (excerpt)

&& for profile in $(echo $ARG_PROFILE_PYTHON | tr "," "\n") ; do (
      [ -f "/opt/utils/install_list_PY_${profile}.apt" ] && install_apt "/opt/utils/install_list_PY_${profile}.apt" || echo "apt install skipped for ${profile}" ;
      [ -f "/opt/utils/install_list_PY_${profile}.pip" ] && install_pip "/opt/utils/install_list_PY_${profile}.pip" || echo "pip install skipped for ${profile}"
    ) ; done \

```

Build the image locally to verify:

```bash
docker build \
  --build-arg ARG_PROFILE_PYTHON=base,datascience,myutils \
  -t labnow/core:myutils .

```

## Key Files and Their Roles

Understanding these critical files ensures your contributions align with the project's modular design:

- **`docker_core/Dockerfile`** — The central orchestrator defining all `ARG_PROFILE_*` hooks and the main image build logic.

- **[`docker_core/work/script-setup.sh`](https://github.com/labnow-ai/lab-foundation/blob/main/docker_core/work/script-setup.sh)** — Contains shared shell functions (`setup_node_*`, `setup_java_*`, `setup_R_*`) for reusable setup steps across profiles.

- **`docker_core/work/*.apt` and `*.pip`** — Package list files consumed by the build system; examples include `install_list_PY_datascience.pip` and `install_list_R_base.apt`.

- **`docker_atom/Dockerfile`** — Demonstrates extending the core image with editor-specific tooling.

- **`docker_db_postgres/postgres-ext.Dockerfile`** — Shows how database-specific images inherit from the core foundation.

- **[`.github/workflows/build-docker.yml`](https://github.com/labnow-ai/lab-foundation/blob/main/.github/workflows/build-docker.yml)** — The GitHub Actions workflow controlling automated builds, matrix testing, and registry pushes.

## Summary

- The **lab-foundation** project uses a profile-based architecture centered on `docker_core/Dockerfile` and install-list files under `docker_core/work/`.

- Contributors modify **`ARG_PROFILE_*` variables** and create new `.pip` or `.apt` lists to add packages without changing core build logic.

- The **[`script-setup.sh`](https://github.com/labnow-ai/lab-foundation/blob/main/script-setup.sh)** file encapsulates complex setup routines for languages like Java, Node, and R.

- All changes are validated through **GitHub Actions** in [`.github/workflows/build-docker.yml`](https://github.com/labnow-ai/lab-foundation/blob/main/.github/workflows/build-docker.yml) before automatic publication to Quay.io and Docker Hub.

- Local testing requires running `docker build` with the exact `--build-arg` flags specified in the Dockerfile documentation.

## Frequently Asked Questions

### What is the difference between an install-list file and modifying the Dockerfile directly?

**Install-list files** (such as `install_list_PY_datascience.pip`) are plain text lists of packages consumed by the parameterized build loop in `docker_core/Dockerfile`. This separation allows contributors to add software by creating a new list file and updating the `ARG_PROFILE_PYTHON` build argument, without touching the core Dockerfile logic. Direct Dockerfile modifications are only necessary when adding new setup functions or changing the build orchestration itself.

### How do I test my changes before submitting a pull request?

Run `docker build` locally using the same `--build-arg` flags defined in the CI pipeline, such as `--build-arg ARG_PROFILE_PYTHON=base,datascience`. For comprehensive validation, use the `act` tool or the GitHub Actions runner Docker image to execute [`.github/workflows/build-docker.yml`](https://github.com/labnow-ai/lab-foundation/blob/main/.github/workflows/build-docker.yml) locally, which catches missing dependencies that manual builds might miss.

### Can I add a completely new programming language profile to the project?

Yes. Create a new install-list file following the naming convention `install_list_<LANG>_<name>.apt` or `.pip`, add any required setup functions to [`docker_core/work/script-setup.sh`](https://github.com/labnow-ai/lab-foundation/blob/main/docker_core/work/script-setup.sh), and expose the profile through a new `ARG_PROFILE_<LANG>` variable in `docker_core/Dockerfile`. Reference existing profiles like R or Julia in the source code as templates for structure.

### Where are the container images published after my PR is merged?

The CI pipeline in [`.github/workflows/build-docker.yml`](https://github.com/labnow-ai/lab-foundation/blob/main/.github/workflows/build-docker.yml) automatically pushes successful builds to both **Quay.io** and **Docker Hub** registries. The exact repository paths and tagging conventions are defined in the workflow file and project README, ensuring your contributions become immediately available to users consuming the LabNow AI stack.