Draft

This documentation is in draft and under active review. Figures for the Fall 2026 GPU reservation system are not yet published, and some pages describe behaviour that has not been verified against a primary source. Check with us before relying on anything here.

Customizing an Environment

Packages can be added to a standard image without building a custom one. Anything that installs into a member's own home directory is available to that member: Python packages, an R library, a private Jupyter kernel. Anything that installs into the operating system is not.

What Can Be Installed


Change Possible without a custom image?
Add a Python package for personal use Yes — into a virtual environment with its own kernel
Add an R package for personal use Yes — into a personal R library
Add a Jupyter kernel Yesipython kernel install --user
Add a system package (apt-get, a compiler, a system utility) No — this needs a custom image
Change the image for a whole course No — this is a custom image, or a different standard one

Installing Python Packages Into a Private Kernel


Install into a virtual environment rather than over the top of the course environment. Installing into the environment the course ships is how people break it.

Open a terminal from the notebook interface (File → New → Terminal), then:

# create a directory and a virtual environment inside it
mkdir mykernel
python3 -m venv mykernel

# activate it; pip now refers to the virtual environment's pip
source mykernel/bin/activate
which pip

pip install ipython ipykernel

Install the packages themselves:

pip install scrapy

Then register the environment as a Jupyter kernel and leave:

# confirm ipython is the virtual environment's copy before registering
which ipython

ipython kernel install --user --name=mykernel
deactivate

Refresh the notebook interface. mykernel now appears in the launcher, and a notebook created with it can import whatever was installed into it.

Libraries installed this way are available only to notebooks using that kernel. A notebook on the course kernel is unaffected by anything installed into a private one.

Installing R Packages


A personal library is created on first use of RStudio, from the RStudio Console:

dir.create("~/R")
dir.create("~/R/library")
.libPaths("~/R/library")

install.packages() then writes there rather than attempting the system library, which is not writable.

The Hard Boundary


There is no root and no sudo. Containers run unprivileged, under the member's own UID, in a per-user Kubernetes namespace, on a node shared with other people's containers. sudo apt-get install ... fails by design rather than through misconfiguration.

The container and the login node share a filesystem. A file written in one is visible in the other. Root inside a container would reach across that shared filesystem to files belonging to other people — which is why there is none.

Not available What works instead
sudo anything Nothing needs sudo; work happens in the member's own home directory
apt-get install a system package Put it in a custom image, where root is available at build time
Write to system directories Install into a virtual environment or a personal R library
Reach another user's container or namespace Share through the workspace's public/ or teams/ areas

Members keep full control of their own space. Installing Python packages, creating a Jupyter kernel, creating an R library, reading and writing anywhere they own, and managing their own pods with kubectl all work normally. → Kubernetes

A system-level package therefore means a custom image. Root is available inside a Dockerfile at build time — that is where USER root and apt-get belong — and the resulting image still runs as the member, not as root. Build time and run time are different moments: root is available while the image is being built, somewhere that is not our cluster; when that image is later launched here, it runs unprivileged, under the member's own UID, exactly like a standard image.

On this platform, "I need a system package" and "I need a custom image" are the same sentence.Building & Publishing a Custom Image

Course-wide needs are not per-user customizations. A package the whole class needs belongs in the course image rather than in 200 individual installations.

When It Breaks


Installing packages with pip or conda can break a local environment. Two recoveries, in increasing order of severity:

A clean notebook. Start a notebook on the Python3 (clean) kernel, which ignores everything in .local. If that fixes the symptom, .local is the cause: moving or deleting .local/lib resolves many cases, and occasionally .local/jupyter as well.

The manual resetter. At datahub.ucsd.edu, open the services dropdown and choose manual-resetter. It stops running servers, signs the account out and resets its profile, leaving files intact. → Sign-In & Session Problems

Neither recovery applies to the shared course grader account. A TA follows up in the course support ticket instead — the grader account carries the course's nbgrader state, and clearing its .local by hand can take grading with it. → Common Grading Failures & Recovery

Caveats & Limitations


Conda is unsettled: see the draft note above. Until it is resolved, the venv route documented here is the one we can support without qualification.

Personal installs count against the quota: everything above lands in the member's home directory, which is per-user and per-workspace and is not large. → Directories, Quotas & Cleaning Up

Support for per-individual customization is limited: minor customizations within a standard image are a supported feature, but ITS staff cannot debug an arbitrary package tree. Instructors and TPOCs can bring these to a 1:1 Consultation. → Getting Help


If you still have questions or need additional assistance, email us at datahub@ucsd.edu or submit a ticket to the ITS Service Desk.