6 ms·
Honestly, I see this as an antipattern, not because it generates extra layers, but because a Dockerfile isn't the right place to write a provisioning script. W
by donw 10y ago
Honestly, I see this as an antipattern, not because it generates extra layers, but because a Dockerfile isn't the right place to write a provisioning script.
When building apps, I keep a small number of shell scripts that live in a `bin` directory, that perform essential operational tasks.
One script installs all the dependencies required to either run or develop the app; another runs all tests and exits with either success or failure; and the final script just runs the app.
Docker then just runs those scripts, which are written deliberately to be easily read, and thus function as living documentation for the project.
These same scripts get used, both by developers on a daily basis, as well as by our CI/CD system when prepping containers.
This also makes onboarding a snap: you run `bin/setup`, and your Mac or Linux box is good to go. And, because that script gets used every time the CI system spins up a build, it will never go out of sync with reality.
- yladiz 10y agoThe problem is that if you're building images a lot, Docker doesn't cache COPY calls because it doesn't know if the file has changed or not when calling the COPY command. So if you constantly build images and there are a lot of computationally intensive tasks within those scripts, but you've only changed one small item near the end of the script, your build time may be significantly longer by using the script than by putting it directly in the Dockerfile using the RUN command. I build a lot of modules within one of my Docker images for work, and while it doesn't change often, I would really not like to wait the 20 minutes if I really needed to push to production when I only change some certificate population segment at the end of the Dockerfile or something after a particularly intensive module build RUN step.
- shawabawa3 10y agoDocker does cache COPY calls AFAIK. If you're copying your whole directory though the cache breaks if any file changes. The normal way of doing it is to copy stuff like requirements.txt, package.json, Gemfile etc first and install stuff, then copy everything else at the end
- yladiz 10y agoAh, maybe that's true, I always figured it didn't cache it since it wasn't text. In this case it doesn't matter since the script would change, but if the scripts were broken apart and ran using RUN commands it would be a better middle-ground solution than wholly putting it all in a script with a single RUN command.
- deleted 10y ago[deleted]
- solatic 10y agoIt never gets out of sync, until somebody gets tripped up by some idiosyncracy of running the server directly on their machine instead of through Docker. One of the original benefits of containers is in its potential to reduce the disparity between dev and prod. If you're running containers based on the exact same image as dev and prod, then there are fewer reasons why something would only work on a dev machine. If your devs are using containers correctly, and building candidate images on their own machines, then there's no need for separate bin scripts. If your devs need separate bin scripts so that they can avoid installing and using Docker on their own workstations, then you're throwing out a lot of the benefit which containers give you.