Access to outside of context in Dockerfile

2020-07-11 05:33发布

问题:

In my Maven project I have following structure:

docker/
   docker-compose.yml
   A/
     Dockerfile
   B/
     Dockerfile
src/
target/
   foo.war

In A's Dockerfile I need access to war in /target folder with the following command:

COPY ../../target/foo.war /usr/local/tomcat/webapps/foo.war

when I run docker-compose up tt gives me error

failed to build: COPY failed: Forbidden path outside the build context: ../../target/foo.war

docker-compose.yml

version: '3.6'
services:
  fooA:
    build: ./docker/A
    ports:
      - "8080:8080"
    depends_on:
      - fooB

  fooB:
    build: ./docker/fooB
    ports:
      - "5433:5433"

Can you tell me how to solve this? I don't want copy war file manually after every project build.

回答1:

As far as I know it's not possible to access things outside out your build context.

You might have some luck by mixing the dockerfile directive with the context directive in your compose file in the root dir of your project as follows:

build:
  context: .
  dockerfile: A/Dockerfile

You may wish to include a .dockerignore in the project root dir to prevent the entire project being send to the docker daemon resulting in potentially much slower builds.



回答2:

Dir Structure

Suppose you have the following dir structure

./docker-compose.yaml
./all-runners/
        /start.sh
        /runner-A/Dockerfile
        /runner-B/Dockerfile
        /runner-C/Dockerfile
  • I had a requirement where all Dockerfiles share the same file
  • The top-level docker-compose is the driver of all the builds

Dockerfile

It ALWAYS will load from its relative path, having the current dir of itself as the local reference to the paths you specify.

COPY start.sh /runtime/start.sh

Docker-compose

  • The real trick is here. The context you want to set is the directory where your main content is located.
  • In this example, your shared context dir is the runtime dir.
    • Imagine all the files under this dir being copied over to a dir called context.
    • Now imaging you can just specify the Dockerfile that you want to copy to that same dir. You can specify that using dockerfile.

The docker-compose.yml is as follows

version: "3.3"
services:

  runner-A
    build:
      context: ./all-runners
      dockerfile: ./runner-A/Dockerfile

  runner-B
    build:
      context: ./all-runners
      dockerfile: ./runner-B/Dockerfile

  runner-C
    build:
      context: ./all-runners
      dockerfile: ./runner-C/Dockerfile
  • Since the context is set to all-runners, the file start.sh will be reuse by each individual Dockerfile specified by the path in dockerfile.
  • You get the same effect as in the parent dir, in a more organized way

Now your build works with files outside the dir of your Dockerfile. The result is just the same when you do the proper mapping!

Happy Dockering