Reputation: 43
I'm new to Docker and read some articles about it.
I read many articles that say "use same image for all environments(dev/stage/production)" and "image for CI/CD and for deployment are different".
But I can't integrate those two advices and I also can't find dockerfile examples for that.
Is that mean I have to make below two docker images?
(1) image for deployment
- application code and its dependencies
- there is no CMD
(2) image for CI/CD
- use (1) as base image
- add extra for CI/CD
Upvotes: 2
Views: 420
Reputation: 40894
I think your confusion comes from section 4:
The deployment images should contain:
- The application code in minified/compiled form plus its runtime dependencies.
- Nothing else. Really nothing else.
The second category is the images used for the CI/CD systems or developers and might contain:
- The source code in its original form (i.e. unminified)
- Compilers/minifiers/transpilers (etc)
While many developers see it as natural, I think it's not a great setup, and it shows the antipattern No 1, treating a container like a VM.
To my mind, during development, the target container should not include compilers, test frameworks, etc. It should only contain the compiled code and the runtime for it, exactly like the container that goes to prod.
All these tools belong to a different container (let's call it "utility"), especially created to make building and testing uniform and reproducible. That container has installed all the tools one might need to build all the containers, or a wide subset thereof (e.g. all Node and Python containers). You mount your source directories when invoking it, and it compiles / minifies / packages the code, generates gRPC stubs, runs the test suite, etc.
You can use the same utility container locally and in CI/CD. Your build and test pipeline is independent from the OS (in our company developers run Windows, macOS, and Linux on their desktops, but for building a backend service it makes no difference). You never have to deal with a diverging zoo of compiler versions, test framework versions, eslint configurations, etc between different "development" images.
Of course, you can run the same image with your compiled code differently in prod and in development: e.g. you can expose ports to attach a debugger, etc. But it's (light) configuration from the outside the container, not a different build.
So no, to my mind, you should use the same container on development, CI/CD, and prod. In one of the companies I worked for all containers had crypto signatures, and you could only promote to QA / staging / prod a container which was build from a particular commit and passed tests, with the signature checked at each promotion. Of course leaving a compiler inside such a container would be a gaffe.
Upvotes: 3