5

I am trying to build an image using dockerfile. The commands in the dockerfile looks something like these:

FROM ubuntu:16.04 : : RUN pip3 install virtualenvwrapper RUN echo '# Python virtual environment wrapper' >> ~/.bashrc RUN echo 'export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3' >> ~/.bashrc RUN echo 'export WORKON_HOME=$HOME/.virtualenvs' >> ~/.bashrc RUN echo 'source /usr/local/bin/virtualenvwrapper.sh' >> ~/.bashrc 

After these commands, I will use virtualenvwrapper commands to make some virtualenvs.

If I had only environment variables to deal with in ~/.bashrc, I would have used ARG or ENV to set them up.

But now I also have other shell script files like virtualenvwrapper.sh the will be setting some of their own variables.

Also, RUN source ~/.bashrc is not working (source not found).

What should I do?

3 Answers 3

3

You shouldn't try to edit shell dotfiles like .bash_profile in a Dockerfile. There are many common paths that don't go via a shell (e.g., CMD ["python", "myapp.py"] won't launch any sort of shell and won't read a .bash_profile). If you need to globally set an environment variable in an image, use the Dockerfile ENV directive.

For a Python application, you should just install your application into the image's "global" Python using pip install. You don't specifically need a virtual environment; Docker provides a lot of the same isolation capabilities (something you pip install in a Dockerfile won't affect your host system's globally installed packages).

A typical Python application Dockerfile (copied from https://hub.docker.com/_/python/) might look like

FROM python:3 WORKDIR /usr/src/app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD ["python", "./your-daemon-or-script.py"] 

On your last question, source is a vendor extension that only some shells provide; the POSIX standard doesn't require it and the default /bin/sh in Debian and Ubuntu doesn't provide it. In any case since environment variables get reset on every RUN command, RUN source ... (or more portably RUN . ...) is a no-op if nothing else happens in that RUN line.

Sign up to request clarification or add additional context in comments.

3 Comments

You are saying that the environment variables get reset with every RUN.. Does that use the ~/.bashrc file to set their variables. In that case I might not need to use source anyways right?
Even if /bin/sh happens to be bash, running sh -c ... (which is what RUN usually does) doesn't read any dotfiles.
so, there is no way except ENV to set environment variables in /bin/sh . But ENV will only set just one variable at a time, or can I attach a script file to it for setting the environment variables?
2

It may be easier to do this from the command line, and avoid messing with the dockerfile entirely. Simply use the -l or --login option to force the shell opened in the Docker image to be a login variant, which will source /etc/profile and the first of the files ~/.bash_profile, ~/.bash_login, or ~/.profile that is found.

docker run -it --rm docker_image /bin/bash -l

1 Comment

Thanks for the '-l' option, it can load bash enviroment variables
0
  1. avoid using ~ => put your bashrc in a specific path
  2. put source bashrc and your command on the same RUN line with ;

the RUN lines are totally independent from each others for the environment

3 Comments

I used RUN echo 'source /usr/local/bin/virtualenvwrapper.sh' >> bashForIndy. RUN source bashForIndy; mkvirtualenv dharmesh. It says /bin/sh: 1: source: not found /bin/sh: 1: mkvirtualenv: not found
Needs to be ., not source, for compatibility with /bin/sh. That is to say: . ~/.bashrc (assuming the file is otherwise written for compatibility with baseline-POSIX shells)
Alternately, one can RUN ["/bin/bash", "-c", "source ~/.bashrc; mkvirtualenv dharmesh"] to explicitly specify bash.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.