Best Practices for Running LabNow AI Docker Images in Production Environments

Pin exact image tags, run containers as the non-root labnow user, mount persistent volumes for data, and use Docker Compose to orchestrate multi-service stacks when deploying LabNow AI containers in production.

The labnow-ai/lab-foundation repository provides a modular container stack designed for reproducible AI and data science workflows. By leveraging its layered architecture—from the minimal Ubuntu base to specialized GPU and database images—you can build secure, scalable production environments that maintain consistency across development and deployment.

Understanding the LabNow AI Container Architecture

LabNow AI ships a layered container stack that lets you compose a production-ready AI/Data-Science runtime from small, purpose-built images. Each layer builds upon the previous one, enabling precise control over your production environment.

The Four Container Layers

  • Base Layer: The foundation located in docker_base/Dockerfile provides a minimal Ubuntu image with a full Conda installation, system-Python replacement, and essential utilities. This layer establishes the labnow non-root user and core environment.

  • Core Layer: Defined in docker_core/Dockerfile, this adds language runtimes (Python, R, Julia, Go, Node) and scientific packages via the script-setup toolkit. It uses ARG variables (ARG_PROFILE_PYTHON, ARG_PROFILE_R, ARG_PROFILE_JAVA) to control which language stacks install without rebuilding the entire stack.

  • Atom Layer: The docker_atom/Dockerfile builds an Ubuntu "noble" image bundling the script-setup helpers and OS tools. This serves as the entry point for custom images and houses the automation scripts in docker_atom/work/.

  • Specialized Layers: Production-specific variants including CUDA support (docker_cuda/nvidia-cuda.Dockerfile) and PostgreSQL (docker_db_postgres/postgres-ext.Dockerfile) extend the core stack for GPU computing and database workloads.

The Script-Setup Automation Toolkit

The script-setup collection under docker_atom/work/ and docker_core/work/ automates dependency installation and enforces reproducible versions. Key components include:

These scripts write environment files sourced at container startup, ensuring consistent runtime configurations across deployments.

Production Deployment Best Practices

Pin Exact Image Tags

Prevent surprise upgrades when latest changes by specifying immutable tags. The LabNow registry uses dated tags (e.g., labnow/core:python3.12-datascience-20241010) that guarantee repeatable builds.

docker pull labnow/atom:ubuntu-noble-20241010

Run as Non-Root User

Reduce attack surface by using the labnow user created in docker_base/Dockerfile. The images explicitly set USER labnow to enforce non-privileged execution.

docker run --user labnow labnow/core:python3.12-datascience-20241010

Mount Persistent Volumes

Keep notebooks, models, and database data across container restarts by mounting host directories to container paths.

docker run -v /srv/labnow/data:/opt/data -v /srv/labnow/config:/opt/config labnow/core:latest

Set Resource Limits

Avoid noisy-neighbor problems in shared clusters by constraining CPU and memory allocation.

docker run --cpus="4" --memory="8g" labnow/core:python3.12-datascience-20241010

Use Docker Compose for Multi-Service Stacks

Orchestrate database and AI services together with proper networking and health checks. The following configuration demonstrates a production-ready stack using labnow/core with PostgreSQL:

version: "3.9"
services:
  labnow:
    image: labnow/core:python3.12-datascience-20241010
    container_name: labnow-app
    user: labnow
    ports: ["8888:8888"]
    environment:
      - JUPYTER_TOKEN=${JUPYTER_TOKEN}
    volumes:
      - ./workspace:/opt/workspace
    depends_on:
      - pg
    command: jupyter lab --ip=0.0.0.0 --no-browser
  pg:
    image: labnow/postgres:15-20241010
    container_name: labnow-pg
    environment:
      POSTGRES_PASSWORD: ${PG_PASSWORD}
      POSTGRES_USER: labnow
      POSTGRES_DB: labnow_db
    volumes:
      - pg_data:/var/lib/postgresql/data
volumes:
  pg_data:

Start the stack with:

docker compose up -d

Secure Credential Management

Supply API keys and passwords via Docker secrets or environment files rather than baking them into images. The Docker-Kit README demonstrates env-var injection patterns that apply to production services.

docker run --env-file .env.prod labnow/core:python3.12-datascience-20241010

Implement CVE Scanning

Regularly scan images for vulnerabilities using tools like Trivy or Clair. LabNow images contain many binaries across language runtimes, making automated scanning essential.

trivy image labnow/core:python3.12-datascience-20241010

Configure Health Checks

Enable orchestrators to restart unhealthy containers by adding HEALTHCHECK instructions that verify runtime functionality. Simple checks like conda list or python -c "import pandas" ensure the scientific stack loads correctly.

Add to your Dockerfile or compose configuration:

HEALTHCHECK CMD python -c "import pandas"

Optimize CI/CD Layer Caching

Keep ARG_PROFILE_* variables stable across builds so Docker can reuse layers. Store profile lists in CI variables and pass them unchanged to minimize rebuild times.

Practical Implementation Examples

Running a Core AI Image with Jupyter

Deploy a fully-featured data science environment with JupyterLab exposed on port 8888:


# Pull the base + core image with Python, R, and Julia

docker pull labnow/core:python3.12-datascience-20241010

# Run it as a non-root user, expose Jupyter, and mount a workspace

docker run -d \
  --name labnow-ai \
  --user labnow \
  -p 8888:8888 \
  -v "$PWD/workspace:/opt/workspace" \
  -e JUPYTER_TOKEN=securetoken \
  labnow/core:python3.12-datascience-20241010 \
  jupyter lab --ip=0.0.0.0 --no-browser --NotebookApp.token=$JUPYTER_TOKEN

GPU-Enabled CUDA Workloads

For machine learning workloads requiring NVIDIA GPUs, use the CUDA-specific image:

docker pull labnow/cuda:nvidia-ctk-20241010

docker run -d \
  --gpus all \
  --name labnow-gpu \
  -p 8888:8888 \
  -v "$PWD/models:/opt/models" \
  labnow/cuda:nvidia-ctk-20241010 \
  jupyter notebook --ip=0.0.0.0 --no-browser

Cross-Registry Image Synchronization

Use Docker-Kit to sync images between registries, referencing the documentation in docker_docker_kit/README.md:

docker run --rm \
  -e DOCKER_REGISTRY_USERNAME=YOUR_USER \
  -e DOCKER_REGISTRY_PASSWORD=YOUR_PASS \
  -e DOCKER_MIRROR_REGISTRY_USERNAME=YOUR_MIRROR_USER \
  -e DOCKER_MIRROR_REGISTRY_PASSWORD=YOUR_MIRROR_PASS \
  labnow/docker-kit \
  python /opt/utils/image-syncer/run_sync.py library/ubuntu \
  --source-registry='quay.io' \
  --target-registry='docker.io'

Summary

  • Pin exact image tags like labnow/core:python3.12-datascience-20241010 to ensure reproducible deployments and prevent unexpected updates.
  • Run as the labnow user created in docker_base/Dockerfile to minimize security risks in production environments.
  • Mount persistent volumes for /opt/data and /opt/config to maintain state across container restarts.
  • Use Docker Compose to orchestrate multi-service stacks, particularly when combining Core images with PostgreSQL or other data stores.
  • Implement health checks using simple Python import statements to verify runtime integrity.
  • Scan images regularly for CVEs using Trivy, given the extensive binary footprint across Conda, Python, R, and Node.js runtimes.

Frequently Asked Questions

How do I choose between LabNow Base, Core, and Atom images for production?

Use the Base image (docker_base/Dockerfile) when you need a minimal Ubuntu foundation with Conda but plan to install custom runtimes yourself. Choose the Core image (docker_core/Dockerfile) for full data science stacks including Python, R, and Julia, controlled via ARG_PROFILE_* build arguments. Select the Atom image (docker_atom/Dockerfile) when you want the script-setup toolkit without the full language runtime suite, ideal for lightweight custom builds.

What security measures are built into LabNow Docker images?

The images implement defense in depth through multiple mechanisms. The docker_base/Dockerfile creates and switches to a labnow non-root user via USER labnow, reducing container escape risks. The script-setup toolkit installs packages from verified repositories only, and the layered architecture allows you to audit specific components like docker_atom/work/script-setup.sh before deployment.

How do I enable GPU support for LabNow AI containers?

Pull the CUDA-specific variant from the Specialized layer, such as labnow/cuda:nvidia-ctk-20241010, and run with the --gpus all flag. This image extends the Core layer with NVIDIA Container Toolkit support, enabling PyTorch and TensorFlow to access host GPUs while maintaining the same labnow user security model and Conda environment structure.

Can I customize which programming languages are installed in LabNow images?

Yes. The docker_core/Dockerfile accepts ARG variables including ARG_PROFILE_PYTHON, ARG_PROFILE_R, ARG_PROFILE_JAVA, and ARG_PROFILE_JULIA. By passing specific values at build time (e.g., --build-arg ARG_PROFILE_PYTHON=3.12), you control which language stacks install without rebuilding the entire Ubuntu base layer, optimizing both image size and build speed.

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 →