Use the postBuild.bash Script#

Overview#

The postBuild.bash script runs after packages install during the container build.

Use it to configure installed software and set up development tools. Commands run automatically when you rebuild the container.

Use postBuild.bash to configure the container after packages install.

Install software from source, configure JupyterLab, or persist IDE servers. Packages from requirements.txt and apt.txt are already installed at this point.

The script runs as the container user with passwordless sudo access.

You can install system packages, modify permissions, and configure services. Changes persist across container restarts because they’re baked into the image.

The build context is separate from the project repository.

The script cannot access files in the /project/ directory during build. Install from external sources like GitHub, PyPI, or URLs instead.

Key Concepts#

postBuild.bash

Optional bash script in the project root that runs after package installation. Used for final configuration and customization.

Build Order

Container build follows: base image –> preBuild.bash –> package installation –> postBuild.bash –> runtime.

Build Context

Separate folder containing only the containerfile, package files, and build scripts. Does not include project files, so the script cannot access /project/ during build.

Passwordless Sudo

The script can run commands with sudo without password prompts. Allows system-level changes during the build.

Edit postBuild.bash in the Desktop App#

Step One: Open the script editor.
  1. Select Project Tab > Project Container > Scripts

  2. Select postBuild.bash

  3. Select Edit Script

Step Two: Add your commands to the script.
  1. Type or paste your bash commands in the editor

  2. Select Save

Step Three: Rebuild the container to apply changes.
  1. Select Project Tab > Project Container > Start Build

Success: The container rebuilds with your script changes applied.

Edit postBuild.bash Directly#

Step One: Open the script file in your project root.
  1. Open postBuild.bash in any text editor

Step Two: Add your commands to the script.
  1. Write bash commands in the file

  2. Save the file

Step Three: Rebuild the container.
  1. Select Project Tab > Project Container > Start Build

Success: The container rebuilds with your script changes applied.

What postBuild.bash Can and Cannot Access#

The script CANNOT access the following.
  • Files in the project repository (anything in /project/)

  • Environment variables defined in variables.env

  • Data files or models in your project

The script CAN access the following.
  • System package managers (apt, yum, etc.)

  • Python package managers (pip, conda)

  • External resources (GitHub, PyPI, URLs with curl/wget)

  • System directories and files being created during the build

  • Build-time environment variables you set in the script itself

  • Packages already installed from requirements.txt and apt.txt

Common Mistakes to Avoid#

Don’t try to copy files from /project/

This will fail because /project/ doesn’t exist during build:

# This FAILS
cp /project/my-config.yaml /opt/app/
Don’t reference environment variables from variables.env

These aren’t set during the build:

# This FAILS
echo $MY_CUSTOM_VAR  # Variable from variables.env

Workarounds#

Install from external sources instead

Download from GitHub or other external locations:

# Install a Python package from GitHub
pip install git+https://github.com/user/repo.git
Copy files at runtime instead of build time

Use mounts or copy files after the container starts. See Configure Runtime Settings for details.

Use Cases for postBuild.bash#

To persist VS Code, Cursor, or other IDE servers, see the IDE-specific guides.

Add R and Julia kernels to JupyterLab for multi-language notebook support.

#!/bin/bash
set -e

# Install R and the R kernel for Jupyter
echo "Installing R and IRkernel..."
sudo apt-get update
sudo apt-get install -y r-base r-base-dev

# Install IRkernel from CRAN
sudo R -e "install.packages('IRkernel', repos='https://cloud.r-project.org/')"
sudo R -e "IRkernel::installspec(user = FALSE)"

# Install Julia
echo "Installing Julia..."
JULIA_VERSION="1.9.3"
cd /tmp
wget https://julialang-s3.julialang.org/bin/linux/x64/1.9/julia-${JULIA_VERSION}-linux-x86_64.tar.gz
sudo tar -xzf julia-${JULIA_VERSION}-linux-x86_64.tar.gz -C /opt/
sudo ln -s /opt/julia-${JULIA_VERSION}/bin/julia /usr/local/bin/julia
rm julia-${JULIA_VERSION}-linux-x86_64.tar.gz

# Install IJulia kernel
echo "Installing IJulia kernel..."
julia -e 'using Pkg; Pkg.add("IJulia")'

echo "Kernels installed successfully"

Install software not available through package managers.

#!/bin/bash
set -e

# Install custom software from source
cd /tmp
git clone https://github.com/example/tool.git
cd tool
sudo make install
cd /
sudo rm -rf /tmp/tool

Compile libraries that need headers from installed packages.

#!/bin/bash
set -e

# Compile custom extension that needs numpy headers
cd /tmp
git clone https://github.com/example/custom-extension.git
cd custom-extension
python setup.py build_ext --inplace
pip install .
cd /
rm -rf /tmp/custom-extension

Clean up build artifacts to reduce image size.

#!/bin/bash
# Remove cached package data
sudo apt-get clean
sudo rm -rf /var/lib/apt/lists/*
pip cache purge

Best Practices#

Use set -e for error handling

Exit immediately if any command fails:

#!/bin/bash
set -e
Add comments to explain complex operations

Document what your script does:

# Install custom ML framework from source
# Required for GPU acceleration on this specific hardware
Use absolute paths for file operations

Avoid issues with working directories:

sudo mkdir -p /opt/myapp
# Not: mkdir -p myapp
Clean up temporary files

Reduce image size by removing build artifacts:

sudo apt-get clean
sudo rm -rf /var/lib/apt/lists/*
Test scripts in isolation when possible

Run commands manually in a container to verify they work before adding to scripts.