Why do I have to use bash -l -c inside my container?

25,022

From bash(1):

  • -l Make bash act as if it had been invoked as a login shell
  • -c If the -c option is present, then commands are read from string.

You're running the command passed to the -c argument. -l makes it a login shell so bash first reads /etc/profile, which probably has the path to rvm which is what makes it work.

FWIW, here's what I do to install rvm in a docker container.

# Install some dependencies
RUN apt-get -y -q install curl rubygems

# Install rvm
RUN curl -L https://get.rvm.io | bash -s stable

# Install package dependencies
RUN /usr/local/rvm/bin/rvm requirements

# Install ruby
RUN /usr/local/rvm/bin/rvm install ruby-2.0.0

# create first wrapper scripts
RUN /usr/local/rvm/bin/rvm wrapper ruby-2.0.0 myapp rake rails gem
Share:
25,022

Related videos on Youtube

Hugo Rodger-Brown
Author by

Hugo Rodger-Brown

Ex-developer, CTO of various companies and now co-founder of YunoJuno, helping to build a community of the very best freelancer developers, designers, UX and associated digital talents.

Updated on February 21, 2020

Comments

  • Hugo Rodger-Brown
    Hugo Rodger-Brown about 4 years

    I've created a docker container using the following Dockerfile (truncated):

    FROM ubuntu:12.04
    # curl enables downloading of other things
    RUN apt-get install curl -y
    # download and install rvm...
    RUN \curl -L https://get.rvm.io | bash -s stable
    # ... so that we can install ruby
    RUN /bin/bash -l -c "rvm requirements"
    

    And so on.

    This all works, but the problem I have is how / where the packages are installed.

    If I just run rvm using docker run [...] rvm I get "Unable to locate rvm", but if I run docker run [...] /bin/bash -l -c "rvm" it works. (I found the "-l -c" options online, but have no idea what they do, and can't find a satisfactory explanation of what I'm doing!)

    This isn't a docker question - it's a bash / *nix question - I presume there's something about how / where things are installed, possibly related to running the install under root?

    Just to be clear - I want to be able to run the things that I install direct from the CLI.

    EDIT 1

    Installing Ruby using rvm is the recommended method, however if you want to run things in a non-interactive, non-login shell (i.e. within a docker container), this just causes too much hassle with paths and environment variables and login scripts not running.

    Given that I am using this to run a docker container, which by definition is isolated, and recoverable (just build another one), I don't really care about switching versions, or isolating packages, and so I've decided to install Ruby from a package repo (http://brightbox.com/docs/ruby/ubuntu/) instead. This 'just works'.

    It may not work for you - I am only installing Ruby in order to get the Foreman gem, as I am running an app through a Procfile, so I'm not that fussed about the details, I just need it to work. If you're building a Ruby app, I wouldn't follow my advice.

    My Dockerfile is here, FWIW, https://index.docker.io/u/yunojuno/dev/

    • Zombo
      Zombo about 10 years
      you should include output from type -ap rvm and echo $PATH
    • jdhao
      jdhao over 4 years
      Adding CMD ["bash", "-l"] to your Dockerfile will also work.
  • Hugo Rodger-Brown
    Hugo Rodger-Brown about 10 years
    Yup - that's it - thanks. If I run docker run [...] bash -l from the host I get into the container with a shell that works - env vars set etc. So it's getting the commands to run within an login shell when I pass them in to the docker run command that's my challenge.
  • Ben Whaley
    Ben Whaley about 10 years
    Perhaps it's just sys admin habit, but I usually like to give fully qualified paths to everything. That way you (hopefully) know what you're running.
  • Hugo Rodger-Brown
    Hugo Rodger-Brown about 10 years
    Yup - that's what I've just done - you beat me to it. And I guess that since the key to Docker is repeatability and reuse, I don't need to worry about things not being where they should be - as they will always be in exactly the same place they were last time.
  • Hugo Rodger-Brown
    Hugo Rodger-Brown about 10 years
    Of course - now I'm getting ruby errors: /usr/bin/env: ruby_executable_hooks: No such file or directory
  • Chris Gunawardena
    Chris Gunawardena over 7 years
    If I do this and try to do RUN gem, then I get a error gem not found. IMHO it's easier to remember the /bin/bash -l -c "" rather than trying to remember the paths of where everything else.