diff --git a/Dockerfile b/Dockerfile index c40251c..41b2571 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,29 +1,35 @@ +# Use the official Python image from the Docker Hub FROM python:3.10 -# Add Tini -ENV TINI_VERSION v0.19.0 +# Add Tini, a minimal init system for containers +ENV TINI_VERSION=v0.19.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini RUN chmod +x /tini -# The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, -# COPY and ADD instructions that follow it in the Dockerfile. -# If the WORKDIR doesn’t exist, it will be created even if it’s not used -# in any subsequent Dockerfile instruction. +# Set the working directory inside the container WORKDIR /root/env -# Prevent running interactive config -ENV DEBIAN_FRONTEND noninteractive +# Prevent running interactive config during package installation +ENV DEBIAN_FRONTEND=noninteractive +# Install system dependencies and remove the package list +RUN apt-get update && \ + apt-get install -y \ + libgeos-dev \ + && rm -rf /var/lib/apt/lists/* + +# Copy the requirements file into the container COPY requirements.txt ./ +# Install Python dependencies RUN pip install --no-cache-dir --upgrade pip && \ pip install --no-cache-dir -r requirements.txt -RUN pip install jupyter -RUN pip install networkx -RUN pip install pandas -RUN pip install seaborn -RUN pip install basemap-data-hires -RUN pip install basemap +# Create a mount point for external volumes +VOLUME /root/env + +# Set the entrypoint to Tini +ENTRYPOINT ["/tini", "-g", "--"] -ENTRYPOINT ["/tini", "-g", "--"] \ No newline at end of file +# Default command to run when the container starts +CMD ["/bin/bash"] \ No newline at end of file diff --git a/dev/Dockerfile b/dev/Dockerfile deleted file mode 100644 index 2d03aa5..0000000 --- a/dev/Dockerfile +++ /dev/null @@ -1,25 +0,0 @@ -# Dockerfile for my PythonBuildEnv docker container - -FROM python:3.10 - -# The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, -# COPY and ADD instructions that follow it in the Dockerfile. -# If the WORKDIR doesn’t exist, it will be created even if it’s not used -# in any subsequent Dockerfile instruction. -WORKDIR /root/env - -# Prevent running interactive config -ENV DEBIAN_FRONTEND noninteractive - -COPY requirements.txt ./ - -RUN pip install --no-cache-dir --upgrade pip && \ - pip install --no-cache-dir -r requirements.txt - -RUN pip install jupyter - -# The VOLUME instruction creates a mount point with the specified name -# and marks it as holding externally mounted volumes from native host or other containers. -VOLUME /root/env - -CMD ["/bin/bash"] diff --git a/dev/buildenv.sh b/dev/buildenv.sh deleted file mode 100755 index ce7e720..0000000 --- a/dev/buildenv.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash - -set -e - -IMAGE_TAG=pybuildenv -IMAGE_ID=$(docker images --format "{{.ID}}" $IMAGE_TAG) - -USAGE="Usage: $0 COMMAND IMAGE_TAG\n" -USAGE+=" COMMAND is what you expect script to do:\n" -USAGE+=" build - Builds an image from a Dockerfile.\n" -USAGE+=" run - Runs a container.\n" -USAGE+=" killall - Stops and removes all running containers.\n" -USAGE+=" forcecleanall - Clean-up Docker.\n" - -if [[ $# -lt 1 ]]; then - echo>&2 "ERROR: Must specify the command" - printf "$USAGE" >&2 - exit 2 -fi - -[[ $(uname) -eq "Darwin" ]] && MODHACK="-v /lib/modules:/lib/modules:ro" || MODHACK="" - -function build { - echo "Building docker container" - docker build ./dev -t $IMAGE_TAG - - IMAGE_ID=$(docker images --format "{{.ID}}" $IMAGE_TAG) - echo "Container image id: $IMAGE_ID" - return 0 -} - -function run { - name=$(basename "`pwd`") - echo "Starting a container with the name $name using $IMAGE_TAG image..." - CONTAINER_ID=$(docker create --rm -it --name $name -v "$PWD":/root/env --entrypoint=/bin/bash --privileged $MODHACK --cap-add ALL $IMAGE_TAG) - docker start $CONTAINER_ID - echo "Started $CONTAINER_ID with the name $name" - - echo "Attaching to a container" - docker attach $CONTAINER_ID - return 0 -} - -function killall { - for container_id in $(docker ps -q --filter "ancestor=$IMAGE_TAG"); do - echo "$(docker kill $container_id) - stopped and removed" - done - - return 0 -} - -function forcecleanall { - for container in $(docker container ls --format "{{.ID}}"); do docker container kill $container; done - for container in $(docker container ls -a --format "{{.ID}}"); do docker container rm $container; done - for image in $(docker images --format "{{.ID}}"); do docker image rm --force $image; done - echo "Docker has been cleaned up" - return 0 -} - -case $1 in - build) - echo "Executing BUILD command..." - build "$@" - ;; - - run) - echo "Executing RUN command..." - run "$@" - ;; - - killall) - echo "Executing KILLALL command..." - killall "$@" - ;; - - forcecleanall) - echo "Executing FORCECLEANALL command..." - forcecleanall "$@" - ;; - - *) - echo>&2 "ERROR: Unknown command $1" - printf "$USAGE" >&2 - exit 2 - ;; -esac diff --git a/dev/requirements.txt b/dev/requirements.txt deleted file mode 100644 index 4088880..0000000 --- a/dev/requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -networkx -numpy -pandas -matplotlib -geopy -build -twine -pytest -pytest-cov -pytest-benchmark -pytest-mock -pylint -black diff --git a/requirements.txt b/requirements.txt index a7d645c..edb0e1a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,16 @@ geopy networkx numpy pandas -matplotlib \ No newline at end of file +matplotlib +build +twine +pytest +pytest-cov +pytest-benchmark +pytest-mock +pylint +black +jupyter +seaborn +basemap-data-hires +basemap \ No newline at end of file diff --git a/run.sh b/run.sh index 332ab53..fd038e7 100755 --- a/run.sh +++ b/run.sh @@ -2,15 +2,21 @@ set -e -IMAGE_TAG=ngraph +DEFAULT_IMAGE_TAG=ngraph +IMAGE_TAG=${2:-$DEFAULT_IMAGE_TAG} +DEFAULT_CONTAINER_NAME=ngraph_jupyter +CONTAINER_NAME=${3:-$DEFAULT_CONTAINER_NAME} IMAGE_ID=$(docker images --format "{{.ID}}" $IMAGE_TAG) -USAGE="Usage: $0 COMMAND IMAGE_TAG\n" -USAGE+=" COMMAND is what you expect script to do:\n" +USAGE="Usage: $0 COMMAND [IMAGE_TAG] [CONTAINER_NAME]\n" +USAGE+=" COMMAND is what you expect the script to do:\n" USAGE+=" build - Builds an image from a Dockerfile.\n" -USAGE+=" run - Runs a container.\n" -USAGE+=" killall - Stops and removes all running containers.\n" -USAGE+=" forcecleanall - Clean-up Docker.\n" +USAGE+=" run - Runs a container and starts Jupyter.\n" +USAGE+=" shell - Attaches to the shell of a running container.\n" +USAGE+=" killall - Stops and removes all running containers based on the image tag.\n" +USAGE+=" forcecleanall - WARNING: Stops and removes all containers and images. This action cannot be undone.\n" +USAGE+=" IMAGE_TAG is the optional Docker image tag (default: $DEFAULT_IMAGE_TAG).\n" +USAGE+=" CONTAINER_NAME is the optional Docker container name (default: $DEFAULT_CONTAINER_NAME).\n" if [[ $# -lt 1 ]]; then echo>&2 "ERROR: Must specify the command" @@ -21,7 +27,7 @@ fi [[ $(uname) -eq "Darwin" ]] && MODHACK="-v /lib/modules:/lib/modules:ro" || MODHACK="" function build { - echo "Building docker container" + echo "Building docker container with tag $IMAGE_TAG" docker build . -t $IMAGE_TAG IMAGE_ID=$(docker images --format "{{.ID}}" $IMAGE_TAG) @@ -30,18 +36,24 @@ function build { } function run { - name=ngraph_jupyter - echo "Starting a container with the name $name using $IMAGE_TAG image..." - CONTAINER_ID=$(docker create --rm -it --name $name -v "$PWD":/root/env -p 8787:8787 --entrypoint=/bin/bash --privileged $MODHACK --cap-add ALL $IMAGE_TAG) + echo "Starting a container with the name $CONTAINER_NAME using $IMAGE_TAG image..." + CONTAINER_ID=$(docker create --rm -it --name $CONTAINER_NAME -v "$PWD":/root/env -p 8787:8787 --entrypoint=/bin/bash --privileged $MODHACK --cap-add ALL $IMAGE_TAG) docker start $CONTAINER_ID - echo "Started $CONTAINER_ID with the name $name" + echo "Started $CONTAINER_ID with the name $CONTAINER_NAME" docker exec -it $CONTAINER_ID pip install -e . echo "Starting Jupyter in a container. Open http://127.0.0.1:8787/ in your browser." docker exec -it $CONTAINER_ID jupyter notebook --port=8787 --no-browser --ip=0.0.0.0 --allow-root --NotebookApp.token='' /root/env return 0 } +function shell { + echo "Attaching to the shell of the running container $CONTAINER_NAME..." + docker exec -it $CONTAINER_NAME /bin/bash + return 0 +} + function killall { + echo "Stopping and removing all running containers based on the image tag $IMAGE_TAG..." for container_id in $(docker ps -q --filter "ancestor=$IMAGE_TAG"); do echo "$(docker kill $container_id) - stopped and removed" done @@ -50,6 +62,13 @@ function killall { } function forcecleanall { + echo "WARNING: This will stop and remove all containers and images. This action cannot be undone." + read -p "Are you sure you want to proceed? (Y/N): " confirm + if [[ $confirm != [Yy] ]]; then + echo "Aborting forcecleanall." + return 1 + fi + for container in $(docker container ls --format "{{.ID}}"); do docker container kill $container; done for container in $(docker container ls -a --format "{{.ID}}"); do docker container rm $container; done for image in $(docker images --format "{{.ID}}"); do docker image rm --force $image; done @@ -68,6 +87,11 @@ case $1 in run "$@" ;; + shell) + echo "Executing SHELL command..." + shell "$@" + ;; + killall) echo "Executing KILLALL command..." killall "$@" @@ -83,4 +107,4 @@ case $1 in printf "$USAGE" >&2 exit 2 ;; -esac +esac \ No newline at end of file