Bootstrap: docker
From: python:3.11-slim

# ---------------------------------------------------------------
# Copy project files (runs on the host before %post is executed)
# ---------------------------------------------------------------
%setup
mkdir -p "${SINGULARITY_ROOTFS}/opt/app"
cp "requirements.txt"  "${SINGULARITY_ROOTFS}/opt/app/requirements.txt"
cp "kernel_api.py"     "${SINGULARITY_ROOTFS}/opt/app/kernel_api.py"
cp "start_kernel.py"   "${SINGULARITY_ROOTFS}/opt/app/start_kernel.py"
cp "start.sh"          "${SINGULARITY_ROOTFS}/opt/app/start.sh"
cp "offline_kernel.py"   "${SINGULARITY_ROOTFS}/opt/offline_kernel.py"

# ---------------------------------------------------------------
# Build steps executed INSIDE the container
# ---------------------------------------------------------------
%post
export DEBIAN_FRONTEND=noninteractive

# --- 1 ▸ System packages ---------------------------------------
apt-get update && apt-get install -y --no-install-recommends \
    tini tzdata build-essential pkg-config libhdf5-dev libsodium-dev \
    libzmq3-dev gcc g++ sudo curl wget git vim nano unzip zip && \
    ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime && \
    dpkg-reconfigure --frontend noninteractive tzdata && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

# --- 2 ▸ Non‑root user ----------------------------------------
NB_USER="sandboxuser"
NB_UID=1001
NB_GID=1001
groupadd  -g "$NB_GID" "$NB_USER"
useradd   -m -s /bin/bash -u "$NB_UID" -g "$NB_GID" "$NB_USER"
echo "$NB_USER ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

# --- 3 ▸ Python dependencies -----------------------------------
pip install --no-cache-dir --upgrade pip
pip install --no-cache-dir -r /opt/app/requirements.txt

# --- 4 ▸ Permissions & executables -----------------------------
chown -R "$NB_USER:$NB_GID" /opt/app
chmod +x /opt/app/start_kernel.py /opt/app/start.sh

chown "$NB_USER:$NB_GID" /opt/offline_kernel.py
chmod +x /opt/offline_kernel.py

# ---------------------------------------------------------------
# Runtime environment
# ---------------------------------------------------------------
%environment
export DEBIAN_FRONTEND=noninteractive
export USER=sandboxuser
export HOME=/home/sandboxuser
export PATH=$HOME/.local/bin:$PATH
export IPY_BASE_PORT=4000

# ---------------------------------------------------------------
# What happens on ‘apptainer run …’
# ---------------------------------------------------------------
%runscript
exec /usr/bin/tini -- /opt/app/start.sh "$@"

# Optional: behaviour for ‘apptainer instance start …’
%startscript
exec /usr/bin/tini -- /opt/app/start.sh "$@"