Skip to content
Merged
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
34 changes: 30 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,30 @@ RUN conda config --set ssl_verify false && \
conda config --set ssl_verify true

# Step 5: Make the environment available (simulate "conda activate spac")
# Set all necessary environment variables for conda activation
ENV CONDA_DEFAULT_ENV=${ENV_NAME}
ENV CONDA_PREFIX=/opt/conda/envs/${ENV_NAME}
ENV PATH=/opt/conda/envs/${ENV_NAME}/bin:${PATH}
ENV PYTHONPATH=/opt/conda/envs/${ENV_NAME}/lib/python3.9/site-packages:${PYTHONPATH}

# Step 6: "Install the SPAC package in development mode"
RUN /opt/conda/envs/${ENV_NAME}/bin/pip install -e .

# Make conda activate spac environment automatically in bash shells
RUN echo "source /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
echo "conda activate ${ENV_NAME}" >> ~/.bashrc

# Create a wrapper script that ensures conda environment is activated
# This helps when Galaxy runs commands directly
RUN echo '#!/bin/bash' > /usr/local/bin/conda-run && \
echo 'source /opt/conda/etc/profile.d/conda.sh' >> /usr/local/bin/conda-run && \
echo 'conda activate spac' >> /usr/local/bin/conda-run && \
echo 'exec "$@"' >> /usr/local/bin/conda-run && \
chmod +x /usr/local/bin/conda-run

# Set the shell to use bash for RUN commands
SHELL ["/bin/bash", "-c"]

# Set environment variables for headless notebook execution
ENV QT_QPA_PLATFORM=offscreen
ENV MPLBACKEND=Agg
Expand All @@ -76,13 +94,21 @@ RUN mkdir -p /workspace /data /results
# Install jupyter and nbconvert for notebook testing
RUN /opt/conda/envs/${ENV_NAME}/bin/pip install jupyter nbconvert

# Verify SPAC installation works correctly
# Verify SPAC installation works correctly in multiple ways
RUN echo "=== VERIFYING SPAC INSTALLATION ===" && \
/opt/conda/envs/${ENV_NAME}/bin/python -c "import spac; print(f'SPAC version: {spac.__version__}'); import scimap; print('All modules imported successfully!')" || \
echo "Some import issues detected but proceeding with test"
echo "Test 1: Direct python call" && \
python -c "import spac; print(f'SPAC version: {spac.__version__}')" && \
echo "Test 2: Which python" && \
which python && \
echo "Test 3: Python path" && \
python -c "import sys; print(sys.executable)" && \
echo "Test 4: Import scimap" && \
python -c "import scimap; print('scimap imported successfully')" && \
echo "=== ALL TESTS PASSED ===" || \
echo "Some import issues detected but proceeding"

# Set working directory for Jupyter (will be mounted via volume)
WORKDIR /workspace

# Default command starts Jupyter notebook server
CMD ["/opt/conda/envs/spac/bin/jupyter", "notebook", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root", "--NotebookApp.token=", "--NotebookApp.password="]
CMD ["/opt/conda/envs/spac/bin/jupyter", "notebook", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root", "--NotebookApp.token=", "--NotebookApp.password="]
87 changes: 87 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
.PHONY: help build run dev stop clean rebuild test

# Default target
help:
@echo "SPAC Docker Management"
@echo "======================"
@echo ""
@echo "Production targets:"
@echo " make build - Build production Docker image"
@echo " make run - Run production container with Jupyter"
@echo " make test - Run tests in production container"
@echo ""
@echo "Development targets:"
@echo " make dev - Start development environment with live code mounting"
@echo " make dev-bash - Start development container with bash shell"
@echo " make dev-test - Run tests in development mode"
@echo ""
@echo "Utility targets:"
@echo " make stop - Stop all running containers"
@echo " make clean - Remove containers and images"
@echo " make rebuild - Clean and rebuild production image"
@echo " make logs - Show container logs"

# Production build
build:
@echo "Building production Docker image..."
docker build -t spac:latest .

# Run production container
run:
@echo "Starting production container with Jupyter..."
docker run -d \
--name spac-prod \
-p 8888:8888 \
-v $(PWD)/data:/data \
-v $(PWD)/results:/results \
spac:latest
@echo "Jupyter available at http://localhost:8888"

# Development environment with live code mounting
dev:
@echo "Starting development environment with live code mounting..."
docker-compose -f docker/docker-compose.dev.yml up -d
@echo "Development Jupyter available at http://localhost:8889"
@echo "Source code is mounted - changes will be reflected immediately!"

# Development with bash shell
dev-bash:
@echo "Starting development container with bash shell..."
docker-compose -f docker/docker-compose.dev.yml run --rm --service-ports spac-dev bash

# Run tests in development mode
dev-test:
@echo "Running tests in development mode..."
docker-compose -f docker/docker-compose.dev.yml run --rm spac-dev \
/opt/conda/envs/spac/bin/pytest tests/ -v

# Run tests in production container
test:
@echo "Running tests in production container..."
docker run --rm spac:latest \
/opt/conda/envs/spac/bin/pytest tests/ -v

# Stop all containers
stop:
@echo "Stopping containers..."
-docker stop spac-prod 2>/dev/null || true
-docker-compose -f docker/docker-compose.dev.yml down 2>/dev/null || true

# Clean up containers and images
clean: stop
@echo "Cleaning up containers and images..."
-docker rm spac-prod 2>/dev/null || true
-docker rmi spac:latest 2>/dev/null || true
-docker-compose -f docker/docker-compose.dev.yml down -v 2>/dev/null || true

# Rebuild from scratch
rebuild: clean build
@echo "Rebuild complete!"

# Show logs
logs:
@echo "=== Production logs ==="
-docker logs spac-prod 2>/dev/null || echo "No production container running"
@echo ""
@echo "=== Development logs ==="
-docker-compose -f docker/docker-compose.dev.yml logs 2>/dev/null || echo "No development container running"
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@ conda config --set ssl_verify true

## Using SPAC with Docker

For a reproducible environment, you can use Docker to run SPAC:
For a reproducible environment, you can use Docker to run SPAC.

**📘 For detailed Docker documentation including development mode with live code mounting, see [`docker/README.md`](docker/README.md)**

**Quick commands:**
- Production: `make build` → `make run`
- Development: `make dev` (changes to `src/` reflected immediately!)
- Help: `make help`

### Build the Docker Image
```bash
Expand Down
98 changes: 98 additions & 0 deletions docker/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
FROM continuumio/miniconda3:24.3.0-0

# Build arguments
ARG ENV_NAME=spac

# Set labels
LABEL maintainer="FNLCR-DMAP"
LABEL description="SPAC - Single Cell Spatial Analysis Container (Development)"
LABEL version="0.9.0-dev"

# Install system dependencies including Chromium for Kaleido (ARM64 compatible)
RUN apt-get update && \
apt-get install -y --no-install-recommends \
git \
ca-certificates \
build-essential \
libgl1-mesa-glx \
libglib2.0-0 \
libsm6 \
libxext6 \
libxrender-dev \
libgomp1 \
libglu1-mesa \
xvfb \
&& rm -rf /var/lib/apt/lists/*

# Install Chromium for Kaleido visualization support (ARM64 compatible)
RUN apt-get update && \
apt-get install -y chromium && \
rm -rf /var/lib/apt/lists/*

# Set Chrome binary path for Kaleido
ENV CHROME_BIN=/usr/bin/chromium

# Install and configure libmamba solver
RUN conda install -n base -y conda-libmamba-solver && \
conda config --set solver libmamba

# Set up working directory
WORKDIR /home/reviewer/SCSAWorkflow

# Copy only environment setup files first (for better layer caching)
COPY environment.yml .

# Configure conda channels
RUN conda config --add channels https://fnlcr-dmap.github.io/scimap/ && \
conda config --add channels conda-forge && \
conda config --add channels ohsu-comp-bio && \
conda config --add channels leej3 && \
conda config --add channels bioconda

# Create the Conda environment
RUN conda config --set ssl_verify false && \
conda env create -f environment.yml && \
conda clean -afy && \
conda config --set ssl_verify true

# Make the environment available
ENV CONDA_DEFAULT_ENV=${ENV_NAME}
ENV PATH=/opt/conda/envs/${ENV_NAME}/bin:${PATH}

# Make conda activate spac environment automatically in bash shells
RUN echo "source /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
echo "conda activate ${ENV_NAME}" >> ~/.bashrc

# Copy setup.py and other necessary files for package installation
COPY setup.py .
COPY LICENSE .
COPY README.md .
COPY CHANGELOG.md .

# Create a minimal src directory structure for initial installation
# The actual source code will be mounted as a volume
RUN mkdir -p src/spac && \
touch src/spac/__init__.py

# Install the SPAC package in editable mode
# The source code will be mounted, so changes will be reflected
RUN /opt/conda/envs/${ENV_NAME}/bin/pip install -e .

# Set environment variables for headless execution
ENV QT_QPA_PLATFORM=offscreen
ENV MPLBACKEND=Agg

# Create working directories
RUN mkdir -p /workspace /data /results

# Install jupyter and nbconvert for notebook testing
RUN /opt/conda/envs/${ENV_NAME}/bin/pip install jupyter nbconvert

# Install development tools
RUN /opt/conda/envs/${ENV_NAME}/bin/pip install ipdb pytest-watch black flake8 isort

# Set working directory for Jupyter
WORKDIR /workspace

# Default command starts Jupyter notebook server
CMD ["/opt/conda/envs/spac/bin/jupyter", "notebook", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root", "--NotebookApp.token=", "--NotebookApp.password="]
Loading