Cesar
Cesar

Reputation: 41

How to remove development dependencies in production docker images

When shipping a dockerized node.js to production, is it correct to ship an image that contains development dependencies?

I am not talking about the development dependencies Not the devDependencies listed in packages.json, I mean gcc, python, node-gyp, some other *-dev packages, containing a bunch of headers, static libraries. All of them are needed to compile some node dependencies (like node-sass)

An idea could be a two stage build, one image with all *-dev dependencies, build stuff in there, and export the results to another new image with just the binaries.

In general, any compiled sofware I want to distribute in docker images, should not contain the compilers, headers, and tools used to build the binaries.

Upvotes: 4

Views: 6551

Answers (3)

BlackStork
BlackStork

Reputation: 8371

The answer to OP question depends of how much images OP/his company maintain for production needs.

There few strategies possible:

  1. If the quantity of maintained images is medium to low and system architecture is not very complex and do not uses dozens of images at once there the simplest and easiest solution to maintain is the best one. You can approach it with 1 single build. Or 2 step build if you want to use compiled source as base for containers that could bear different content (In this case 2nd stage could be even done during docker-compose up (system start-up)).

  2. You can remove dev-only dependencies (as other answers suggested) if its necessary to keep the image slim/ there a lot of running containers that use same image / the size of compiled files is huge. This will increase time span of the build process but will result in smaller image.

  3. 3rd approach is totally different - if there is compiling process, use CI pipeline that independently compiles the assets within separate container (CI runner process) and provides versioned artifact - which you can use in your production builds (even store it somewhere, on S3/CDN/private, accesible to deployment storage), and then just fetch it from there, or just use files hosted there (in case of CDN).

Upvotes: 0

Sébastien
Sébastien

Reputation: 1053

If you want something to not be included in your final image, you have to do all the related commands in only one layer (one RUN statement).

Something like the following (pseudo code):

RUN install dev-dependencies && build your-project && uninstall dev-dependencies

Only one layer is created for the RUN statement and it won't contain dev dependencies.

Upvotes: 6

Ricardo Branco
Ricardo Branco

Reputation: 6079

The image would not be smaller if you remove the dependencies because the older layers contain them.

Try the new (experimental) --squash option with docker-build, using Docker 1.13.

Upvotes: 0

Related Questions