Skip to content

Instantly share code, notes, and snippets.

@blwsh
Last active October 21, 2020 02:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blwsh/3ffd41773dad357d00277860be7df487 to your computer and use it in GitHub Desktop.
Save blwsh/3ffd41773dad357d00277860be7df487 to your computer and use it in GitHub Desktop.
An elegant solution to installing docker dependencies twice

If you use a production docker image for your local dev environment it’s very likely one of the builds stages is running a command which installs your dependencies such as npm install, composer install or go get.

Now you don’t want to adjust your production docker image but at the same time, your dependency installs can take a long time and you really don’t want to run the command twice.

An easy solution would be to tell docker to not mount the directory into the container with the rest of your project code but then you don’t get all the useful information provided by your IDE.

Enter docker cp and volume overrides.

Using docker cp and overriding the volume we wish to copy from the container allows us to pull directories such as node_modules out of the built docker image. This is great because it means we don’t need to run our installs twice. It also has the added benefit of reflecting your production environment files better and eliminates the issue of slightly different language versions and in turn, different dependencies.

It's as simple as just two commands:

docker-compose run --name node_install -d -v /path/to/node_modules/ node sh
docker cp node_install:/path/to/node_modules ./path/on/host

Here is an example makefile:

install:
	echo "Copying node_modules from node container"
	(docker rm -f node_install || true) && docker-compose run --name node_install -d -v /src/public/node_modules/ node sh && \
		docker cp node_install:/src/public/node_modules ./public/ && \
		docker rm -f node_install &> /dev/null
	echo "Copying vendor from php container"
	(docker rm -f php_install || true) && docker-compose run --name php_install -d -v /src/public/backend/vendor php sh && \
		docker cp php_install:/src/public/backend/vendor ./public/backend && \
		docker rm -f php_install &> /dev/null
	echo "Done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment