How To Activate Conda Environment In Dokcer
Introduction
I am trying to containerize my work using Docker. Since the entire procedure is not organized into a single virtual environment, I need to create multiple virtual environments inside the docker and change the environment through the entrypoint. In summary, the Dockerfile was set up as follows.
FROM condaforge/miniforge3:24.1.2-0
ENV DEBIAN_FRONTEND=noninteractive
RUN conda update -n base -c conda-forge conda
RUN mamba init bash
COPY environment1.yml .
RUN mamba env create -f environment1.yml # env1
COPY environment2.yml .
RUN mamba env create -f environment2.yml # env2
I thought that if I included conda activate env1 in the docker run command, I would be able to run the code in the env1 environment.
docker run test:0.0.1 mamba activate env1 && python3 run.py
>>> Run 'mamba init' to be able to run mamba activate/deactivate
>>> and start a new shell session. Or use conda to activate/deactivate.
Contrary to expectations, it asks to run mamba init. I thought it would be a simple problem, but it wasn’t at all. This post discusses how to resolve this issue.
What ‘mamba init’ does
First, we need to understand what mamba init changes to make mamba work.
While it may have several functions, the most crucial thing this command does is modify the ~/.bashrc file.
It adds the environment settings for using mamba commands to ~/.bashrc, ensuring these settings are automatically applied every time bash starts.
The command looks like this:
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('$HOME/.miniforge3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/opt/conda/etc/profile.d/conda.sh" ]; then
. "/opt/conda/etc/profile.d/conda.sh"
else
export PATH="$HOME/.miniforge3/bin:$PATH"
fi
fi
unset __conda_setup
if [ -f "/opt/conda/etc/profile.d/mamba.sh" ]; then
. "/opt/conda/etc/profile.d/mamba.sh"
fi
# <<< conda initialize <<<
Here, the script that is executed is /opt/conda/etc/profile.d/mamba.sh.
This script must be executed for mamba to work.
Even though mamba init changes ~/.bashrc, the changes are not reflected in the current shell environment, so after mamba init, it says to restart the shell.
This is because the shell starts and executes ~/.bashrc when it is started.
What Happen When Docker Starts
Then, why is the script that is perfectly fine in ~/.bashrc not working when Docker starts?
I found the answer in the appendix of Geniac Documentation.

It turns out that the script that is executed depends on the condition when bash starts.
~/.bashrc is usually executed in an interactive and login state.
However, Docker is non-interactive and does not have a login option.
Therefore, changing ~/.bashrc does not work.
How To Resolve It
So, how do we solve this? The choices are two.
- Execute in an interactive, login shell.
- Execute
/opt/conda/etc/profile.d/mamba.shdirectly.
1 is not feasible.
If we do that, why use Docker?
Therefore, I used the second method.
Execute the script before mamba activate to complete the environment setup.
The final Dockerfile and entrypoint.sh file are as follows.
FROM condaforge/miniforge3:24.1.2-0
ENV DEBIAN_FRONTEND=noninteractive
RUN conda update -n base -c conda-forge conda
RUN mamba init bash
COPY environment1.yml .
RUN mamba env create -f environment1.yml # env1
COPY environment2.yml .
RUN mamba env create -f environment2.yml # env2
RUN echo "#! /bin/bash\n\n" > ~/.bashrc \
&& conda init bash \
&& echo "\nconda activate base" >> ~/.bashrc
ENV BASH_ENV=~/.bashrc
COPY entrypoint.sh .
RUN chmod +x entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
#!/bin/bash
run_in_env() {
. "/opt/conda/etc/profile.d/mamba.sh"
local env=$1
shift
mamba activate $env && "$@"
}
run_in_env env1 python3 ...
So, the environment setup is completed before mamba activate is executed in the entrypoint.