From 4d766c2ee5f3a592fe3b0372dbb6d4bd2d0d67af Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Fri, 26 Jan 2018 09:43:24 -0500 Subject: [PATCH 1/3] Mount `pip_cache_path` in Docker container This allow us to have permanent pip cache between different builds / projects to work faster locally and under slow internet connections. --- readthedocs/doc_builder/environments.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readthedocs/doc_builder/environments.py b/readthedocs/doc_builder/environments.py index c89fa22c78b..f0645f644b4 100644 --- a/readthedocs/doc_builder/environments.py +++ b/readthedocs/doc_builder/environments.py @@ -728,6 +728,10 @@ def create_container(self): 'bind': self.project.doc_path, 'mode': 'rw' }, + self.project.pip_cache_path: { + 'bind': self.project.pip_cache_path, + 'mode': 'rw' + } }), detach=True, environment=self.environment, From f9b942ea21db829531c9c57207d42f3d8f461a7c Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Sat, 27 Jan 2018 13:43:03 -0500 Subject: [PATCH 2/3] Mount the pip cache in Docker only if we are in DEBUG mode --- readthedocs/projects/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/projects/models.py b/readthedocs/projects/models.py index 3215a7fd9d5..f346f2fc984 100644 --- a/readthedocs/projects/models.py +++ b/readthedocs/projects/models.py @@ -449,7 +449,7 @@ def checkout_path(self, version=LATEST): @property def pip_cache_path(self): """Path to pip cache.""" - if getattr(settings, 'GLOBAL_PIP_CACHE', False): + if getattr(settings, 'GLOBAL_PIP_CACHE', False) and settings.DEBUG: return settings.GLOBAL_PIP_CACHE return os.path.join(self.doc_path, '.cache', 'pip') From c876f6f2d1e8b9dcfbc98c7da81f1927c11f0c36 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 30 Jan 2018 11:24:52 -0500 Subject: [PATCH 3/3] Mount the GLOBAL_PIP_CACHE conditionally Refactor, by creating a new method, where the binds are created to be easier to read. --- readthedocs/doc_builder/environments.py | 56 +++++++++++++++++-------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/readthedocs/doc_builder/environments.py b/readthedocs/doc_builder/environments.py index f0645f644b4..7995de160de 100644 --- a/readthedocs/doc_builder/environments.py +++ b/readthedocs/doc_builder/environments.py @@ -13,6 +13,7 @@ from datetime import datetime from readthedocs.core.utils import slugify +from django.conf import settings from django.utils.translation import ugettext_lazy as _, ugettext_noop from docker import Client from docker.utils import create_host_config @@ -662,6 +663,42 @@ def get_client(self): ) ) + def get_container_host_config(self): + """ + Create the ``host_config`` settings for the container. + + It mainly generates the proper path bindings between the Docker + container and the Host by mounting them with the proper permissions. + Besides, it mounts the ``GLOBAL_PIP_CACHE`` if it's set and we are under + ``DEBUG``. + + The object returned is passed to Docker function + ``client.create_container``. + """ + binds = { + SPHINX_TEMPLATE_DIR: { + 'bind': SPHINX_TEMPLATE_DIR, + 'mode': 'ro', + }, + MKDOCS_TEMPLATE_DIR: { + 'bind': MKDOCS_TEMPLATE_DIR, + 'mode': 'ro', + }, + self.project.doc_path: { + 'bind': self.project.doc_path, + 'mode': 'rw', + }, + } + + if getattr(settings, 'GLOBAL_PIP_CACHE', False) and settings.DEBUG: + binds.update({ + self.project.pip_cache_path: { + 'bind': self.project.pip_cache_path, + 'mode': 'rw', + } + }) + return create_host_config(binds=binds) + @property def container_id(self): """Return id of container if it is valid.""" @@ -715,24 +752,7 @@ def create_container(self): exit=DOCKER_TIMEOUT_EXIT_CODE)), name=self.container_id, hostname=self.container_id, - host_config=create_host_config(binds={ - SPHINX_TEMPLATE_DIR: { - 'bind': SPHINX_TEMPLATE_DIR, - 'mode': 'ro' - }, - MKDOCS_TEMPLATE_DIR: { - 'bind': MKDOCS_TEMPLATE_DIR, - 'mode': 'ro' - }, - self.project.doc_path: { - 'bind': self.project.doc_path, - 'mode': 'rw' - }, - self.project.pip_cache_path: { - 'bind': self.project.pip_cache_path, - 'mode': 'rw' - } - }), + host_config=self.get_container_host_config(), detach=True, environment=self.environment, mem_limit=self.container_mem_limit,