0

My project is structured kind of like this:

project
|- docker_compose.yml
|- svc-a
   |- Dockerfile
|- svc-b
   |- Dockerfile
|- common-lib
   |- Dockerfile

Within docker_compose.yaml:

version: 3.7
services:
  common-lib:
    build:
      context: ./common-lib/
    image: common-lib:latest
  svc-a:
    depends_on:
      - common-lib
    build:
       ...
  svc-b:
    depends_on:
      - common-lib
    build:
      ...

In common-lib/Dockerfile relatively standard:

FROM someBuilderBase:latest
COPY . .
RUN build_libraries.sh

Then in svc-a/Dockerfile I import those built libraries:

FROM common-lib:latest as common-lib

FROM someBase:latest
COPY --from=common-lib ./built ./built-common-lib
COPY . .
RUN build_service_using_built_libs.sh

And the Dockerfile for svc-b is basically the same.

This works great using docker-compose build svc-a as it first builds the common-lib container because of that depends-on and I can reference to it easily with common-lib:latest. It is also great because running docker-compose build svc-b doesn't rebuild that base common library.

My problem is that I am defining a builder container as a docker compose service. When I run docker-compose up it attempts to run the common-lib as a running binary/service and spits out a slew of errors. In my real project I have a bunch of chains of these builder container services which is making docker-compose up unusuable.

I am relatively new to docker, is there a more canonical way to do this while a) avoiding code duplication building common-lib in multiple Dockerfiles and b) avoiding a manual re-run of docker build ./common-lib before running docker build ./svc-a (or b)?

4

1 回答 1

0

The way you do it is not exactly how you should do it in Docker.

You have two options to achieve what you want :

1/ Multi stage build

This is almost what you're doing with this line (in your svc-a dockerfile)

FROM common-lib:latest as common-lib

However, instead of creating you common-lib image in another project, just copy the dockerfile content in your service :

FROM someBuilderBase:latest as common-lib
COPY . .
RUN build_libraries.sh

FROM someBase:latest
COPY --from=common-lib ./built ./built-common-lib
COPY . .
RUN build_service_using_built_libs.sh

This way, you won't need to add a common-lib service in docker-compose.

2/ Inheritance

If you have a lot of images that need to use what is inside your common-lib (and you don't want to add it in every dockerfile with multi stage build), then you can just use inheritance.

What's inheritance in docker ?

It's a base image.
From your example, svc-a image is based on someBase:latest. I guess, it's the same for svc-b. In that case, just add the lib you need in someBase image (with multi-stage build for example or by creating a base image containing your lib).

于 2020-03-02T13:31:16.483 回答