Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why `~/.bashrc` is not executed when run docker container?

Tags:

I have a docker file as below. launch.sh is the entry point in this docker image.

FROM ubuntu:16.04 USER root  RUN apt-get update && apt-get install -y \         curl \         vim \         net-tools \         git \         iputils-ping \         wget  RUN apt-get install -y python RUN apt-get update && apt-get install -y gcc g++ make libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev  RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash  ENV NVM_DIR /root/.nvm RUN . $NVM_DIR/nvm.sh && \   nvm install 7.9.0 && npm install -g [email protected]  ADD ./Docker/launch.sh /workspace/  CMD ["/bin/sh", "/workspace/launch.sh"] 

The content of launch.sh is:

#!/bin/bash  cd /workspace/demo npm install node index.js 

when I run the docker container: docker run IMAGE_NAME, I got this error:

npm: not found node: not found 

The node in this image is managed by nvm which has been installed and its script has been set on /root/.bashrc file. But I don't know why it can't find the nodejs commands. But if I run the container by docker run -it IMAGE_NAME bash, then manually run workspace/launch.sh command, everything works fine. It seems the ~/.bashrc is not executed when run the image. How can I let the container source .bashrc?

The content of /root/.bashrc is:

# ~/.bashrc: executed by bash(1) for non-login shells. # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) # for examples  # If not running interactively, don't do anything [ -z "$PS1" ] && return  # don't put duplicate lines in the history. See bash(1) for more options # ... or force ignoredups and ignorespace HISTCONTROL=ignoredups:ignorespace  # append to the history file, don't overwrite it shopt -s histappend  # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) HISTSIZE=1000 HISTFILESIZE=2000  # check the window size after each command and, if necessary, # update the values of LINES and COLUMNS. shopt -s checkwinsize  # make less more friendly for non-text input files, see lesspipe(1) [ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"  # set variable identifying the chroot you work in (used in the prompt below) if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then     debian_chroot=$(cat /etc/debian_chroot) fi  # set a fancy prompt (non-color, unless we know we "want" color) case "$TERM" in     xterm-color) color_prompt=yes;; esac  # uncomment for a colored prompt, if the terminal has the capability; turned # off by default to not distract the user: the focus in a terminal window # should be on the output of commands, not on the prompt #force_color_prompt=yes  if [ -n "$force_color_prompt" ]; then     if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then     # We have color support; assume it's compliant with Ecma-48     # (ISO/IEC-6429). (Lack of such support is extremely rare, and such     # a case would tend to support setf rather than setaf.)     color_prompt=yes     else     color_prompt=     fi fi  if [ "$color_prompt" = yes ]; then     PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' else     PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' fi unset color_prompt force_color_prompt  # If this is an xterm set the title to user@host:dir case "$TERM" in xterm*|rxvt*)     PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"     ;; *)     ;; esac  # enable color support of ls and also add handy aliases if [ -x /usr/bin/dircolors ]; then     test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"     alias ls='ls --color=auto'     #alias dir='dir --color=auto'     #alias vdir='vdir --color=auto'      alias grep='grep --color=auto'     alias fgrep='fgrep --color=auto'     alias egrep='egrep --color=auto' fi  # some more ls aliases alias ll='ls -alF' alias la='ls -A' alias l='ls -CF'  # Alias definitions. # You may want to put all your additions into a separate file like # ~/.bash_aliases, instead of adding them here directly. # See /usr/share/doc/bash-doc/examples in the bash-doc package.  if [ -f ~/.bash_aliases ]; then     . ~/.bash_aliases fi  # enable programmable completion features (you don't need to enable # this, if it's already enabled in /etc/bash.bashrc and /etc/profile # sources /etc/bash.bashrc). #if [ -f /etc/bash_completion ] && ! shopt -oq posix; then #    . /etc/bash_completion #fi  export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion 
like image 794
Joey Yi Zhao Avatar asked Mar 17 '19 10:03

Joey Yi Zhao


People also ask

Can you ssh into a running docker container?

The SSH method works fine for Docker containers, too. That said, you can SSH into a Docker container using Docker's built-in docker exec . If you do not need an interactive shell, you can also use the docker attach command to connect the host's stdin and stdout to the running container and execute remote commands.

How do I run a docker container with environment variables?

With a Command Line Argument The command used to launch Docker containers, docker run , accepts ENV variables as arguments. Simply run it with the -e flag, shorthand for --env , and pass in the key=value pair: sudo docker run -e POSTGRES_USER='postgres' -e POSTGRES_PASSWORD='password' ...

What does T flag do with docker run?

The -t (or --tty) flag tells Docker to allocate a virtual terminal session within the container. This is commonly used with the -i (or --interactive) option, which keeps STDIN open even if running in detached mode (more about that later).

Does docker stop save state?

That's why its ideal to have to changes in docker file and in short, there is no save state feature in docker system like we have in virtual machines. The memory contents are always lost.


2 Answers

Each command runs a separate sub-shell, so the environment variables are not preserved and .bashrc is not sourced (see this answer).

You have to source your script manually in the same process where you run your command so it would be:

CMD source /root/.bashrc && /workspace/launch.sh 

provided your launch.sh is an executable.

As per documentation exec form you are using does not invoke a command shell, so it won't work with your .bashrc.

Edit:

BASH wasn't your default shell so

CMD /bin/bash -c "source /root/.bashrc && /workspace/launch.sh" 

was needed in order to run your script. If you want yo set your shell as BASH by default, you can use SHELL instruction as described in documentation, e.g.:

SHELL ["/bin/bash", "-c"] 
like image 74
Szymon Maszke Avatar answered Sep 22 '22 16:09

Szymon Maszke


with CMD and shell form

CMD /bin/bash -i "/workspace/launch.sh" 

Edit should also work with ENTRYPOINT and and using exec form using

ENTRYPOINT ["bash","-i","/workspace/entrypoint.sh"] 

I believe the -i flag works in the intended way, the .bashrc file is used as intended, the other solutions did not work for me, the .bashrc file was never used

solution may not be ideal for everyone, with the -i flag the program may prompt for user interaction

ps: I used docker create and docker start -i "container name"

like image 23
daniel reis Avatar answered Sep 22 '22 16:09

daniel reis