My Dockerfile is something like
FROM my/base
ADD . /srv
RUN pip install -r requirements.txt
RUN python setup.py install
ENTRYPOINT ["run_server"]
Every time I build a new image, dependencies have to be reinstalled, which could be very slow in my region.
One way I think of to cache
packages that have been installed is to override the my/base
image with newer images like this:
docker build -t new_image_1 .
docker tag new_image_1 my/base
So next time I build with this Dockerfile, my/base already has some packages installed.
But this solution has two problems:
- It is not always possible to override a base image
- The base image grow bigger and bigger as newer images are layered on it
So what better solution could I use to solve this problem?
EDIT##:
Some information about the docker on my machine:
☁ test docker version
Client version: 1.1.2
Client API version: 1.13
Go version (client): go1.2.1
Git commit (client): d84a070
Server version: 1.1.2
Server API version: 1.13
Go version (server): go1.2.1
Git commit (server): d84a070
☁ test docker info
Containers: 0
Images: 56
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Dirs: 56
Execution Driver: native-0.2
Kernel Version: 3.13.0-29-generic
WARNING: No swap limit support
Try to build with below Dockerfile.
If there are some changes on
.
(your project), docker skippip install
line by using cache.Docker only run
pip install
on build when you edit requirements.txt file.I write simple
Hello, World!
program.Below is output.
I update only run.py and try to build again.
Below is output.
As you can see above, docker use build cache. And I update requirements.txt this time.
Below is output.
And docker doesn't use build cache. If it doesn't work, check your docker version.
To minimise the network activity, you could point
pip
to a cache directory on your host machine.Run your docker container with your host's pip cache directory bind mounted into your container's pip cache directory.
docker run
command should look like this:Then in your Dockerfile install your requirements as a part of
ENTRYPOINT
statement (orCMD
statement) instead of as aRUN
command. This is important, because (as pointed out in comments) the mount is not available during image building (whenRUN
statements are executed). Docker file should look like this:Probably it's best if the host system's default pip directory will be used as a cache (e.g.
$HOME/.cache/pip/
on Linux or$HOME/Library/Caches/pip/
on OSX), just like I suggested in the exampledocker run
command.I found that a better way is to just add the Python site-packages directory as a volume.
This way I can just pip install new libraries without having to do a full rebuild.
EDIT: Disregard this answer, jkukul's answer above worked for me. My intent was to cache the site-packages folder. That would have looked something more like:
Caching the download folder is alot cleaner though. That also caches the wheels, so it properly achieves the task.