> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/ai-workbench/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/ai-workbench/_mcp/server.

# 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.**

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 --> completed image.
The `onStart.bash` script runs later, each time a container starts from that image.

**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 (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:

```bash
# This FAILS
cp /project/my-config.yaml /opt/app/
```

**Don't reference environment variables from variables.env**

These aren't set during the build:

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

### Workarounds

**Install from external sources instead**

Download from GitHub or other external locations:

```bash
# 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](/ai-workbench/how-to/environments/runtime-configuration) for details.

## Use Cases for postBuild.bash

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

- [Persist VS Code in the Container](/ai-workbench/how-to/ides/vs-code)
- [Persist Cursor in the Container](/ai-workbench/how-to/ides/cursor)

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

> ```bash
> #!/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.**

> ```bash
> #!/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.**

> ```bash
> #!/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.**

> ```bash
> #!/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:

```bash
#!/bin/bash
set -e
```

**Add comments to explain complex operations**

Document what your script does:

```bash
# 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:

```bash
sudo mkdir -p /opt/myapp
# Not: mkdir -p myapp
```

**Clean up temporary files**

Reduce image size by removing build artifacts:

```bash
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.

## Related Topics

- [Use the preBuild.bash Script](/ai-workbench/how-to/environments/prebuild-script) - Set up the environment before package installation
- [Use the onStart.bash Script](/ai-workbench/how-to/environments/onstart-script) - Initialize the running container at each start
- [Package Management](/ai-workbench/how-to/environments/package-management) - Add packages to your container
- [Configure Runtime Settings](/ai-workbench/how-to/environments/runtime-configuration) - Set environment variables and mounts
- [Use a Custom Container](/ai-workbench/how-to/use-custom-container) - Use your own base image
- [VS Code](/ai-workbench/how-to/ides/vs-code) - Configure VS Code with AI Workbench
- [Cursor](/ai-workbench/how-to/ides/cursor) - Configure Cursor with AI Workbench