Installing rbenv on docker ubuntu/debian - ruby

I want to install rbenv on Docker which seems to work but I can't reload the shell.
FROM node:0.10.32-slim
RUN \
apt-get update \
&& apt-get install -y sudo
RUN \
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \
&& groupadd r \
&& useradd r -m -g r -g sudo
USER r
RUN \
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv \
&& echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc \
&& echo 'eval "$(rbenv init -)"' >> ~/.bashrc
RUN rbenv # check if it works...
When I run this I get:
docker build .
..
Step 5 : RUN rbenv
/bin/sh: 1: rbenv: not found
From what I understand, I need to reload the current shell so I can install ruby versions. Not sure if I am on the right track.
Also see:
Using rbenv with Docker

The RUN command executes everything under /bin/sh, thus your bashrc is not evaled at any point.
use this
&& export PATH="$HOME/.rbenv/bin:$PATH" \
which would append rbenv to /bin/sh's PATH.
Full Dockerfile
FROM node:0.10.32-slim
RUN \
apt-get update \
&& apt-get install -y sudo
RUN \
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \
&& groupadd r \
&& useradd r -m -g r -g sudo
USER r
RUN \
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv \
&& echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc \
&& echo 'eval "$(rbenv init -)"' >> ~/.bashrc \
&& export PATH="$HOME/.rbenv/bin:$PATH"
RUN rbenv # check if it works...

I'm not sure how Docker works, but it seems like maybe you're missing a step where you source ~/.bashrc, which is preventing you from having the rbenv executable in your PATH. Try adding that right before your first attempt to run rbenv and see if it helps.
You can always solve PATH issues by using the absolute path, too. Instead of just rbenv, try running $HOME/.rbenv/bin/rbenv.
If that works, it indicates that rbenv has installed successfully, and that your PATH is not correctly set to include its bin directory.
It looks from reading the other question you posted that docker allows you to set your PATH via an ENV PATH command, like this, for example:
ENV PATH $HOME/.rbenv/bin:/usr/bin:/bin
but you should make sure that you include all of the various paths you will need.

Related

How to restart the shell in script?

I have a script that installs the pyenv package. Installing it requires adding environment variables, then restarting the shell.
apt install -y make build-essential libssl-dev zlib1g-dev \
> libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev\
> libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python-openssl\
> git
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bashrc
for example after PATH:
exec $SHELL <<EOF1
How can I restart the shell so that the rest of the script continues to run?
Think twice before having a script updating your .bashrc. In particular if you are not the only user of this script, never modify .bashrc automatically. You don't know what's in it, and how the user of your script has carefully handcrafted his .bashrc.
Instead write the settings to a separate file and request the user to source this file from inside his .bashrc (or wherever he wants to do it; perhaps he will prefer .bash_profile for this?). Therefore you do something like
echo 'export PYENV_ROOT="$HOME/.pyenv"' > ~/.pyenv_settings
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.pyenv_settings
source ~/.pyenv_settings
which also ensures that the settings are now performed inside your script.

How to pass docker build command arguments to bash files

I am passing two command line arguments to my docker file like this:
docker build . -t ros-container --build-arg UBUNTU_VERSION=bionic --build-arg ROS_VERSION=melodic
I'm able to access them in my docker file, tho I couldn't get them in my bash files. I have tried both entrypoint and cmd techniques. But, non of them helped me.
Expectation
I want to access the two arguments,UBUNTU_VERSION & ROS_VERSION, from the 'script_init.bash' file. See the project structure.
Project structure
- ros_tutorials-noetic-devel
-Dockerfile
-scripts
-script_init.bash
Dockerfile
FROM ros:melodic-perception-bionic
# install packages
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -q && \
apt-get upgrade -yq && \
apt-get install -yq wget curl git build-essential vim sudo lsb-release locales bash-
completion
# Adjust working directory
RUN locale-gen en_US.UTF-8
RUN useradd -m -d /home/ubuntu ubuntu -p `perl -e 'print crypt("ubuntu",
"salt"),"\n"'` && \
echo "ubuntu ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# declare ros version arg
ARG ROS_VERSION
#declare ubuntu version arg
ARG UBUNTU_VERSION
# setup environment
USER ubuntu
WORKDIR /home/ubuntu
ENV UBUNTU_V=$UBUNTU_VERSION \
ROS_V=$ROS_VERSION
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
CMD COPY ./scripts/script_init.bash /
ENTRYPOINT ["/scripts/script_init.bash /"]
script_init.bash
#!/bin/bash
set -e
export UBUNTU_CODENAME=$UBUNTU_V
export REPO_DIR=$(dirname "$SCRIPT_DIR")
export CATKIN_DIR="$HOME/catkin_ws"
export ROS_DISTRO=$ROS_V
You need to copy the script file into your docker image and execute it correctly.
You should be able to get it working by using this Dockerfile, note the lines at the bottom:
FROM ros:melodic-perception-bionic
# install packages
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -q && \
apt-get upgrade -yq && \
apt-get install -yq \
bash-completion \
build-essential \
curl \
git \
locales \
lsb-release \
sudo \
vim \
wget
# Adjust working directory
RUN locale-gen en_US.UTF-8
RUN useradd -m -d /home/ubuntu ubuntu -p `perl -e 'print crypt("ubuntu", "salt"),"\n"'` && \
echo "ubuntu ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# declare ros version arg
ARG ROS_VERSION
#declare ubuntu version arg
ARG UBUNTU_VERSION
# setup environment
USER ubuntu
WORKDIR /home/ubuntu
ENV UBUNTU_V=$UBUNTU_VERSION \
ROS_V=$ROS_VERSION
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
# Copy your scripts directory into the docker image
COPY --chown=ubuntu:ubuntu scripts scripts
# Make sure you have execute permissions on the script
RUN chmod +x "./scripts/script_init.bash"
# Set your entrypoint to execute the script
ENTRYPOINT ["./scripts/script_init.bash"]
As a note, you could export all of these environment variables in the Dockerfile during the build without needing to execute a script at runtime, e.g. in your dockerfile:
# Export environment variables in Dockerfile
ENV UBUNTU_CODENAME=$UBUNTU_VERSION
ENV REPO_DIR=/home/ubuntu/scripts
ENV CATKIN_DIR=/home/ubuntu/catkin_ws
ENV ROS_DISTRO=$ROS_VERSION
I have finally found a solution that works like charm! Once you add the script folder, you can run it with bash command. In this way, you can pass what ever arguments to any bash file within the script folder.
# setup base image
FROM ros:melodic-perception-bionic
# install packages
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -q && \
apt-get upgrade -yq && \
apt-get install -yq wget curl git build-essential vim sudo lsb-release locales bash-completion
# Adjust working directory
RUN locale-gen en_US.UTF-8
RUN useradd -m -d /home/ubuntu ubuntu -p `perl -e 'print crypt("ubuntu", "salt"),"\n"'` && \
echo "ubuntu ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# declare ros version arg
ARG ROS_VERSION
#declare ubuntu version arg
ARG UBUNTU_VERSION
# setup environment
USER ubuntu
WORKDIR /home/ubuntu
ENV UBUNTU_V=$UBUNTU_VERSION \
ROS_V=$ROS_VERSION
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
# call script files
ADD /scripts /scripts
RUN bash /scripts/script_init.bash

Singularity 3.6.2 Installation

I have problems with installation of singularity 3.6.2 in linux mint, I followed the instructions of https://sylabs.io/guides/3.0/user-guide/installation.html.
I installed the dependencies and Go.
Then I run the command for install the latest version:
export VERSION=3.6.2 && # adjust this as necessary \
mkdir -p $GOPATH/src/github.com/sylabs && \
cd $GOPATH/src/github.com/sylabs && \
wget https://github.com/sylabs/singularity/releases/download/v${VERSION}/singularity-${VERSION}.tar.gz && \
tar -xzf singularity-${VERSION}.tar.gz && \
cd ./singularity && \
./mconfig
The error is:
Configuring for project `singularity' with languages: C, Golang
=> running pre-basechecks project specific checks ...
=> running base system checks ...
checking: host C compiler... cc
checking: host C++ compiler... c++
checking: host Go compiler (at least version 1.13)... not found!
mconfig: could not complete configuration
I have go (go version)
go version go1.15.2 linux/amd64
I don't know what happend!
Thanks so much!
I was struggling with the same error. All the suggestions say that probably you have an older version of Go and that's why. But turned out it's even more important to place Go and Singularity in the right locations.
I found these docs https://github.com/hpcng/singularity/blob/release-3.5/INSTALL.md are the most useful and correct about where to put what in terms of directories.
The key is to clone Singularity in a directory which is GOPATH:
You won't have this directory by default so create it first
$ mkdir -p ${GOPATH}/src/github.com/sylabs && \
cd ${GOPATH}/src/github.com/sylabs && \
git clone https://github.com/sylabs/singularity.git && \
cd singularity
Make sure your singularity is here: {GOPATH}/src/github.com/sylabs/singularity
To summarize:
The Go itself is located here /usr/local/go
GOPATH would be something like home/your_username/go and the singularity will be located inside in e.g. home/your_username/go/src/github.com/sylabs/singularity
The issue was reported in 5099.
# 5320 also mentions:
I deleted the PPO python 3.6 and this worked fine!
Make sure nothing is executed as root, which would have a $PATH different from your current user.
If someone faces this issue, follow this installation guide.
sudo apt-get update && \
sudo apt-get install -y build-essential \
libseccomp-dev pkg-config squashfs-tools cryptsetup
sudo rm -r /usr/local/go
export VERSION=1.13.15 OS=linux ARCH=amd64 # change this as you need
wget -O /tmp/go${VERSION}.${OS}-${ARCH}.tar.gz https://dl.google.com/go/go${VERSION}.${OS}-${ARCH}.tar.gz && \
sudo tar -C /usr/local -xzf /tmp/go${VERSION}.${OS}-${ARCH}.tar.gz
echo 'export GOPATH=${HOME}/go' >> ~/.bashrc && \
echo 'export PATH=/usr/local/go/bin:${PATH}:${GOPATH}/bin' >> ~/.bashrc && \
source ~/.bashrc
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh |
sh -s -- -b $(go env GOPATH)/bin v1.21.0
mkdir -p ${GOPATH}/src/github.com/sylabs && \
cd ${GOPATH}/src/github.com/sylabs && \
git clone https://github.com/sylabs/singularity.git && \
cd singularity
git checkout v3.6.3
cd ${GOPATH}/src/github.com/sylabs/singularity && \
./mconfig && \
cd ./builddir && \
make && \
sudo make install
singularity version

Command `source` doesn't work in Dockerfile

I want build my images, here is my Dockerfile:
FROM ubuntu:16.04
MAINTAINER 'hulei886#aliyun.com'
ENV PHANTOMJS_VERSION 2.1.1
ENV PYTHON_VERSION 3.6.3
# install python3.6.3
RUN apt-get update \
&& apt-get install -y build-essential \
git \
curl \
libssl-dev \
zlib1g-dev \
libncurses5-dev \
libncursesw5-dev \
libreadline-dev \
libsqlite3-dev \
&& apt-get install -y libgdbm-dev \
libdb5.3-dev \
libbz2-dev \
libexpat1-dev \
liblzma-dev \
tk-dev \
&& cd ~ \
&& git clone https://github.com/pyenv/pyenv.git .pyenv \
&& echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc \
&& echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc \
&& echo 'eval "$(pyenv init -)"' >> ~/.bashrc \
&& source ~/.bashrc \
&& curl -L https://raw.githubusercontent.com/yyuu/pyenv- installer/master/bin/pyenv-installer | bash \
&& pyenv install PYTHON_VERSION \
&& pyenv global PYTHON_VERSION \
&& cd .. \
CMD [python]
but when i run "docker build . -t [mytag]",
git clone command didn't clone anything,here is screenshot:
I need help to fix this problem,thanks!
The error message is pretty clear:
/bin/sh: 1: source: not found
No problem with git clone but with source in a /bin/sh shell. You need to use the . (dot) command instead.
When writing a Dockerfile, it's better to test the commands in a container with /bin/sh shell.
In your case, after the source error, there are other errors:
space in the curl URL
env variable wrongly used: missing $ prefix
useless cd ~: only WORKDIR instruction will change the current directory when running containers from the resulting image
CMD instruction wrongly inserted in the RUN instruction
A fixed version would be:
[...]
&& git clone https://github.com/pyenv/pyenv.git .pyenv \
&& echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc \
&& echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc \
&& echo 'eval "$(pyenv init -)"' >> ~/.bashrc \
&& . ~/.bashrc \
&& curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash \
&& pyenv install $PYTHON_VERSION \
&& pyenv global $PYTHON_VERSION
WORKDIR /root
CMD [python]
You have to use source alternative in bash. You can do something like
. somefile
instead of
source somefile

How to run bash function in Dockerfile

I have a bash function nvm defined in /root/.profile. docker build failed to find that function when I call it in RUN step.
RUN apt-get install -y curl build-essential libssl-dev && \
curl https://raw.githubusercontent.com/creationix/nvm/v0.16.1/install.sh | sh
RUN nvm install 0.12 && \
nvm alias default 0.12 && \
nvm use 0.12
The error is
Step 5 : RUN nvm install 0.12
---> Running in b639c2bf60c0
/bin/sh: nvm: command not found
I managed to call nvm by wrapping it with bash -ic, which will load /root/.profile.
RUN bash -ic "nvm install 0.12" && \
bash -ic "nvm alias default 0.12" && \
bash -ic "nvm use 0.12"
The above method works fine, but it has a warning
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
And I want to know is there a easier and cleaner way to call the bash function directly as it's normal binary without the bash -ic wrapping? Maybe something like
RUN load_functions && \
nvm install 0.12 && \
nvm alias default 0.12 && \
nvm use 0.12
Docker's RUN doesn't start the command in a shell. That's why shell functions and shell syntax (like cmd1 && cmd2) cannot being used out of the box. You need to call the shell explicitly:
RUN bash -c 'nvm install 0.12 && nvm alias default 0.12 && nvm use 0.12'
If you are afraid of that long command line, put those commands into a shell script and call the script with RUN:
script.sh
#!/bin/bash
nvm install 0.12 && \
nvm alias default 0.12 && \
nvm use 0.12
and make it executable:
chmod +x script.sh
In Dockerfile put:
RUN /path/to/script.sh

Resources