To customize an image you generally want to create a new one using the existing image as a base. In Docker it is extremely common to create custom images when existing ones don't quite do what you want. By basing your images off public ones you can add your own customizations without having to repeat (or even know) what the base image does.
Add the necessary steps to a new Dockerfile.
FROM tensorflow/tensorflow:latest-gpu-jupyter RUN <extra install steps> COPY <extra files>RUNandCOPYare examples of instructions you might use.RUNwill run a command of your choosing such asRUN pip install matplotlib.COPYis used to add new files from your machine to the image, such as a configuration file.Build and tag the new image. Give it a new name of your choosing. I'll call it
my-customized-tensorflow, but you can name it anything you like.Assuming the
Dockerfileis in the current directory, rundocker build:$ docker build -t my-customized-tensorflow .Now you can use
my-customized-tensorflowas you would any other image.$ docker run my-customized-tensorflow
» pip install docker
Videos
To customize an image you generally want to create a new one using the existing image as a base. In Docker it is extremely common to create custom images when existing ones don't quite do what you want. By basing your images off public ones you can add your own customizations without having to repeat (or even know) what the base image does.
Add the necessary steps to a new Dockerfile.
FROM tensorflow/tensorflow:latest-gpu-jupyter RUN <extra install steps> COPY <extra files>RUNandCOPYare examples of instructions you might use.RUNwill run a command of your choosing such asRUN pip install matplotlib.COPYis used to add new files from your machine to the image, such as a configuration file.Build and tag the new image. Give it a new name of your choosing. I'll call it
my-customized-tensorflow, but you can name it anything you like.Assuming the
Dockerfileis in the current directory, rundocker build:$ docker build -t my-customized-tensorflow .Now you can use
my-customized-tensorflowas you would any other image.$ docker run my-customized-tensorflow
Add this to your Dockerfile after pulling the image:
RUN python -m pip install matplotlib
» pip install docker-py
During development it is IMO perfectly fine to map/mount the hostdirectory with your ever changing sources into the Docker container. The rest (the python version, the other libraries you are dependent upon you can all install in the normal way in the the docker container.
Once stabilized I remove the map/mount and add the package to the list of items to install with pip. I do have a separate container running devpi so I can pip-install packages whether I push them all the way to PyPI or just push them to my local devpi container.
Doing speed up container creation even if you use the common (but more limited) python [path_to_project/setup.py] develop. Your Dockerfile in this case should look like:
# the following seldom changes, only when a package is added to setup.py
COPY /some/older/version/of/project/plus/dependent/packages /older/setup
RUN pip /older/setup/your_package.tar.gz
# the following changes all the time, but that is only a small amount of work
COPY /latest/version/of/project
RUN python [path_to_project/setup.py] develop
If the first copy would result in changes to files under /older/setup then the container gets rebuilt from there.
Running python ... develop still makes more time and you need to rebuild/restart the container. Since my packages all can also be just copied in/linked to (in addition to be installed) that is still a large overhead. I run a small program in the container that checks if the (mounted/mapped) sources change and then reruns anything I am developing/testing automatically. So I only have to save a new version and watch the output of the container.
For deployment/distribution, it would be seamless to have a docker image for your package. If not as an image, you need to transfer you source code to the environment where it needs to be run, configure a volume to have the source inside container so that it can be built etc., With image its just pull and run a container out of it.
But for ease and to get rid of manual steps in building the image, consider using docker-compose.
docker-compose.yml may look like this:
ml_experiment:
build: <path/to/Dockerfile>
volumes:
- ~/data/:/data
command: ["python", "run_ML_experiment_file.py"]
Now to build an image and bring up a container you just need to do
docker-compose up --build
The option --build is must to rebuild the image each time, else docker-compose chooses to use the image already built
Refer https://docs.docker.com/compose/
Recommended base image
As suggested in my comment, you could write a Dockerfile that looks like:
FROM python:3
RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir nibabel pydicom matplotlib pillow med2image
# Note: we had to merge the two "pip install" package lists here, otherwise
# the last "pip install" command in the OP may break dependency resolution…
CMD ["cat", "/etc/os-release"]
And the command example above could confirm at runtime (docker build --pull -t test . && docker run --rm -it test) that this image is based on the GNU/Linux distribution "Debian stable".
Generic Dockerfile template
Finally to give a comprehensive answer, note that a good practice regarding Python dependencies consists in specifying them in a declarative way in a dedicated text file (in alphabetical order, to ease review and update) so that for your example, you may want to write the following file:
requirements.txt
matplotlib
med2image
nibabel
pillow
pydicom
and use the following generic
Dockerfile
FROM python:3
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "./your-daemon-or-script.py"]
To be more precise, this is the approach suggested in the documentation of the Docker official image python, §. How to use this image
Some of the other answers/comments are suggesting to change your base image but if you want to keep your ubuntu 16.04 you can also simply specify your version of pip/python to use pip3 or pip3.5 like shown below.
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y --no-install-recommends \
python3.5 \
python3-pip \
&& \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN pip3 install nibabel pydicom matplotlib pillow
RUN pip3 install med2image