8

I have a bash alias loaded into a Docker container, in /etc/bash.bashrc. It functions as a shortcut to a commandline PHP script. This is convenient, since anyone can use that alias directly after one logs into the container, with:

$ docker exec -it my-container bash

However, I would also like to be able to use this alias in one-off commands without logging in, like:

$ docker exec -it my-container my-alias

I have tried different variations, such as defining the alias in other places than /etc/bash.bashrc, but I keep running into this error:

rpc error: code = 2 desc = oci runtime error: exec failed: exec: "my-alias": executable file not found in $PATH

Other suggestions I find on the web did not do the trick, so far. Anyone?

4
  • Make a script in the container, and call the script with full path name?
    – bgStack15
    Jul 11, 2016 at 14:05
  • That's definitely a fine idea for a workaround, thanks! However I do wonder why an alias by itself isn't picked up in this context. I thought it should, since it's in /etc/bash.bashrc, and not in f.i. a login based .profile. Jul 11, 2016 at 15:19
  • Have you tried exporting my-alias as an environment variable and then using the following? docker exec -it my-container $my-alias
    – joatd
    Sep 9, 2016 at 1:56
  • What you were attempting was somewhat limited. Bash aliases allow you to declare an alias for an entire command line. It may or may not work (yours doesn't) when you create aliases for portions of a command line. Exporting my-alias as an environment variable for the bash session may be a better approach.
    – joatd
    Sep 9, 2016 at 1:58

5 Answers 5

6

It doesn't due to limitations due to aliases being meant to be used interactively. You can probably hack around this but the easiest solution is by far to simply make your "alias" into a script and place it in /bin.

Dockerfile

RUN echo '#! /bin/sh'                >> /bin/mycommand
RUN echo 'echo "running mycommand!"' >> /bin/mycommand
RUN chmod u+x /bin/mycommand

Then it works as expected

docker exec -it f3a34 mycommand # => running mycommand!
0
1

Aliases are mostly useful when you want to shorten part of a commonly used command which takes variable arguments. In a ruby dev context that might be creating an alias like

alias be="bundle exec"

because who wants to type out bundle exec all the time?

If what you really want is a shorter version of a longer command with static arguments then you should create a script anyway. With a script, it will always be available and not be dependent on sourcing particular profiles in particular contexts (which you can basically never rely on).

A more comman case (like that above) is when you use an alias because you want to effortless string arguments on to the end of the alias. For instance

$ be rails server

or

$ be rake db:migrate

In both cases, i don't want to have to type out more than I need to. With just a dash of bash, however, you can achieve the same thing in a more versatile solution.

Similar to some of the above answers, create a file - /usr/local/bin/be in this example. This assumes that /usr/local/bin is included in your PATH.

#!/usr/bin/env bash

bundle exec "$@"

followed up with (possibly with sudo)

$ chmod +x /usr/local/bin/be

This is a bit of a naive example, and requires that both ruby and the bundler gem have been installed, but the thing to notice is "$@" which let's you pass in a variable number of arguments into the script. Thus, you get the ergonomics of the alias, but with a command that is always available and not context dependent.

I find this approach particularly helpful when working with containers. Hope it helps.

2
  • You should always put $@ (and other shell variables) in quotes:  i.e., bundle exec "$@". Nov 5, 2018 at 4:13
  • Thanks for pointing that out. I went ahead and updated as it's a good habit to be in, but in this case, however, it's not strictly necessary. Nov 6, 2018 at 10:25
1

If you have a script file under your container just add a these RUN.

RUN cat /workdir/bin/doit.sh >> /bin/doit
RUN chmod u+x /bin/doit

to run it:

docker exec -it container_name doit

doit.sh sample

#!/usr/bin/env bash
python manage.py $@
0

It took me a slightly different approach eventually, because I haven't managed to get it to work with the bash.bashrc strategy. @joat is right, an alias is probably an unfortunate combination with the partial execution of a command line (with docker exec).

In the end, I injected a script (in my case through PHP Composer) into the image. In my case by mounting my local directory, although that shouldn't matter. Then I add the path to this script in my Dockerfile through an environment variable:

ENV PATH $PATH:./vendor/bin

This makes the script globally available at runtime.

I do consider it a workaround, still, so interested to hear from anyone who actually got regular aliases to work at docker exec runtime.

2
  • 1
    Please explain in specific detail what the workaround is. I read your answer 5 times and I still don't know what the workaround is.
    – Ramhound
    Dec 5, 2016 at 18:33
  • @Ramhound: Sorry about that, you're right. Did some digging and I found that my eventual solution was in fact slightly different. Will update the answer now. Dec 7, 2016 at 13:01
0

I had this problem and I solved it by wrapping the command I wanted to execute inside a temporary shell, in the example you have it would be done like this:

$ docker exec -it my-container sh -l -c "my-alias"

(the -l flag is only needed if your aliases are only available in login shells, which is my case)

It does make it more verbose, but you can always create an alias or a function to wrap this.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .