Imagine you have your web application and some workflow executors:
- http-server (serving pre-build asset files) - production
- builder (compiling/bundling js/css/html from sources) - deployment/development
- debugger/builder (building from sources on the fly, add js source maps) - development
- selenium (running tests) - integration testing
How can we construct layered images to get those workflow executors working the most effectively? By effectively I mean "fastest to run and least to write".
The answer might be straightforward: just create 4 Dockerfile
s one depending on another.
You can add a volume to share build from sources part. The question is whether you want result assets to be included in the image or build it from sources each time.
Create 4 folders to have Dockerfile
in each.
Production
production/Dockefile
:
FROM # put server here
COPY # put config here
# some other option
# volume sharing?
Build
build/Dockerfile
:
# install dependencies
ADD # add sources here
RUN # some building script
Debug
debug/Dockefile
:
# ideally, configure production or build image
Test
test/Dockefile
:
FROM # import production
# install test dependencies
RUN # test runner
There are also several options.
1. Use .gitignore with negative pattern (or ADD?)
*
!directory-i-want-to-add
!another-directory-i-want-to-add
Plus use docker command specifying dockerfiles and context:
docker build -t my/debug-image -f docker-debug .
docker build -t my/serve-image -f docker-serve .
docker build -t my/build-image -f docker-build .
docker build -t my/test-image -f docker-test .
You could also use different gitignore files.
- Mount volumes
Skip sending context at all, just use mounting volumes during run time (using
-v host-dir:/docker-dir
).
So you'd have to:
docker build -t my/build-image -f docker-build . # build `build` image (devtools like gulp, grunt, bundle, npm, etc)
docker run -v output:/output my/build-image build-command # copies files to output dir
docker build -t my/serve-image -f docker-serve . # build production from output dir
docker run my/serve-image # production-like serving from included or mounted dir
docker build -t my/serve-image -f docker-debug . # build debug from output dir
docker run my/serve-image # debug-like serving (uses build-image with some watch magic)