Skip to content

Local Containers

This guide is for contributor machines using either Docker or Podman. The lab/server workflow is separate because Yen uses Podman, Slurm, and Apptainer; see lab-containers.md.

The local setup keeps the same in-container paths as the lab setup:

  • repo checkout at /hct-tower
  • datasets at /data
  • runtime outputs at /artifacts

Keep /data and /artifacts outside the repo. The repo should contain code and documentation; large datasets, checkpoints, plots, tables, and evaluation outputs should be mounted in.

Use any host paths you like, but keep the three boundaries clear:

/absolute/path/to/hct-tower    repo checkout
/absolute/path/to/data         raw and processed datasets
/absolute/path/to/artifacts    checkpoints, plots, tables, figures, eval outputs

Replace those paths in the commands below with paths on your machine.

Choose A Local Path

Use the NVIDIA GPU path only when your local machine has an NVIDIA GPU and your container runtime is configured for GPU passthrough:

  • Docker: NVIDIA Container Toolkit with --gpus all
  • Podman: NVIDIA Container Toolkit/CDI with --device nvidia.com/gpu=all

If your local machine has no NVIDIA GPU, or GPU passthrough is not configured, use the CPU-only path. Docker infers the target architecture from the host by default. On amd64, the model image uses the CUDA-capable PyTorch base and can still run without a GPU device. On arm64, including Apple Silicon, it uses a CPU-only Python/PyTorch base. In CPU-only containers, torch.cuda.is_available() should return False.

For Podman on Apple Silicon, use the architecture-aware Dockerfile with -f Dockerfile. The default Containerfile is kept compatible with the older Podman version on the lab server and is intentionally amd64/server-oriented.

Local NVIDIA GPU

Model Image With Docker

Build from inside model/:

cd model
docker build -t hct-tower-model-cuda .

Create, start, and enter a reusable model container with GPU access:

docker create -it --name hct-tower-model-cuda \
  --gpus all \
  -v "/absolute/path/to/hct-tower:/hct-tower" \
  -v "/absolute/path/to/data:/data" \
  -v "/absolute/path/to/artifacts:/artifacts" \
  -w /hct-tower/model \
  hct-tower-model-cuda

docker start hct-tower-model-cuda
docker exec -it hct-tower-model-cuda bash

Model Image With Podman

Build from inside model/:

cd model
podman build -t hct-tower-model-cuda .

Create, start, and enter a reusable model container with GPU access:

podman create -it --name hct-tower-model-cuda \
  --device nvidia.com/gpu=all \
  -v "/absolute/path/to/hct-tower:/hct-tower" \
  -v "/absolute/path/to/data:/data" \
  -v "/absolute/path/to/artifacts:/artifacts" \
  -w /hct-tower/model \
  hct-tower-model-cuda

podman start hct-tower-model-cuda
podman exec -it hct-tower-model-cuda bash

GPU Check

Run this inside the model container:

python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"

For the GPU path, the CUDA availability check should print True.

Local CPU-Only

Use this path when your local machine has no NVIDIA GPU, or when Docker/Podman has not been configured for NVIDIA GPU passthrough. Use hct-tower-model-cuda on amd64 and hct-tower-model-cpu on Apple Silicon.

Model Image With Docker

Build from inside model/:

cd model
docker build -t hct-tower-model-cpu .

Create, start, and enter a reusable model container:

docker create -it --name hct-tower-model-cpu \
  -v "/absolute/path/to/hct-tower:/hct-tower" \
  -v "/absolute/path/to/data:/data" \
  -v "/absolute/path/to/artifacts:/artifacts" \
  -w /hct-tower/model \
  hct-tower-model-cpu

docker start hct-tower-model-cpu
docker exec -it hct-tower-model-cpu bash

On amd64, use hct-tower-model-cuda in the docker build, docker create, docker start, and docker exec commands above.

Model Image With Podman

Build from inside model/:

cd model
podman build -f Dockerfile -t hct-tower-model-cpu .

Create, start, and enter a reusable model container:

podman create -it --name hct-tower-model-cpu \
  -v "/absolute/path/to/hct-tower:/hct-tower" \
  -v "/absolute/path/to/data:/data" \
  -v "/absolute/path/to/artifacts:/artifacts" \
  -w /hct-tower/model \
  hct-tower-model-cpu

podman start hct-tower-model-cpu
podman exec -it hct-tower-model-cpu bash

On amd64, use hct-tower-model-cuda in the podman build, podman create, podman start, and podman exec commands above. For amd64 Podman, the build command can use the default Containerfile:

cd model
podman build -t hct-tower-model-cuda .

CPU Check

Run this inside the model container:

python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"

For the CPU-only path, the CUDA availability check should print False.

Local Analyses Container

The analyses image is CPU-only. It can be built and run with either Docker or Podman regardless of which model-container path you chose above.

With Docker, the analyses image follows the runtime target platform. amd64 builds use rocker/verse; native ARM builds use rocker/r-ver and let renv install the analyses packages. The native ARM build takes longer because more R packages are compiled during image creation, but it avoids amd64 emulation.

With Podman, use the default Containerfile on amd64, including Linux workstations. On Apple Silicon, use -f Dockerfile to get the native ARM build. The default Containerfile is kept compatible with the older Podman version on the lab server and is intentionally amd64/server-oriented.

Analyses Image With Docker

Build from inside analyses/:

cd analyses
docker build -t hct-tower-analyses-cpu .

Create, start, and enter a reusable analyses container:

docker create -it --name hct-tower-analyses-cpu \
  -v "/absolute/path/to/hct-tower:/hct-tower" \
  -v "/absolute/path/to/data:/data" \
  -v "/absolute/path/to/artifacts:/artifacts" \
  -w /hct-tower/analyses \
  hct-tower-analyses-cpu

docker start hct-tower-analyses-cpu
docker exec -it hct-tower-analyses-cpu bash

Analyses Image With Podman

Build from inside analyses/:

cd analyses
podman build -t hct-tower-analyses-cpu .

On Apple Silicon, build from the architecture-aware Dockerfile:

cd analyses
podman build -f Dockerfile -t hct-tower-analyses-cpu .

Create, start, and enter a reusable analyses container:

podman create -it --name hct-tower-analyses-cpu \
  -v "/absolute/path/to/hct-tower:/hct-tower" \
  -v "/absolute/path/to/data:/data" \
  -v "/absolute/path/to/artifacts:/artifacts" \
  -w /hct-tower/analyses \
  hct-tower-analyses-cpu

podman start hct-tower-analyses-cpu
podman exec -it hct-tower-analyses-cpu bash

Check the R runtime inside the analyses container:

Rscript --version

The analyses image is R-only and intentionally does not include the Python environment needed for shared.data.* pipeline commands. Build shared processed data and reusable about embeddings from the model environment when those files are missing or stale, then consume the resulting parquet files from analyses. If they already exist at the configured /data/... paths, there is no need to rebuild them.

Workflow Commands

After entering the model container, model and shared-data commands are documented in:

After entering the analyses container, analyses workflow commands are documented on the analyses landing page.

One-Off Commands

For quick checks, you can run commands without creating a named container.

Docker CPU-only example:

docker run --rm -it \
  -v "/absolute/path/to/hct-tower:/hct-tower" \
  -v "/absolute/path/to/data:/data" \
  -v "/absolute/path/to/artifacts:/artifacts" \
  -w /hct-tower/model \
  hct-tower-model-cuda \
  python -m training.train --config /hct-tower/model/config/config_samples.yaml

Use hct-tower-model-cpu instead of hct-tower-model-cuda on Apple Silicon.

Docker GPU example:

docker run --rm -it \
  --gpus all \
  -v "/absolute/path/to/hct-tower:/hct-tower" \
  -v "/absolute/path/to/data:/data" \
  -v "/absolute/path/to/artifacts:/artifacts" \
  -w /hct-tower/model \
  hct-tower-model-cuda \
  python -m training.train --config /hct-tower/model/config/config_samples.yaml

Podman CPU-only example:

podman run --rm -it \
  -v "/absolute/path/to/hct-tower:/hct-tower" \
  -v "/absolute/path/to/data:/data" \
  -v "/absolute/path/to/artifacts:/artifacts" \
  -w /hct-tower/model \
  hct-tower-model-cuda \
  python -m training.train --config /hct-tower/model/config/config_samples.yaml

Use hct-tower-model-cpu instead of hct-tower-model-cuda on Apple Silicon.

Podman GPU example:

podman run --rm -it \
  --device nvidia.com/gpu=all \
  -v "/absolute/path/to/hct-tower:/hct-tower" \
  -v "/absolute/path/to/data:/data" \
  -v "/absolute/path/to/artifacts:/artifacts" \
  -w /hct-tower/model \
  hct-tower-model-cuda \
  python -m training.train --config /hct-tower/model/config/config_samples.yaml