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

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

Related

Ubuntu 20.04 packages missing all mo-files in docker image

For some reason, iso-codes package does not install it's files inside docker image.
Here is what as consider more or less minimal Dockerfile:
FROM ubuntu:20.04
ENV TZ=Etc/UTC
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get upgrade -y && apt-get install -y locales
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LC_ALL=en_US.UTF-8
RUN apt-get update && apt-get install -y iso-codes
RUN ls /usr
I have left locale-related settings in case those are relevant. The same problem appears when I comment all but FROM and RUN apt-get update && apt-get install -y iso-codes out.
Building:
docker build -t 'mytry:1' .
Now when I run the following, I do not see anything in the directory where mo-files should reside:
docker run --cidfile /tmp/docker_test.cid 'mytry:1' ls -R /usr/share/locale/en/LC_MESSAGES/
However, dpkg -l shows it's there:
ii iso-codes 4.4-1 all ISO language, territory, currency, script codes and their translations
And dpkg -L has some files in the directory:
/usr/share/locale/en/LC_MESSAGES
/usr/share/locale/en/LC_MESSAGES/iso_3166-2.mo
/usr/share/locale/en/LC_MESSAGES/iso_3166_2.mo
What is that I am missing? (I am using the specific docker run way just for simplicity. The same problem arises in the normal usage)
I also tried find / -name 'iso_3166-1.mo', but seems like there is no such file anywhere.
Also it seems like poedit-common, which also should have mo files, is missing them, so the problem is more general.
docker -v gives
Docker version 20.10.7, build 20.10.7-0ubuntu5~20.04.2
We have found the reason:
cat /etc/dpkg/dpkg.cfg.d/excludes
# Drop all man pages
path-exclude=/usr/share/man/*
# Drop all translations
path-exclude=/usr/share/locale/*/LC_MESSAGES/*.mo
# Drop all documentation ...
path-exclude=/usr/share/doc/*
# ... except copyright files ...
path-include=/usr/share/doc/*/copyright
# ... and Debian changelogs
path-include=/usr/share/doc/*/changelog.Debian.*
In order to get locales, one should comment out the path-exclude line for /usr/share/locale/... or replace the file. Before installing packages.
Of course, the size of the image can grow as a result.

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

How to fix error occurring during Docker image build: "E: Unsupported file /tmp given on commandline"

I am trying to build an image from Dockerfile and I am getting below error:
E: Unsupported file /tmp given on commandline
This is my dockerfile:
FROM python:3.7-slim-stretch
LABEL version="0.1"
ENV DAEMON_RUN=true
ENV SPARK_VERSION=2.4.4
ENV HADOOP_VERSION=2.7
ENV SCALA_VERSION=2.12.4
ENV SCALA_HOME=/usr/share/scala
ENV SPARK_HOME=/spark
RUN apt-get update -yqq
RUN apt-get install -yqq --no-install-recommends \
wget \
tar \
bash \
vim \
less \
RUN cd "/tmp"
But when i run below line I'm getting mentioned error:
docker build --rm -t test/docker-airflow-spark -f Dockerfile-Spark >.
If i remove the last command : RUN cd "/tmp"
And i try to connect ssh to the container the folder exists
Any ideas?
you need to edit the last line in apt-get command change less \ to less
docker thinks that RUN cd "/tmp" is a parameter for apt-get
anyway you should use WORKDIR if you want to use /tmp for further steps

Use STDIN during docker build from a Dockerfile

I'm trying to install Miniconda in a docker image as a first step, right now this is what I have:
FROM ubuntu:14.04
RUN apt-get update && apt-get install wget
RUN wget *miniconda download URL* && bash file_downloaded.sh
When I try to build the image, it goes well until it starts popping the following message continously:
>>> Please answer 'yes' or 'no'
At that point I need to stop docker build. How can I fix it? Should I include something in the dockerfile?
You can't attach interactive tty during image build. If it is asking for 'yes' or 'no' during package installation, wget in your case, you can replace the corresponding line with RUN apt-get update -qq && apt-get install -y wget. If it is bash file_downloaded.sh, check if file_downloaded.sh accepts 'yes' or 'no' as a command line argument.
If file_downloaded.sh doesn't have that option, create a container from ubuntu:14.04 image, install wget and run your commands manually there. Then, you can make an image of the container by committing your changes like: docker commit <cotainer_id> <image_name>.
I believe you can pass -b flag to miniconda shell script to avoid manual answering
Installs Miniconda3 4.0.5
-b run install in batch mode (without manual intervention),
it is expected the license terms are agreed upon
-f no error if install prefix already exists
-h print this help message and exit
-p PREFIX install prefix, defaults to $PREFIX
something like that:
RUN wget http://......-x86_64.sh -O miniconda.sh
RUN chmod +x miniconda.sh \
&& bash ./miniconda.sh -b

Docker CMD doesn't see installed components

I am trying to build a docker image using the following docker file.
FROM ubuntu:latest
# Replace shell with bash so we can source files
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# Update packages
RUN apt-get -y update && apt-get install -y \
curl \
build-essential \
libssl-dev \
git \
&& rm -rf /var/lib/apt/lists/*
ENV APP_NAME testapp
ENV NODE_VERSION 5.10
ENV SERVE_PORT 8080
ENV LIVE_RELOAD_PORT 8888
# Install nvm, node, and angular
RUN (curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.1/install.sh | bash -) \
&& source /root/.nvm/nvm.sh \
&& nvm install $NODE_VERSION \
&& npm install -g angular-cli \
&& ng new $APP_NAME \
&& cd $APP_NAME \
&& npm run postinstall
EXPOSE $SERVE_PORT $LIVE_RELOAD_PORT
WORKDIR $APP_NAME
EXPOSE 8080
CMD ["node", "-v"]
But I keep getting an error when trying to run it:
docker: Error response from daemon: Container command 'node' not found or does not exist..
I know node is being properly installed because if I rebuild the image by commenting out the CMD line from the docker file
#CMD ["node", "-v"]
And then start a shell session
docker run -it testimage
I can see that all my dependencies are there and return proper results
node -v
v5.10.1
.....
ng -v
angular-cli: 1.0.0-beta.5
node: 5.10.1
os: linux x64
So my question is. Why is the CMD in Dockerfile not able to run these and how can I fix it?
When using the shell to RUN node via nvm, you have sourced the nvm.sh file and it will have a $PATH variable set in it's environment to search for executable files via nvm.
When you run commands via docker run it will only inject a default PATH
docker run <your-ubuntu-image> echo $PATH
docker run <your-ubuntu-image> which node
docker run <your-ubuntu-image> nvm which node
Specifying a CMD with an array execs a binary directly without a shell or a $PATH to lookup.
Provide the full path to your node binary.
CMD ["/bin/node","-v"]
It's better to use the node binary rather than the nvm helper scripts due to the way dockers signal processing works. It might be easier to use the node apt packages in docker rather than nvm.

Resources