I have a multistage Dockerfile where the first stage is very compute intensive, so I want to make sure its cached.
I created a simple Dockerfile and docker-compose.yaml to show what I mean. Even if I re-build it several times, only the second stage is running from cache. The first stage is always re-building.
Dockerfile
FROM node:15.4 as build-stage
RUN sleep 5
RUN touch /test
# Stage 1, based on Nginx, to have only the compiled app, ready for production with Nginx
FROM nginx:1.17-alpine
COPY --from=build-stage /test /test
docker-compose.yaml
version: '3'
services:
myservice:
build:
context: ./
cache_from:
- myservice:latest
- myservice:build-stage
image: myservice:latest
After doing docker-compose build here I can see the following images
REPOSITORY TAG IMAGE ID CREATED SIZE
myservice latest ae96394ac660 15 seconds ago 19.9MB
<none> <none> d4c212c2bcd1 15 seconds ago 936MB
node 15.4 6f7f341ab8b8 9 days ago 936MB
nginx 1.17-alpine 89ec9da68213 8 months ago 19.9MB
One could assume that the one called <none> is the build-stage image. But since it's not tagged I can't make the cache_from work.
If I had used only docker and not docker-compose I would do:
docker build . --target build-image -t myservice:build-image
This would build only the first stage and tag it so it can be used as cache afterwards. But is this possible with docker-compose?
I mean, there is a target: option in the docker-compose.yaml but if I add a separate service to build and tag only the first stage, that will also want to start when I do docker-compose up.