micromamba-docker
micromamba-docker copied to clipboard
Activate Conda and Mamba if possible
Currently we automatically initialize Micromamba. However, when they are installed, we do not automatically initialize Conda or Mamba. Since these tools are so closely related, it seems natural to me that we could extend the activation logic.
This resolves the following error messages.
$ docker run --rm -i mambaorg/micromamba
(base) mambauser@c044080d3465:/tmp$ micromamba install -y -c conda-forge conda
(base) mambauser@c044080d3465:/tmp$ bash
(base) mambauser@c044080d3465:/tmp$ conda activate base
...
CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
To initialize your shell, run
$ conda init <SHELL_NAME>
Currently supported shells are:
- bash
- fish
- tcsh
- xonsh
- zsh
- powershell
See 'conda init --help' for more information and options.
IMPORTANT: You may need to close and restart your shell after running 'conda init'.
and similarly for Mamba
$ docker run --rm -i mambaorg/micromamba
(base) mambauser@c044080d3465:/tmp$ micromamba install -y -c conda-forge mamba
(base) mambauser@c044080d3465:/tmp$ bash
(base) mambauser@c044080d3465:/tmp$ mamba activate base
Run 'mamba init' to be able to run mamba activate/deactivate
and start a new shell session. Or use conda to activate/deactivate.
Assuming there are no objections, I'll provide tests at some point.
Hey @maresb - I wanted to think about this one for a little while, as the proposed functionality goes a little beyond supporting micromamba in a container. But I do see some benefit and not much downside, so I'd support a more fleshed out PR. As always, thanks for contributing!
Anything beyond tests that you have in mind for fleshing this out?
I don't think any documentation in the README.md is needed, but we should have a mention in the CHANGELOG.md.
I would be interested in having this feature as well. Possible to merge?
I'm not sure whether or not @wholtz would be willing to merge without tests. I simply haven't managed to find the time to write any tests. :disappointed:
@hadim if you manage to find some time, you're welcome to write some tests yourself. (I invited you to my fork.)
I have added a test file but it does not work. I am not sure how test activation mechanisms during a Docker build. @wholtz could you help here?
Thanks @hadim for the draft test!
To answer your question: to activate inside the Dockerfile, set ARG MAMBA_DOCKERFILE_ACTIVATE=1. The mechanism for that is in _dockerfile_shell.sh.
Ah, sorry, I see you're already doing that!
The use case I had in mind was for docker run and not docker build. In particular, _activate_current_env.sh is sourced from the entrypoint script.
Would it work if you removed the RUN bash -c ... commands from your Dockerfile and then changed the command from ls -1 foobar to conda activate base?
I tried but I keep having messages for conda and mamba saying I need to init the shell first.
I see, that's what we're trying to solve. Unfortunately there are all sorts of Bash shells: all combinations of interactive/non-interactive and login/non-login. It's really hard to get this working correctly, and I can never seem to get them straight in my head.
Could you try adapting it to use faketty like here? I think that might solve this particular case.
As the PR is currently written, _activate_current_env.sh will only install the conda and mamba shell hooks if conda and mamba are in the PATH without any environment activated. I have added a test that works if conda and mamba are placed in the PATH, but I'm not sure that is going to be aligned with the expectations of users.
I'm curious how @maresb envisioned this feature working. Right now I'm leaning more towards an implementation that expands on the current one, so that when an environment containing conda or mamba is activated, then the shell hooks will get installed immediately after environment activation. This probably also means that if conda and mamba are not in the pre-environment PATH, then on environment deactivation, we would want to remove the conda and mamba shell hooks. I'm not sure if there is a clean way for to trigger the removal of the shell hooks on environment deactivation.
Thanks @wholtz for pointing out the inconsistency. I meant to use MAMBA_ROOT_PREFIX in place of CONDA_PREFIX. Does it make more sense now?
I should probably write a few words about the intent of the current implementation, since Bash is so horrendously confusing for me.
The goal is to have conda activate work in the shell spawned by the entrypoint. For example, I want to use this as a base image, install Conda, and allow users to run an interactive shell where conda activate works.
A really nasty Bash pitfall is that running bash -c 'conda activate' will run a non-interactive subshell, so .bashrc won't be sourced, and conda activate will fail. To fix this, we can add -i to the bash command. I'll include a test for this...
I reverted the test I just added... it was working locally, but in CI where there's no TTY it was failing with:
# (from function `assert_output' in file test/test_helper/bats-assert/src/assert_output.bash, line 194,
# in test file test/conda-mamba-activate.bats, line 24)
# `assert_output ""' failed
#
# -- output differs --
# expected :
# actual : the input device is not a TTY
# --
If I were to fix it by also using faketty, then it would be almost identical to my previous test.
@wholtz, is it clear what the current PR accomplishes? If so, is the current test sufficient?
Right now I'm leaning more towards an implementation that expands on the current one, so that when an environment containing
condaormambais activated, then the shell hooks will get installed immediately after environment activation.
I've thought about it a little, and I still don't quite follow your idea yet. Do you have any particular use case in mind? Also, any idea for how to implement it?
The issue with MAMBA_ROOT_PREFIX and CONDA_PREFIX did have me a bit confused. The use case that I was concerned about works now that the prefix variable has been swapped.
Ugh. I did the merge too fast and did rebase instead of a squashed merge. Sorry for leaving a messy history on the main branch.
Do you want to force push a reset on main and I can reopen the pr for a squash merge?
No. I don't want to be doing a reset on anything that is in main. Just kicking myself for not paying enough attention.
I think it's extremely unlikely that anyone pulled main in the past 2 hours. And in case anyone did, I think they'd be able to deal with it.