docker-compose file can't build images

Viewed 918

I have a project structure like this:

root (folder)
--- foo (folder)
------ target (folder)
------ Dockerfile (file)
--- bar (folder)
------ target (folder)
------ Dockerfile (file)
--- docker-compose.yml (file)

Here's the docker-compose file:

version: "3.9"
services:
  foo-service:
    image: foo-image:latest
    container_name: foo-container
    build:
      context: .
      dockerfile: foo/Dockerfile
  bar-service:
    image: bar-image:latest
    container_name: bar-container
    build:
      context: .
      dockerfile: bar/Dockerfile

The Dockerfile are equal to both, like this:

FROM openjdk:8-jdk-alpine
COPY target/*.jar app.jar
CMD ["java", "-jar", "/app.jar"]

When I try to run docker-compose up, it fails on step 2 (copy step): "no source files were specified". When running each docker build . individually, it works.

How do I get to solve this?

1 Answers

When you build a Docker image, there are two basic things you can control. The context directory is the base directory for COPY commands; the Dockerfile location is a specific file within the context that's the Dockerfile. In Compose you specify these with the build: {context: ..., dockerfile: ...} options; in plain Docker these are the path argument to docker build and the -f option.

When your Dockerfile says:

build:
  context: .
  dockerfile: foo/Dockerfile

That's the equivalent of the CLI command:

docker build -f foo/Dockerfile .

...and paths in foo/Dockerfile will be interpreted relative to the root (.) directory.

Probably what you're actually running is

cd foo
docker build .

or, equivalently,

docker build foo

which you can express in Compose syntax

build:
  context: foo
  # dockerfile: Dockerfile

or more succinctly

build: foo

(Compose on its own will assign reasonable defaults for image: and container_name: and you don't need to explicitly specify these if you're build:ing a local image, unless you're planning to push the built image somewhere.)

Related