title: Activating a conda env inside a Docker container when using docker-compose to start Jupyter notebook
body: <p>I have the following <code>Dockerfile</code>.</p>
  
  <pre><code>FROM continuumio/miniconda3:4.5.11
  
  # create a new user (defaults to 'al-khawarizmi')
  USER root
  ARG username=al-khawarizmi
  RUN useradd --create-home --home-dir /home/${username} ${username}
  ENV HOME /home/${username}
  
  # switch to newly created user to avoid running container as root
  USER ${username}
  WORKDIR $HOME
  
  # build and activate the specified conda environment from a file (defaults to 'environment.yml')
  ARG environment=environment.yml
  COPY ${environment} .
  RUN conda env create --file ${environment} &amp;&amp; \
      echo ". /opt/conda/etc/profile.d/conda.sh" &gt;&gt; ~/.bashrc &amp;&amp; \ 
      echo "conda activate $(head -1 ${environment} | cut -d' ' -f2)" &gt;&gt; ~/.bashrc
  </code></pre>
  
  <p>The Dockerfile allows the user to specify a conda environment file as a build arg. Here would be a typical <code>environment.yml file</code>.</p>
  
  <pre><code>name: nessie-py
  
  channels:
    - conda-forge
    - defaults
  
  dependencies:
    - python=3.6
    - "notebook=5.7.*"
    - "matplotlib=3.0.*"
    - "numpy=1.15.*"
    - "pandas=0.23.*"
  </code></pre>
  
  <p>The user can run the image in the standard way and the conda environment will be automatically activated. Running</p>
  
  <pre><code>$ docker run -it image_name:image_tag
  </code></pre>
  
  <p>yields a bash prompt within the Docker container with the conda environment activated.</p>
  
  <pre><code>(environment_name)$
  </code></pre>
  
  <p>Now I would like to use <code>docker-compose</code> to start a Jupyter notebook server within the container (built with a conda environment file specifying Jupyter as a dependency).</p>
  
  <p>When I use the following <code>docker-compose.yml</code></p>
  
  <pre><code>version: "3.7"
  
  services:
    notebook-server:
      build:
        context: ./
      ports:
        - "8888:8888"
      volumes:
        - ./:/home/al-khawarizmi
      command: jupyter notebook --no-browser ip=0.0.0.0  
  </code></pre>
  
  <p>I get the following error.</p>
  
  <pre><code>$ docker-compose up
  Creating network "nessie-py_default" with the default driver
  Creating nessie-py_notebook-server_1 ... done
  Attaching to nessie-py_notebook-server_1
  notebook-server_1  | [FATAL tini (7)] exec jupyter failed: No such file or directory
  nessie-py_notebook-server_1 exited with code 127
  </code></pre>
  
  <p>I suspected that this error meant that the conda environment is not activated. I then tried adding <code>tty: true</code> and <code>stdin_open: true</code> to the <code>docker-compose.yml</code> thinking that this should invoke and interactive bash prompt prior to running the <code>command</code>. This resulted in the same error as above.</p>
  
  <p>I also tried defining a <code>start-notebook.sh</code> script that explicitly activates the conda environment prior to running the notebook.</p>
  
  <pre><code>#!/bin/bash
  set -e
  
  # activate the environment and start the notebook
  conda activate nessie-py
  jupyter notebook --no-browser ip=0.0.0.0
  </code></pre>
  
  <p>results in a different error</p>
  
  <pre><code>$ docker-compose up
  Creating network "nessie-py_default" with the default driver
  Creating nessie-py_notebook-server_1 ... done
  Attaching to nessie-py_notebook-server_1
  notebook-server_1  | 
  notebook-server_1  | CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
  notebook-server_1  | If your shell is Bash or a Bourne variant, enable conda for the current user with
  notebook-server_1  | 
  notebook-server_1  |     $ echo ". /opt/conda/etc/profile.d/conda.sh" &gt;&gt; ~/.bashrc
  notebook-server_1  | 
  notebook-server_1  | or, for all users, enable conda with
  notebook-server_1  | 
  notebook-server_1  |     $ sudo ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh
  notebook-server_1  | 
  notebook-server_1  | The options above will permanently enable the 'conda' command, but they do NOT
  notebook-server_1  | put conda's base (root) environment on PATH.  To do so, run
  notebook-server_1  | 
  notebook-server_1  |     $ conda activate
  notebook-server_1  | 
  notebook-server_1  | in your terminal, or to put the base environment on PATH permanently, run
  notebook-server_1  | 
  notebook-server_1  |     $ echo "conda activate" &gt;&gt; ~/.bashrc
  notebook-server_1  | 
  notebook-server_1  | Previous to conda 4.4, the recommended way to activate conda was to modify PATH in
  notebook-server_1  | your ~/.bashrc file.  You should manually remove the line that looks like
  notebook-server_1  | 
  notebook-server_1  |     export PATH="/opt/conda/bin:$PATH"
  notebook-server_1  | 
  notebook-server_1  | ^^^ The above line should NO LONGER be in your ~/.bashrc file! ^^^
  notebook-server_1  | 
  notebook-server_1  | 
  nessie-py_notebook-server_1 exited with code 1
  </code></pre>
  
  <p>This error suggests that <code>bash</code> is not sourcing <code>~/.bashrc</code> prior to running the script.</p>
  
  <p>I tried explicitly sourcing <code>/opt/conda/etc/profile.d/conda.sh</code> prior to activating the conda environment.</p>
  
  <pre><code>#!/bin/bash
  set -e
  
  # activate the environment and start the notebook
  . /opt/conda/etc/profile.d/conda.sh
  conda activate nessie-py
  jupyter notebook --no-browser ip=0.0.0.0
  </code></pre>
  
  <p>which results in a different error!</p>
  
  <pre><code>$ docker-compose up
  Creating network "nessie-py_default" with the default driver
  Creating nessie-py_notebook-server_1 ... done
  Attaching to nessie-py_notebook-server_1
  notebook-server_1  | Could not find conda environment: nessie-py
  notebook-server_1  | You can list all discoverable environments with `conda info --envs`.
  notebook-server_1  | 
  nessie-py_notebook-server_1 exited with code 1
  </code></pre>
  
  <p>I can check to see which conda envs are discoverable in the container by running</p>
  
  <pre><code>$ docker run -it nessie-py conda info --envs
  </code></pre>
  
  <p>which says that the environment does indeed exist.</p>
  
  <pre><code>$ docker run -it nessie-py_notebook-server conda info --envs
  # conda environments:
  #
  nessie-py                /home/al-khawarizmi/.conda/envs/nessie-py
  base                  *  /opt/conda
  </code></pre>
  
  <p>I am out of ideas at this point. This should be possible.  <a href="https://github.com/caesarnine/data-science-docker-template" rel="nofollow noreferrer">Here</a> is an example of a project with a <code>docker-compose.yml</code> file, a Dockerfile that specifies a conda environment and starts a Jupyter notebook server.</p>
  
  <p>The additional complexities that I need include adding a non-root user to the Dockerfile and creating a new conda environment instead of updating the default <code>base</code> conda environment.</p>