4 ms·
I'm not sure if Circle supports it yet but you should definitely look into docker multistage builds as that should solve this problem for you. https://docs.doc
by 147 9y ago
I'm not sure if Circle supports it yet but you should definitely look into docker multistage builds as that should solve this problem for you.
https://docs.docker.com/engine/userguide/eng-image/multistage-build/ https://docs.docker.com/engine/userguide/eng-image/multistag...
- dankohn1 9y agoI've been experimenting with multi-stage builds, and they do let me build a leaner image with clearer syntax by using one the first image to build my gems, and then copying the gems to the final image. <https://github.com/coreinfrastructure/best-practices-badge/blob/dan-docker-updated/Dockerfile#L48> https://github.com/coreinfrastructure/best-practices-badge/b... However, that doesn't fix the problem of having lots of development and test gems installed in test that I don't want for production. I don't know of a way of copying just my production gems to a production image.
- lstamour 9y agoWell, you could load only the gems required for the environment: http://bundler.io/groups.html http://bundler.io/groups.html Or maybe have more than one path for gems and change load paths between environments? Or keep tests in a separate image from the production image under test? Similarly, build tools could live in a different image/layer.
- dankohn1 9y agoIt's not a crazy idea to first install production only gems, then copy them (cache them), and then install the remaining gems. But I'm asking for info on best practices.
- lstamour 9y agoYou can bundle into vendor folders, one for each env and one for the rest.
- dankohn1 9y agoDo you have a URL demonstrating this, please?
- 147 9y agoHere’s a node example that demonstrates the same concept. https://codefresh.io/blog/node_docker_multistage/ https://codefresh.io/blog/node_docker_multistage/
- lstamour 9y agoNo URL right this second (maybe I should write a blog post–), but I would set GEM_HOME or BUNDLE_PATH env variables as I ran bundler to have it install in a different folder, and add the folders as necessary to GEM_PATH at runtime. I would also consider using a local cache folders for the source of the gems bundler uses. This is the purpose of http://bundler.io/v1.6/bundle_package.html http://bundler.io/v1.6/bundle_package.html which assumes that gems are installed separately rather than loaded directly by path because of platform differences (packaging on Mac to run on Linux, for example). But you don’t need the overhead of bundler’s packaging and install process if your binaries are built in the same environment they run in, as could be the case with Docker or VMs. You could also point BUNDLE_PATH at the last place bundler ran for that environment (don’t delete the old gems) and that would speed up the install, but a better approach might be to package to a shared folder and then install to env specific bundle path folders in your docker image/build workspace, if you want bundler to manage the shared caching while keeping gem output separate and unique to each build. It’s important to remember that gems are just folders of ruby files placed in the load path, sometimes with compiled bits to load at runtime, that could in turn be dynamically compiled to rely on system libraries or non-Ruby packages. So you have similar constraints with Ruby that you would have with Node.js – the potential for issues from the portability or lack thereof for native code dependencies. That’s why there’s a distinction between “install” and “package” – install will make sure the binary output can run on the current system unless flagged not to.
- felicianotech 9y agoYou can optionally use a newer version of Docker CE that supports multistage builds.