Some RUNs won't work on docker but will when inside a container - docker

I've got a Dockerfile for some lua and torch related tasks and I'm trying to install some rocks using luarocks.
FROM ubuntu:14.04
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
RUN apt-get update -y
RUN apt-get install -y curl git
RUN curl -s https://raw.githubusercontent.com/torch/ezinstall/master/install-deps | bash
RUN git clone https://github.com/torch/distro.git ~/torch --recursive
RUN cd ~/torch; ./install.sh
RUN source ~/.bashrc
RUN luarocks install nngraph
RUN luarocks install optim
RUN luarocks install nn
RUN luarocks install cltorch
RUN luarocks install clnn
docker build runs fine up until the first luarocks call: RUN luarocks install nngraph at which point it stops and throws the error:
/bin/sh: luarocks: command not found
If I comment out the luarocks lines, the build runs fine. Using that image, I can create a container and using bash, run luarocks as expected.
Of course, I don't particularly want to have to do this every time I start up the container, so I'm wondering if there's anything I can do to make this work. I have a feeling that this problem has something to do with the line RUN rm /bin/sh && ln -s /bin/bash /bin/sh but I need that to be able to run the line RUN source ~/.bashrc.
Thanks.

Each RUN command runs on its own shell and a new layer is committed.
From the Docker documentations:
RUN (the command is run in a shell - /bin/sh -c - shell
form)
So when you run luarocks install <app> it will not be the same shell you source your profile.
You have to provide the full path for luarocks to run. See below a modified Dockerfile I successfully run:
FROM ubuntu:14.04
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
RUN apt-get update -y
RUN apt-get install -y curl git
RUN curl -s https://raw.githubusercontent.com/torch/ezinstall/master/install-deps | bash
RUN git clone https://github.com/torch/distro.git ~/torch --recursive
RUN cd ~/torch; ./install.sh
RUN source ~/.bashrc
RUN /root/torch/install/bin/luarocks install nngraph
RUN /root/torch/install/bin/luarocks install optim
RUN /root/torch/install/bin/luarocks install nn
RUN /root/torch/install/bin/luarocks install cltorch
RUN /root/torch/install/bin/luarocks install clnn
For more details see docker RUN documentation here.

As Alex da Silva pointed it out, sourcing .bashrc happens in another shell in your Dockerfile.
You could also try that to have your luarocks commands executed in the same shell with your sourced bashrc:
...
RUN source ~/.bashrc && luarocks install nngraph
RUN source ~/.bashrc && luarocks install optim
RUN source ~/.bashrc && luarocks install nn
RUN source ~/.bashrc && luarocks install cltorch
RUN source ~/.bashrc && luarocks install clnn

Related

Installed packages in docker image not found in path?

My Dockerfile for custom image with Gradle and Node installed:
FROM ubuntu:jammy
LABEL key=DevOps
SHELL ["/bin/bash", "--login", "-i", "-c"]
RUN apt update && apt upgrade -y && apt install curl -y
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
RUN source /root/.bashrc && nvm install 12.14.1
RUN nvm install 12.20.0
RUN apt install zip unzip
RUN curl -s "https://get.sdkman.io" | bash
RUN source "$HOME/.sdkman/bin/sdkman-init.sh"
RUN sdk install java 8.0.302-open
RUN sdk install gradle 3.4.1
SHELL ["/bin/bash", "--login", "-c"]
CMD [ "bin/bash" ]
After I run it, it says that npm is not found in $PATH, I tried Java, Gradle as well but they weren't found in the path as well.
I don't know why since I installed them as you can tell from the Dockerfile.
How can I preinstall these dependencies so that I can address them during the build process of my app?

GUI menu in docker container freezes (ubuntu parent image)

I've been trying to run a docker container including the esp8266 toolchain and ESP8266_RTOS_SDK.
After the Dockerfile is done the 'Espressif IoT Menu' pops up but freezes instantly and I cant control anything. Screenshot of the menu. I thought maybe I had to run the container endlessly, but it didn't help either. I tried this command: RUN tail -f /dev/null.
What else I thought is that the container might be missing some programs for a terminal?
Here is my Dockerfile (first time working with docker):
FROM ubuntu:latest
# -------------------------- TOOLCHAIN --------------------------------------
WORKDIR /
RUN apt-get update && apt-get install -y software-properties-common
RUN apt update && add-apt-repository universe
RUN apt-get -y install gcc wget git make libncurses-dev flex bison gperf python3 python3-serial python3-pip
RUN mkdir -p downloads esp8266
ADD https://dl.espressif.com/dl/xtensa-lx106-elf-linux64-1.22.0-100-ge567ec7-5.2.0.tar.gz downloads
RUN cd esp8266;tar -xzf /downloads/xtensa-lx106-elf-linux64-1.22.0-100-ge567ec7-5.2.0.tar.gz
ENV PATH=/esp8266/xtensa-lx106-elf/bin:$PATH
# -------------------------- ESP8266_RTOS_SDK ---------------------------------
RUN cd esp8266;git clone https://github.com/espressif/ESP8266_RTOS_SDK.git
ENV IDF_PATH="/esp8266/ESP8266_RTOS_SDK"
RUN ln -s /usr/bin/python3 /usr/bin/python #otherwise python wont be found
ENV TERM xterm #otherwise "terminal unknown"
RUN python3 -m pip install --user -r $IDF_PATH/requirements.txt
RUN cd esp8266;cp -r $IDF_PATH/examples/get-started/hello_world .
RUN cd /esp8266/hello_world;make menuconfig
I run the container with:
sudo docker build -f $(pwd)/dEsp8266 -t espenv .
The guide's I used:
For the toolchain: https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/get-started/linux-setup.html
For the RTOS_SDK: https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/get-started/index.html#get-started-get-esp-idf

Why can't I run command in Dockerfile but I can from within the my Docker container?

I have the following Dockerfile. This is what the "n" package is.
FROM ubuntu:18.04
SHELL ["/bin/bash", "-c"]
# Need to install curl, git, build-essential
RUN apt-get clean
RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y curl
RUN apt-get install -y git
# Per docs, the following allows automated installation of n without installing node https://github.com/mklement0/n-install
RUN curl -L https://git.io/n-install | bash -s -- -y
# This refreshes the terminal to use "n"
RUN . /root/.bashrc
# Install node version 6.9.0
RUN /root/n/bin/n 6.9.0
This works perfectly and does everything I expect.
Unfortunately, after refreshing the terminal via RUN . /root/.bashrc, I can't seem to call "n" directly and instead I have to reference the exact binary using RUN /root/n/bin/n 6.9.0.
However, when I docker run -it container /bin/bash into the container and run the above sequence of commands, I am able to call "n" like so: Shell command: n 6.9.0 with no issues.
Why does the following command not work in the Dockerfile?
RUN n 6.9.0
I get the following error when I try to build my image:
/bin/bash: n: command not found
Each RUN command runs a separate shell and a separate container; any environment variables set in a RUN command are lost at the end of that RUN command. You must use the ENV command to permanently change environment variables like $PATH.
# Does nothing
RUN export FOO=bar
# Does nothing, if all the script does is set environment variables
RUN . ./vars.sh
# Needed to set variables
ENV FOO=bar
Since a Docker image generally only contains one prepackaged application and its runtime, you don't need version managers like this. Install the single version of the language runtime you need, or use a prepackaged image with it preinstalled.
# Easiest
FROM node:6.9.0
# The hard way
FROM ubuntu:18.04
ARG NODE_VERSION=6.9.0
ENV NODE_VERSION=NODE_VERSION
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install --assume-yes --no-install-recommends \
curl
RUN cd /usr/local \
&& curl -LO https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz \
&& tar xjf node-v${NODE_VERSION}-linux-x64.tar.xz \
&& rm node-v${NODE_VERSION}-linux-x64.tar.xz \
&& for f in node npm npx; do \
ln -s ../node-v${NODE_VERSION}-linux-x64/bin/$f bin/$f; \
done

Error in building docker image with perl installation

I am new to docker and i am trying to build the docker image with the perl installation but not sure exactly how to fix this error.
Dockerfile:
FROM amazonlinux
RUN mkdir /shared
RUN cd /shared
RUN yum -y install sudo
RUN cd /shared
RUN echo "Installing Perl."
RUN sudo yum -y update; yum -y install gcc
RUN yum -y install wget
RUN wget http://www.cpan.org/src/5.0/perl-5.22.1.tar.gz
RUN tar -xzf perl-5.22.1.tar.gz
RUN cd perl-5.22.1
RUN /shared/perl-5.22.1/Configure -des -Dprefix=/opt/perl-5.22.1/localperl
RUN make
RUN make test
RUN make install
RUN echo "Perl installation complete."
instead of /shared/perl-5.22.1/Configure i tried to give ./configure as well but i get the same error No such file or directory
Error:
/bin/sh: /shared/perl-5.22.1/Configure: No such file or directory
The command '/bin/sh -c /shared/perl-5.22.1/Configure -des -Dprefix=/opt/perl-5.22.1/localperl' returned a non-zero code: 127
ish-mac:testanalyse ish$
Can anyone tell me how to fix this issue.
Each Dockerfile RUN command runs in its own shell. So, when you do something like RUN cd /shared, the subsequent RUN commands will not be run inside that working directory.
What you want to use in this case is the WORKDIR instruction (https://docs.docker.com/engine/reference/builder/#workdir). You can also combine and shorten some things by taking advantage of the ADD instruction. A more concise Dockerfile to do what you are after might be:
FROM amazonlinux
WORKDIR /shared
RUN yum -y install gcc
ADD http://www.cpan.org/src/5.0/perl-5.22.1.tar.gz /shared
RUN tar -xzf perl-5.22.1.tar.gz
RUN /shared/perl-5.22.1/Configure -des -Dprefix=/opt/perl-5.22.1/localperl
RUN make -C /shared/perl-5.22.1
RUN make -C /shared/perl-5.22.1 test
RUN make -C /shared/perl-5.22.1 install
For example, the build context is already running as root so there is no need for sudo. With ADD we can add directly from URLs and no wget is required. And the make utility has a -C option to specify the working directory for make.
This should get you closer to what you are after. But the build still fails for other reasons (which you should probably open another question for if you are stuck).

not able to start uwsgi as a service in docker

1)I have copied my demo.ini file inside /etc/uwsgi/app-enabled/demo.ini
2)I have installed the package apt-get install uwsgi-plugin-python
3)Added the plugins= python in demi.ini file
now when i hit the command sudo service uwsgi status it shows output which?
FROM base_image
RUN apt-get -y install uwsgi
COPY workspace /home/nt/workspace
RUN ln -s /home/nt/workspace/backend.conf /etc/nginx/sites-enabled/backend.conf
RUN ln -s /home/nt/workspace/nti-backend/environment/development.ini /etc/uwsgi/apps-enabled/
RUN pip install -r /home/nt/workspace/nti-backend/requirements.txt
ENTRYPOINT sh /home/nt/workspace/startup.sh && /bin/bash

Resources