Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Want a way to specify a dockerfile outside the context in the docker-compose dockerfile directive #4926

Closed
bitdancer opened this issue Jun 14, 2017 · 18 comments

Comments

@bitdancer
Copy link

I've read several discussions about the security reasons why paths outside the context are not permitted. OK, but it seems to me that that should not apply to the dockerfile directive. After all, you can specify a dockerfile outside the context when using the docker build command itself, using -f. I'd like to be able to do the same thing in docker-compose, either relative to the context or relative to the dockerfile-compose.yml file. My goal is to put all the dockerfile-specific config in a subdirectory next to my context directory. I can do that with everything except the dockerfile itself.

@shin-
Copy link

shin- commented Jun 14, 2017

It already works?

$ cat docker-compose.yml 
version: '2.2'
services:
  foo:
    build:
      context: .
      dockerfile: /opt/Dockerfile
    command: sleep 3

$ cat /opt/Dockerfile 
FROM alpine:3.5
RUN mkdir /test

$ docker-compose build --no-cache
Building foo
Step 1/2 : FROM alpine:3.5
 ---> 02674b9cb179
Step 2/2 : RUN mkdir /test
 ---> Running in d5601b4cad02
 ---> dd9cf82ed85a
Removing intermediate container d5601b4cad02
Successfully built dd9cf82ed85a
Successfully tagged repro4926_foo:latest

@shin- shin- modified the milestone: 1.15.0 Jun 14, 2017
@bitdancer
Copy link
Author

That's an absolute path. Given that this is checked in to a repo and I don't know where it will be checked out, I can't practically use an absolute path. How would I specify it using a relative path (as I said, I don't care if it is relative to the context or relative to the docker-compose.yml file)?

@shin-
Copy link

shin- commented Jun 14, 2017

$ docker build -f ../../../../../../opt/Dockerfile .
unable to prepare context: the Dockerfile (/opt/Dockerfile) must be within the build context

Not a Compose issue I'm afraid.

@bitdancer
Copy link
Author

You are right. I could have sworn that I tested that, but obviously whatever I thought I did wasn't a proper test, because I see that error myself trying it again.

@shin- shin- closed this as completed Jul 3, 2017
@theimpostor
Copy link

FWIW it is possible to use a Dockerfile outside the of the build context:

docker build -f - . < ../Dockerfile

It would be great if docker-compose could support this as well.

@colltoaction
Copy link

It seems that you can use $PWD, but it would be best to be able to use a relative path:

version: '2'
services:
  service:
    build:
      context: ../path/to/service
      dockerfile: $PWD/Dockerfile-for-service

@thaJeztah
Copy link
Member

Docker 18.03 will add support for Dockerfile outside of the context directory; docker/cli#886

@shin- not sure if changes are needed in Docker Compose for that?

@shin-
Copy link

shin- commented Mar 5, 2018

@thaJeztah Thanks! This will require some changes to support it both in the SDK and in Compose, but I'll put it on the list.

@jbdhacf
Copy link

jbdhacf commented Apr 30, 2018

cd ./.. wont work?

@masaeedu
Copy link

masaeedu commented May 14, 2018

@shin- How is this supposed to work? I'm trying to use:

version: '3'
services:
  xyz:
    image: xyz
    build:
      context: .
      dockerfile: dockerfiles/api.Dockerfile

with the docker-compose.yml shown above and a Dockerfile in dockerfiles/api.Dockerfile, but I get:

ERROR: Cannot locate specified Dockerfile: dockerfiles\api.Dockerfile

Trying to build directly from the docker CLI using docker build -t test -f .\dockerfiles\api.Dockerfile works fine.

@ghost
Copy link

ghost commented Jul 2, 2018

@masaeedu A relative path is not supported. What you can do is to specify a path relative to the current working directory using $PWD/dockerfiles/api.Dockerfile.

@kferrone
Copy link

kferrone commented Jul 26, 2018

yo yo I have it working as you want, check it out below. I put Dockerfile and docker-compose.yml in a dir called builder then changed the context for docker-compose.

At top level of project make a file called .env and add the following:

COMPOSE_FILE=./builder/docker-compose.yml

Don't change anything in your Dockerfile, it's good to go.

Now make your compose file like so:

version: "3"
services:
  myapp:
    build: 
      context: ../
      dockerfile: ./builder/Dockerfile

Now at the root of the project, simply run:

docker-compose build

Voila!

@jmoz
Copy link

jmoz commented Dec 3, 2018

Why is a relative path ok for context yet fails for dockerfile?

@kferrone
Copy link

kferrone commented Dec 3, 2018

@jmoz

The Dockerfile is relative to the context. Dockerfile path does not need to be a relative simply because the relative part of the path is defined in the context.

@armdev
Copy link

armdev commented Dec 15, 2018

This is working
version: '2'
services:
eurekanode:
mem_limit: 256m
image: eurekanode
build:
context: .
dockerfile: eurekanode/docker/Dockerfile
container_name: eurekanode

FROM openjdk:11-jdk-slim
VOLUME /tmp
ADD eurekanode/target/eurekanode.jar /app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Xmx128m", "-Xss256m", "-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
EXPOSE 8761

sqs added a commit to sourcegraph/sourcegraph-public-snapshot that referenced this issue Feb 13, 2019
This is because we build using a Dockerfile outside of the build context, which is supported only in v18+ (docker/compose#4926 (comment)).

On Docker 17, you get an error:

```
$ IMAGE=foo cmd/symbols/build.sh
/home/sqs/src/github.com/sourcegraph/sourcegraph
Compiling the symbols service...
Building symbols image foo...
unable to prepare context: The Dockerfile (/home/sqs/src/github.com/sourcegraph/sourcegraph/cmd/symbols/Dockerfile) must be within the build context (/tmp/sgdockerbuild_sBc8sv6)
```
@KalanaDananjaya
Copy link

It seems that you can use $PWD, but it would be best to be able to use a relative path:

version: '2'
services:
  service:
    build:
      context: ../path/to/service
      dockerfile: $PWD/Dockerfile-for-service

I recently came across this issue and your solution was a life saver @colltoaction

@dimadeveatii
Copy link

dimadeveatii commented Jul 3, 2020

The $PWD works great on linux, but fails on Windows (as $PWD is just empty in Windows).
For those looking for a cross-platform solution, use a default value:

version: '2'
services:
  service:
    build:
      context: ../path/to/service
      dockerfile: ${PWD:-.}/Dockerfile-for-service

In this case the dockerfile is resolved to $PWD/Dockerfile-for-service in linux and to ./Dockerfile-for-service in Windows.
It looks like docker-compose on Windows does not suffer from the Forbidden path outside the build context issue and allows to use relative paths for dockerfile.

@calebickler
Copy link

$PWD works, does a path relative to your docker-compose.yml file work yet? Is there an issue for that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests