33

I need to add some paths to my PATH in docker-compose.yml

in docker-compose.yml I have tried

app:
    ...
    environment:
        - PATH /code/project

however that just overwrites the existing PATH - whereas I want to add to the existing PATH

lukeaus
  • 11,465
  • 7
  • 50
  • 60

5 Answers5

22

A docker-compose.yml does not offer you any mean to extend an environment variable which would already be set in a Docker image.

The only way I see to do such things is to have a Docker image which expects some environment variable (let's say ADDITONAL_PATH) and extends at run time its own PATH environment variable with it.


Let's take the following Dockerfile:

FROM busybox
ENV PATH /foo:/bar
CMD export PATH=$PATH:$ADDITIONAL_PATH; /bin/echo -e "ADDITIONAL_PATH is $ADDITIONAL_PATH\nPATH is $PATH"

and the following docker-compose.yml file (in the same directory as the Dockerfile):

app:
  build: .

Build the image: docker-compose build

And start a container: docker-compose up, you will get the following output:

app_1 | ADDITIONAL_PATH is

app_1 | PATH is /foo:/bar:

Now change the docker-compose.yml file to:

app:
  build: .
  environment:
    - ADDITIONAL_PATH=/code/project

And start a container: docker-compose up, you will now get the following output:

app_1 | ADDITIONAL_PATH is /code/project

app_1 | PATH is /foo:/bar:/code/project


Also note a syntax error in your docker-compose.yml file: there must be an equal sign (=) character between the name of the environment variable and its value.

environment:
    - PATH=/code/project

instead of

environment:
    - PATH /code/project
Thomasleveil
  • 95,867
  • 15
  • 119
  • 113
  • 1
    This will also work in the `Dockerfile`: `ENV="/my/new/path"${PATH}". Note that the quotes are important. I recommend adding this to your answer. See [this post](https://stackoverflow.com/questions/28722548/updating-path-environment-variable-permanently-in-docker-container). – orodbhen Oct 06 '17 at 13:57
13

I know this is an old thread, but I think there are a couple of things that can be clarified.

Through docker-compose file one can only address variables from the host machine, therefore it is NOT possible to extend image's PATH from docker-compose.yml:

app:
    ...
    environment:
        - PATH=/code/project:$PATH

On the other hand, using RUN or CMD EXPORT directive will not suffice due to EXPORTED variables not persisting through images. Since every Dockerfile directive generates an intermediate image, these values will be reflected in them and not in the main image where you actually need them.

The best option would be to use build option in docker-compose.yml:

  app:
    build: .

and adding ENV option to a Dockerfile:

ENV PATH /path/to/bin/folder:$PATH

This is suggested in issue #684 and I would also suggest looking at an answer: docker ENV vs RUN export.

Rocksn17
  • 739
  • 1
  • 9
  • 9
2

You can add your value. To do so you need to know name or ID of the container, run it to know:

docker ps

This will print details of all running containers. Look for your container and copy its ID or name. Then run this:

docker inspect <container ID>

It will print all values of specified container. Look for ENV section and find PATH environment variable. Then copy its value, add your changes and extend it with your new values then set it again in your docker-compose.yml "environment" section.

app
environment:
    - PATH=value-you-copied:new-value:new-value:etc

Note that you shouldn't remove anything from initial value of PATH, just extend it and add new value.

Jamali
  • 754
  • 10
  • 24
0

@Thomasleveil's answer works only for containers built directly from the docker-compose file (via the build). And you have no control over the command executed.

I needed this functionality for containers downloaded from (our) repository where this does not quite work.

I have found solution using the entrypoint and command.

Lets have some base container base and another one, java7, that is based upon it. And finaly some docker-compose using the java7 container to run some stuff.

Probably the most important file here, entrypoint.sh

$ cat base/script/entrypoint.sh
#!/bin/bash

export PATH="$PATH_ADD:$PATH"
echo "Path modified to $PATH"
exec $@

Dockerfile for base container

$ cat base/Dockerfile
FROM xxx
# copy entrypoint script that extends current PATH variable by PATH_ADD
COPY script/entrypoint.sh /usr/sbin

ENTRYPOINT ["/usr/sbin/entrypoint.sh"]

Dockerfile for java7 container

$ cat java7/Dockerfile
FROM base
# download java7
curl ... /opt/java/jdk7
ENV JAVA_HOME /opt/java/jdk7

Commands run by docker-compose

$ cat sbin/run-app1.sh
exec $JAVA_HOME/bin/java -version

$ cat sbin/run-app2.sh
exec $JAVA_HOME/bin/java -version

Docker-compose using these:

$ cat docker-compose.yml
version: '3'
services:
  app1:
    image: java7
    command: run-app1.sh
    environment:
      PATH_ADD: /app/sbin
    volumes:
      - "./sbin:/app/sbin:cached"
  app2:
    image: java7
    command: run-app2.sh
    environment:
      PATH_ADD: /app/sbin
    volumes:
      - "./sbin:/app/sbin:cached"

File structure

$ tree
.
├── base
│   ├── script
│   │   └── entrypoint.sh
│   └── Dockerfile
├── java7
│   └── Dockerfile
├── sbin
│   ├── run-app1.sh
│   └── run-app2.sh
└── docker-compose.yml
Petr Újezdský
  • 1,233
  • 12
  • 13
-8

to add a single location to PATH in your docker-compose.yml file:

app
    environment:
        - PATH=/code/project:$PATH

to add multiple locations to your PATH in your docker-compose.yml file

app
    environment:
        - PATH=/code/project:/code/lib:/foo/bar:$PATH

to add to your PYTHONPATH

app
    environment:
        - PYTHONPATH=/code/project:/code/lib:/foo/bar
lukeaus
  • 11,465
  • 7
  • 50
  • 60
  • 17
    here $PATH would be replaced with the value defined on the machine on which you run the docker-compose command. This would not extend the value of the original PATH environment variable as it was in the docker image. – Thomasleveil Jan 09 '16 at 14:42
  • @Thomasleveil - Interesting - I have tested extending PATH using the code above and it works - have tested several times – lukeaus Jan 13 '16 at 10:04
  • 4
    are you sure the `PATH` value wasn't the same on both your docker host system and your docker image, as a coincidence? – Thomasleveil Jan 13 '16 at 10:12
  • @Thomasleveil - just checked, the path for the docker container is not on the host system. In fact that path `code` is created just for the docker image – lukeaus Jan 13 '16 at 10:16
  • 7
    I'm sorry I maintain it does not work, see [this gist](https://gist.github.com/thomasleveil/7428032dcfe9a13432e0), using docker-compose v1.5.2 on CentOS 6.7 – Thomasleveil Jan 13 '16 at 13:27
  • it works on `PYTHONPATH` Please be careful on your workdir. – Ryan Chou Jun 03 '17 at 01:18
  • 3
    @Thomasleveil is correct. This is simply using the value from the host where you're running `docker-compose` from. The fact that the same `PATH` exists in the container, does not mean "it works" in the way that the OP describes. Try adding values to `PATH` in your host shell, and then run `docker-compose`. You'll see that they show up in the container `PATH`. Then try clearing `PATH` in your host shell, and you'll see that it no longer "works". Additionally, using `env_file` to do this will simply interpret `$PATH` as a string literal. – orodbhen Oct 06 '17 at 13:22
  • 1
    My experience with Docker for Windows running a Windows Image is that @Thomasleveil is right. – Dean C Wills Apr 21 '18 at 19:31