diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..bd99046 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,94 @@ +# Project specific +data/ +images/ +figures/ +site/ +docs/images/ +tests/ + +# Git +.git +.gitignore + +# CI +.codeclimate.yml +.travis.yml +.taskcluster.yml + +# Docker +docker-compose.yml +.docker + +# Byte-compiled / optimized / DLL files +__pycache__/ +**/__pycache__/ +**/*.py[cod] +**/*.pyc + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.cache +nosetests.xml +coverage.xml + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Virtual environment +.env/ +.venv/ +venv/ + +# IDEs +.idea +.vscode + +# Python mode for VIM +.ropeproject +**/.ropeproject + +# Vim swap files +*.swp +**/*.swp \ No newline at end of file diff --git a/.gitignore b/.gitignore index 506c5b2..e0a4d57 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ data figures plots +images # IDEs .vscode diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..aa40877 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +# Build image with multi-stage builds +# Ensures image is built faster and smaller +FROM python:3.8-slim AS compile-image +RUN apt-get update +RUN apt-get install -y --no-install-recommends build-essential gcc + +# Install with pip‘s --user option, so all files will be installed in +# the .local directory of the current user’s home directory +COPY . /ColonyScanalyser +WORKDIR /ColonyScanalyser +RUN pip install --user . + +# Copy compiled artefacts to fresh image, without compiler baggage +FROM python:3.8-slim AS build-image +COPY --from=compile-image /root/.local /root/.local + +# Make sure scripts in .local are usable: +ENV PATH=/root/.local/bin:$PATH + +# Return help if no arguments are passed to ColonyScanalyser +ENTRYPOINT ["colonyscanalyser"] +CMD ["-h"] \ No newline at end of file diff --git a/README.md b/README.md index 07b3445..24a3a62 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ The remaining Python package dependencies are automatically handled by Pip when -Optionally use a virtual environment, such as [Pipenv](https://github.com/pypa/pipenv). +Optionally use a virtual environment, such as [Pipenv](https://github.com/pypa/pipenv), or a [containerised instance of the package](https://hub.docker.com/r/erikwhite/colonyscanalyser). For testing: * [Pytest](https://pytest.org/) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 0f2af8b..ec9526b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.4.1] - 2020-05-11 +### Added +- Dockerfile and utility scripts +- Docker image is now available: https://hub.docker.com/r/erikwhite/colonyscanalyser ## [0.4.0] - 2020-03-26 ### Added - `plate_labels` command line argument diff --git a/docs/installation.md b/docs/installation.md index 197c296..3bbdba1 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -48,4 +48,14 @@ Then run the ColonyScanalyser package: pipenv run scanalyser /path/to/images ``` -[More detailed instructions](https://packaging.python.org/tutorials/managing-dependencies/) can be found on the Python packaging site. \ No newline at end of file +[More detailed instructions](https://packaging.python.org/tutorials/managing-dependencies/) can be found on the Python packaging site. + +## Docker +The image is available on [Docker Hub](https://hub.docker.com/r/erikwhite/colonyscanalyser). + +Alternatively, you can build the image yourself using the Dockerfile included with the package. The container can be built by running `docker-build.sh` in the `scripts` directory. + +`scripts/docker-run.sh` is an example of how to use a containerised instance of ColonyScanalyser to analyse images in a directory on the host machine. Run the script as you normally would ColonyScanalyser, passing it the target image directory followed by any other command line arguments: +``` +scripts/docker-run.sh /absolute/path/to/images/ --verbose 3 --plate_size 100 +``` \ No newline at end of file diff --git a/scripts/docker-build.sh b/scripts/docker-build.sh new file mode 100755 index 0000000..b82adb7 --- /dev/null +++ b/scripts/docker-build.sh @@ -0,0 +1,2 @@ +# Create a containerised image of ColonyScanalyser +docker build --pull --rm -f "./Dockerfile" -t colonyscanalyser:latest "." \ No newline at end of file diff --git a/scripts/docker-run.sh b/scripts/docker-run.sh new file mode 100755 index 0000000..bcdd810 --- /dev/null +++ b/scripts/docker-run.sh @@ -0,0 +1,21 @@ +# Use a containerised instance of ColonyScanalyser to analyse +# a directory of images in the host system +# +# Pass the directory path to this script, followed by any +# other command line arguments for ColonyScanalyser +# The directory path must be absolute, not relative +# +# Example: +# docker-run.sh /path/to/images/ --verbose 5 --plate_size 100 + +# Store images directory and mount in docker image +# Shift remaining arguments and pass to ColonyScanalyser +img_dir="$1" +shift +# Run ColonyScanalyser on the images in the mounted directory +docker run \ + --rm \ + --name colonyscanalyser \ + --mount type=bind,source=$img_dir,target=/data \ + colonyscanalyser /data \ + $@ \ No newline at end of file diff --git a/setup.py b/setup.py index b4f23ff..5472385 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ def read(*names, **kwargs): setup( python_requires = ">=3.7", name = "colonyscanalyser", - version = "0.4.0", + version = "0.4.1", description = "An image analysis tool for measuring microorganism colony growth", long_description = "%s\n%s" % ( re.compile("^.. start-badges.*^.. end-badges", re.M | re.S).sub("", read("README.md")),