Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/workflows/container-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Build and Publish Container Images

on:
push:
branches:
- master
- main
tags:
- 'v*'
pull_request:
branches:
- master
- main
workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Free up disk space
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf /usr/local/share/boost
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
docker system prune -af

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push container image
id: build
uses: docker/build-push-action@v5
with:
context: .
file: Containerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64

- name: Generate artifact attestation
if: github.event_name != 'pull_request'
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true
115 changes: 115 additions & 0 deletions CONTAINER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Container Images

CDTools is available as a container image on GitHub Container Registry (ghcr.io). The image includes PyTorch with CUDA support and automatically uses GPU acceleration when available, or falls back to CPU mode on systems without GPUs (like Macs).

## Available Image

- **Universal image**: `ghcr.io/als-computing/cdtools:latest`
- ~3GB with CUDA support
- Auto-detects and uses GPU when available
- Falls back to CPU on Macs and systems without GPUs

## Quick Start

### Using with Podman

```bash
# Pull the image
podman pull ghcr.io/als-computing/cdtools:latest

# Run in CPU mode (no GPU flags needed)
podman run -it ghcr.io/als-computing/cdtools:latest

# Run with GPU support (Linux with NVIDIA GPU - requires nvidia-container-toolkit)
podman run --device nvidia.com/gpu=all -it ghcr.io/als-computing/cdtools:latest

# Run an example (CPU mode)
podman run -it ghcr.io/als-computing/cdtools:latest \
python examples/simple_ptycho.py
```

### Using with Docker

```bash
# Pull the image
docker pull ghcr.io/als-computing/cdtools:latest

# Run in CPU mode (no GPU flags needed - works on Mac too)
docker run -it ghcr.io/als-computing/cdtools:latest

# Run with GPU support (Linux with NVIDIA GPU - requires NVIDIA Container Toolkit)
docker run --gpus all -it ghcr.io/als-computing/cdtools:latest

# Run an example (CPU mode)
docker run -it ghcr.io/als-computing/cdtools:latest \
python examples/simple_ptycho.py
```

## Mounting Data

To work with your own data files:

```bash
# With Podman (Linux with GPU)
podman run -v /path/to/your/data:/data:z \
--device nvidia.com/gpu=all -it \
ghcr.io/als-computing/cdtools:latest \
python -c "from cdtools.datasets import Ptycho2DDataset; dataset = Ptycho2DDataset.from_cxi('/data/your_file.cxi')"

# With Docker (Linux with GPU)
docker run -v /path/to/your/data:/data \
--gpus all -it \
ghcr.io/als-computing/cdtools:latest \
python -c "from cdtools.datasets import Ptycho2DDataset; dataset = Ptycho2DDataset.from_cxi('/data/your_file.cxi')"

# Without GPU (Podman or Docker)
podman run -v /path/to/your/data:/data:z -it ghcr.io/als-computing/cdtools:latest
docker run -v /path/to/your/data:/data -it ghcr.io/als-computing/cdtools:latest
```

## Interactive Development

```bash
# Start an interactive Python session
podman run -it ghcr.io/als-computing/cdtools:latest

# Start with a bash shell
podman run -it --entrypoint bash ghcr.io/als-computing/cdtools:latest
```

## Version Tags

Images are tagged with:
- `latest` - Latest stable release
- `v0.3.1` - Specific version
- `master` - Latest from master branch

## Platform Support

The image works on:
- ✅ **Linux with NVIDIA GPU** - Full CUDA acceleration
- ✅ **Linux without GPU** - CPU mode (automatic fallback)
- ✅ **macOS (Intel/Apple Silicon)** - CPU mode (automatic fallback)
- ✅ **Windows with WSL2** - GPU or CPU mode

## Image Size

- **Universal image**: ~3.0 GB (includes CUDA libraries for GPU support)

## Building Locally

To build the image locally:

```bash
# Using Podman
podman build -t cdtools:local .

# Using Docker
docker build -t cdtools:local .
```

## Requirements

- **For GPU support**: NVIDIA GPU with CUDA support and nvidia-container-toolkit
- **For CPU mode**: No special requirements (works on any system)
- **Mac users**: The image works out of the box in CPU mode
37 changes: 37 additions & 0 deletions Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Multi-stage build for CDTools - Python library for ptychography and CDI reconstructions
FROM python:3.11-slim as builder

# Set working directory
WORKDIR /build

# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
g++ \
&& rm -rf /var/lib/apt/lists/*

# Copy project files
COPY pyproject.toml setup.py requirements.txt README.md ./
COPY src/ ./src/
COPY examples/ ./examples/

# Install Python dependencies
RUN pip install --no-cache-dir --upgrade pip setuptools wheel && \
pip install --no-cache-dir .

# Final stage - lightweight runtime image
FROM python:3.11-slim

# Set working directory
WORKDIR /app

# Copy installed packages from builder
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin

# Copy source code (optional, for development)
COPY src/ ./src/

# Set Python to run in unbuffered mode
ENV PYTHONUNBUFFERED=1