Using the RUN instruction in a Dockerfile with 'source' does not work

Hugo Rodger-Brown picture Hugo Rodger-Brown · Dec 17, 2013 · Viewed 236.5k times · Source

I have a Dockerfile that I am putting together to install a vanilla python environment (into which I will be installing an app, but at a later date).

FROM ubuntu:12.04

# required to build certain python libraries
RUN apt-get install python-dev -y

# install pip - canonical installation instructions from pip-installer.org
# http://www.pip-installer.org/en/latest/installing.html
ADD https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py /tmp/ez_setup.py
ADD https://raw.github.com/pypa/pip/master/contrib/get-pip.py /tmp/get-pip.py
RUN python /tmp/ez_setup.py
RUN python /tmp/get-pip.py
RUN pip install --upgrade pip 

# install and configure virtualenv
RUN pip install virtualenv 
RUN pip install virtualenvwrapper
ENV WORKON_HOME ~/.virtualenvs
RUN mkdir -p $WORKON_HOME
RUN source /usr/local/bin/virtualenvwrapper.sh

The build runs ok until the last line, where I get the following exception:

[previous steps 1-9 removed for clarity]
...
Successfully installed virtualenvwrapper virtualenv-clone stevedore
Cleaning up...
 ---> 1fc253a8f860
Step 10 : ENV WORKON_HOME ~/.virtualenvs
 ---> Running in 8b0145d2c80d
 ---> 0f91a5d96013
Step 11 : RUN mkdir -p $WORKON_HOME
 ---> Running in 9d2552712ddf
 ---> 3a87364c7b45
Step 12 : RUN source /usr/local/bin/virtualenvwrapper.sh
 ---> Running in c13a187261ec
/bin/sh: 1: source: not found

If I ls into that directory (just to test that the previous steps were committed) I can see that the files exist as expected:

$ docker run 3a87 ls /usr/local/bin
easy_install
easy_install-2.7
pip
pip-2.7
virtualenv
virtualenv-2.7
virtualenv-clone
virtualenvwrapper.sh
virtualenvwrapper_lazy.sh

If I try just running the source command I get the same 'not found' error as above. If I RUN an interactive shell session however, source does work:

$ docker run 3a87 bash
source
bash: line 1: source: filename argument required
source: usage: source filename [arguments]

I can run the script from here, and then happily access workon, mkvirtualenv etc.

I've done some digging, and initially it looked as if the problem might lie in the difference between bash as the Ubuntu login shell, and dash as the Ubuntu system shell, dash not supporting the source command.

However, the answer to this appears to be to use '.' instead of source, but this just causes the Docker runtime to blow up with a go panic exception.

What is the best way to run a shell script from a Dockerfile RUN instruction to get around this (am running off the default base image for Ubuntu 12.04 LTS).

Answer

chobo picture chobo · Aug 1, 2014

RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh"