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

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.

  • Keep data in the external folder for mongodb docker container
  • Can Docker help build executable that work in different platform
  • DOCKER + PDO: SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
  • How to configure an Hbase cluster in fully distributed mode using Docker
  • Neo4j 2.3.2 to cloud foundry
  • pip install doesn't work correctly in docker
  • 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/

  • Installing new gentoo kernel in docker container
  • rhel docker usage - start process at container start
  • ODBC Driver 13 for SQL Server can't open lib on pyodbc while connecting on ubuntu docker image
  • Docker container without ipv4 address
  • Profile my app with Blackfire container in Docker environment
  • Boot2Docker on Mac - Accessing Local Files
  • One Solution collect form web for “Why do I have to use bash -l -c inside my container?”

    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
    
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.