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
112 changes: 112 additions & 0 deletions Docker/DOCKERFILE_MERGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Dockerfile Consolidation - Issue #115 Task #4

## Overview

This document describes the consolidation of two separate Dockerfiles into a single unified Dockerfile that supports both standalone and Kaapana deployment.

## Problem

Previously maintained two separate Dockerfiles:

1. `Docker/Dockerfile` - Standalone IVIM fitting
2. `kaapana_ivim_osipi/.../Dockerfile` - Kaapana deployment

This created:

- Code duplication
- Maintenance overhead
- Inconsistent updates

## Solution

Created `Docker/Dockerfile.unified` using **Docker multi-stage builds** with named stages:

- `base` - Common dependencies shared by both environments
- `standalone` - Standalone IVIM fitting stage (target)
- `kaapana` - Kaapana deployment stage (target)

### Why Multi-Stage?

Following reviewer feedback, this approach:
Eliminates conditional `if` statements for cleaner code
Makes the build flow easier to follow
Allows Docker to better cache and optimize layers
Each stage is self-contained and easier to debug

### Build Arguments

| Argument | Default | Purpose |
| ------------ | ------------------ | --------------------------------------------- |
| `BASE_IMAGE` | `python:3.11-slim` | Specify base Docker image |
| `--target` | (required) | Choose build stage: `standalone` or `kaapana` |

## Building

### Standalone Build

Method 1: Using build script
./Docker/build-standalone.sh

Method 2: Direct docker command
docker build --target standalone
-t ivim-fitting:standalone
-f Docker/Dockerfile.unified .

### Kaapana Build

Method 1: Using build script
./Docker/build-kaapana.sh

Method 2: Direct docker command
docker build --target kaapana
--build-arg BASE_IMAGE=local-only/base-python-cpu:latest
-t ivim-fitting:kaapana
-f Docker/Dockerfile.unified .

## Testing Completed

### Local Testing (Docker Desktop - Windows)

- [x] Standalone build succeeds (13.2GB, ID: 75a626d42f0b)
- [x] Kaapana build succeeds (14GB, ID: f662fb55bfee)
- [x] Both conditional logic statements work correctly
- [x] File copying and dependencies install without errors
- [x] Build scripts execute correctly

### Integration Testing (Requires Kaapana Platform)

- [ ] Runtime with actual `local-only/base-python-cpu:latest` base image
- [ ] Volume mounts work (`OPERATOR_IN_DIR`, `OPERATOR_OUT_DIR`)
- [ ] MinIO data integration
- [ ] Airflow DAG execution in Kaapana UI
- [ ] Workflow submission through web interface

## Files Modified/Added

| File | Change | Type |
| ---------------------------- | --------------------------- | ---- |
| `Docker/Dockerfile.unified` | New unified Dockerfile | New |
| `Docker/build-standalone.sh` | Build script for standalone | New |
| `Docker/build-kaapana.sh` | Build script for Kaapana | New |
| `Docker/DOCKERFILE_MERGE.md` | This documentation | New |

## Notes for Reviewers

### What I Could Test

Docker build process for both environments
Image creation and basic structure
Build argument passing
Entry point configuration

### What Needs Your Testing

Runtime behavior in actual Kaapana deployment
Compatibility with Kaapana base image
Workflow execution through Kaapana UI
Data pipeline with MinIO

## Related Issues

- Addresses #115 (Task #4)
- Related to PR #112
85 changes: 85 additions & 0 deletions Docker/Dockerfile.unified
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Multi-Stage Unified Dockerfile for IVIM Fitting Method

# Supports both standalone and Kaapana deployment using multi-stage builds.
# This approach is cleaner than using if statements throughout.
#
# BUILD COMMANDS:
# Note: Run from PROJECT ROOT, not from Docker/ folder!
#
# For standalone:
# $ docker build --target standalone -t ivim-fitting:standalone -f Docker/Dockerfile.unified .
#
# For Kaapana:
# $ docker build --target kaapana \
# --build-arg BASE_IMAGE=local-only/base-python-cpu:latest \
# -t ivim-fitting:kaapana \
# -f Docker/Dockerfile.unified .
#

# Build argument for base image (default for standalone)
ARG BASE_IMAGE=python:3.11-slim

# Stage: BASE - Common setup shared by both environments
FROM ${BASE_IMAGE} AS base

# Metadata labels
LABEL IMAGE="ivim-fitting-method"
LABEL VERSION="0.2.4"
LABEL BUILD_IGNORE="False"

# Install common system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*

# Stage: STANDALONE - For standalone IVIM fitting
FROM base AS standalone

WORKDIR /usr/src/app

# Copy requirements and source code
COPY requirements.txt ./
COPY WrapImage ./WrapImage/

# Install Python dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Create entrypoint script
RUN echo '#!/bin/bash' > /entrypoint.sh && \
echo 'cd /usr/src/app' >> /entrypoint.sh && \
echo 'exec python3 -m WrapImage.nifti_wrapper "$@"' >> /entrypoint.sh && \
chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
CMD []

# Stage: KAAPANA - For Kaapana platform deployment
FROM base AS kaapana

# Install additional Kaapana dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
texlive-xetex \
texlive-fonts-recommended \
texlive-plain-generic \
git && \
apt-get clean && rm -rf /var/lib/apt/lists/*

WORKDIR /kaapana/app

# Clone IVIM code collection and install dependencies
RUN git clone https://github.com/OSIPI/TF2.4_IVIM-MRI_CodeCollection.git && \
cd TF2.4_IVIM-MRI_CodeCollection && \
pip install --no-cache-dir -r requirements.txt

# Set final working directory
WORKDIR /kaapana/app/TF2.4_IVIM-MRI_CodeCollection

# Create entrypoint script
RUN echo '#!/bin/bash' > /entrypoint.sh && \
echo 'cd /kaapana/app/TF2.4_IVIM-MRI_CodeCollection' >> /entrypoint.sh && \
echo 'exec python3 -u -m WrapImage.nifti_wrapper_kaapana "$@"' >> /entrypoint.sh && \
chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
CMD []
17 changes: 17 additions & 0 deletions Docker/build-kaapana.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
set -e

echo "📦 Building IVIM Fitting for KAAPANA (multi-stage)..."
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

docker build \
--target kaapana \
--build-arg BASE_IMAGE=local-only/base-python-cpu:latest \
-t ivim-fitting:kaapana \
-f Docker/Dockerfile.unified \
.

echo ""
echo "Build successful!"
echo "Image: ivim-fitting:kaapana"
docker images | grep "ivim-fitting.*kaapana"
16 changes: 16 additions & 0 deletions Docker/build-standalone.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash
set -e

echo "📦 Building IVIM Fitting for STANDALONE (multi-stage)..."
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

docker build \
--target standalone \
-t ivim-fitting:standalone \
-f Docker/Dockerfile.unified \
.

echo ""
echo "Build successful!"
echo "Image: ivim-fitting:standalone"
docker images | grep "ivim-fitting.*standalone"