Installing libraries in ubuntu image using Docker - docker

I am trying to install the 'sl' package in my ubuntu:14.04 image. Here's the content of my Dockerfile :
FROM ubuntu:14.04
MAINTAINER xyz <xyz#gmail.com>
RUN echo 'Going to install sl now'
RUN apt-get install -y sl
And this is the command I'm using to build the image:
sudo docker build -t xyz/ubuntu:14.04 .
But I'm getting this error message:
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:14.04
---> d0955f21bf24
Step 1 : MAINTAINER xyz <xyz#gmail.com>
---> Using cache
---> a6e08926e788
Step 2 : RUN echo 'Going to install sl now'
---> Using cache
---> 1bf0bc6b3092
Step 3 : RUN apt-get install -y sl
---> Running in f7e57167443f
Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package sl
INFO[0004] The command [/bin/sh -c apt-get install -y sl] returned a non-zero code: 100
Where am I going wrong?

You need to run apt-get update e.g:
RUN apt-get update && apt-get install -y sl
You can also tidy up after yourself to save a bit of disk space:
RUN apt-get update && apt-get install -y sl && rm -r /var/lib/apt/lists/*

You need to update indices on your local ubuntu repository before installing any other package. The right way to do this will be:
RUN apt-get update
RUN apt-get install -y <package-name>
As Adrian mentioned in his answer deleting the downloaded list can be used to save some space on the disk. This is especially helpful when you are pushing the image back to the hub.

Related

Docker: python has no installation candidate

I am trying to create a docker image from my docker file which has the following content:
FROM ubuntu:latest
WORKDIR /app
ADD . /app
RUN apt-get update && apt-get install python -y
CMD python /app/main.py
LABEL color=red
which fails with the following error:
apt-get update && apt-get install python -y returned a non-zero code: 100
So please help me in solving this error
Docker is just Linux. When some apt-get install acme fails, you just need to try the exact command and or research the missing dependencies.
To replicate your error I ran: docker run -it ubuntu:latest and inside, I ran your apt-get update && apt-get install python -y. I got the error:
So, I tried with apt-get install python3 -y and it worked. Finally your Dockerfile should be:
FROM ubuntu:latest
WORKDIR /app
ADD . /app
RUN apt-get update && apt-get install python3 -y
CMD python3 /app/main.py
LABEL color=red
Older Python
If your code needs old python version, you should not use FROM ubuntu:latest because in the lastest version of ubuntu, only python3 is allowed.
Anyway if you need python2, you must research a lot on internet to get the exact steps to install python2 or use some ready to use docker images:
https://hub.docker.com/layers/python/library/python/2.7.18-slim-stretch/images/sha256-a0b3c65a15ba08138460de9fd2267b8dec30ed98407a0edac0adc0ccbe809cad?context=explore
how do i setup only python 2.7 in docker container?
https://github.com/Docker-Hub-frolvlad/docker-alpine-python2

Unable to locate package python

I'm trying to run the below Dockerfile contents on ubuntu image.
FROM ubuntu
RUN apt-get update
RUN apt-get install -y python
RUN apt-get install -y python-pip
RUN pip install flask
COPY app.py /opt/app.py
ENTRYPOINT FLASK_APP=/opt/app.py flask run --host=0.0.0.0
But i'm getting the below error at layer 3.
Step 1/7 : FROM ubuntu
---> 549b9b86cb8d
Step 2/7 : RUN apt-get update
---> Using cache
---> 78d87d6d9188
Step 3/7 : RUN apt-get install -y python
---> Running in a256128fde51
Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package python
Athough while I run the below command individually
sudo apt-get install -y python
It's successfully getting installed.
Can anyone please help me out.
Note: I'm working behind organization proxy.
Step 2/7 : RUN apt-get update
---> Using cache
You should run apt-get update and apt-get install in the same RUN instruction as follows
RUN apt-get update && apt-get install -y python
Each instruction in a Dockerfile will create separate layer in the image and the layers are cached. So the apt-get update might just use cache and not even run. This has happened in your case as well. You can see the line ---> Using cache in your logs. You can use docker build --no-cache to make docker rebuild all the layers without using cache.
You can instead just use python:3 official image as base image to run your python apps.
In the python installation tutorial there is a package name python3.x for Debian.
I think this is your case. I tested it in the Docker and this is right configuration
looks like
From ubuntu:20.04
RUN apt-get update && apt-get -y install python3.8 python3.8-dev
I feel you should rather use Python3 's image instead of using ubuntu and then installing it.
FROM python:3
RUN apt-get update && apt-get install -y python3-pip #You don't need to install pip, because it is already there in python's image
RUN pip install -r requirements.txt
COPY . /usr/src/apps #This you can change
WORKDIR /usr/src/apps/ #this as well
CMD ["python","app.py"]
Try the following, it worked for me
apt-get install python3-pip
And then for installing flask you will have to use
pip3 install flask

How hash IDs are managed for each RUN statements in Dockfile?

For example, I may have the following Dockfile. When I run docker build, for each RUN, there is a spearate hash (e.g., 1d9c17228a9e), and it runs very fast it had run already. I guess each hash is associated an actual file at the backend. Is it so?
If there are separate files, how they can be loaded in a single virtual machine quickly? Is there any kind of assemble upon starting a new virtual machine (docker container)? Thanks.
$ docker build -t ubtsrv .
Sending build context to Docker daemon 12.29kB
Step 1/22 : FROM ubuntu
---> 1d9c17228a9e
Step 2/22 : RUN rm -rf /etc/dpkg/dpkg.cfg.d/excludes
---> Using cache
---> eb02f606ba08
Step 3/22 : RUN apt-get -y update && dpkg -l | grep ^ii | cut -d' ' -f3 | xargs apt-get install -y --reinstall
---> Using cache
---> 7062816b0023
Step 4/22 : RUN apt-get -y install apt-utils
---> Using cache
---> b89d4cdb791c
Step 5/22 : RUN apt -y update && apt -y upgrade
---> Using cache
---> 8100af2b7f2e
Step 6/22 : RUN apt-get -y install vim
---> Using cache
---> 57c142f99935
Step 7/22 : RUN apt-get -y install man
---> Using cache
---> ddb73e4bbddc
Step 8/22 : RUN apt-get -y install gawk
---> Using cache
---> 7422b4371c16
Step 9/22 : RUN apt-get -y install mawk
---> Using cache
---> 53a01709a342
Step 10/22 : RUN apt-get -y install build-essential
---> Using cache
---> af94947e6922
Step 11/22 : RUN apt-get -y install command-not-found
---> Using cache
---> 20094698a583
Step 12/22 : RUN apt-get -y install clang
---> Using cache
---> e63570058a57
Step 13/22 : RUN apt-get -y install htop
---> Using cache
---> b09fec30dc23
Step 14/22 : RUN apt-get -y install wget
---> Using cache
---> d2794d29f9ee
Step 15/22 : RUN apt-get -y install curl
---> Using cache
---> 2b122c49f3ca
Step 16/22 : RUN wget -q ftp://ftp.gnu.org/gnu/bash/bash-4.4.18.tar.gz && tar xzvf bash-4.4.18.tar.gz && cd bash-4.4.18 && ./configure && make -j && make install && cd .. && rm -rf bash-4.4.18.tar.gz bash-4.4.18
---> Using cache
---> c4bf046aff2a
Step 17/22 : RUN apt-get install -y git
---> Using cache
---> 40ebefa7acda
Step 18/22 : RUN apt-get install -y ack
---> Using cache
---> 05cefb3f0496
Step 19/22 : RUN apt-get install -y info
---> Using cache
---> 3361e4e4e06f
Step 20/22 : RUN apt-get install -y llvm
---> Using cache
---> 50b7c75fc2f5
Step 21/22 : RUN apt-get install -y graphviz
---> Using cache
---> 80f89477930c
Step 22/22 : RUN apt-get install -y cmake
---> Using cache
---> c8320b1b2523
Successfully built c8320b1b2523
Successfully tagged ubtsrv:latest
$ cat Dockerfile
FROM ubuntu
RUN rm -rf /etc/dpkg/dpkg.cfg.d/excludes
RUN apt-get -y update && \
dpkg -l | grep ^ii | cut -d' ' -f3 | xargs apt-get install -y --reinstall
RUN apt-get -y install apt-utils
RUN apt -y update && apt -y upgrade
RUN apt-get -y install vim
RUN apt-get -y install man
RUN apt-get -y install gawk
RUN apt-get -y install mawk
RUN apt-get -y install build-essential
RUN apt-get -y install command-not-found
RUN apt-get -y install clang
RUN apt-get -y install htop
RUN apt-get -y install wget
RUN apt-get -y install curl
RUN wget -q ftp://ftp.gnu.org/gnu/bash/bash-4.4.18.tar.gz && \
tar xzvf bash-4.4.18.tar.gz && \
cd bash-4.4.18 && \
./configure && \
make -j && \
make install && \
cd .. && \
rm -rf bash-4.4.18.tar.gz bash-4.4.18
RUN apt-get install -y git
RUN apt-get install -y ack
RUN apt-get install -y info
RUN apt-get install -y llvm
RUN apt-get install -y graphviz
RUN apt-get install -y cmake
Each hash is a docker layer. It's just a filesystem layer containing the different files added in that step. If you dip into docker internals you can actually take a look at the specific files that were added.
This section on docker caching describes how docker decides what is cached and what is not: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache
This tool is a lot of fun: https://github.com/wagoodman/dive an easy way to explore your docker images and check out the contents of each layer.
Let's talk through an example dockerfile:
FROM alpine
WORKDIR /opt/
RUN touch foo && mkdir bar && touch bar/foo
RUN rm foo && touch file.txt
RUN rm -rf bar
Here's the build output:
Building app
Step 1/5 : FROM alpine
---> 196d12cf6ab1
Step 2/5 : WORKDIR /opt/
---> Running in 2098e27c28b9
Removing intermediate container 2098e27c28b9
---> 74634b6a7dcd
Step 3/5 : RUN touch foo && mkdir bar && touch bar/foo
---> Running in f109a620ebfd
Removing intermediate container f109a620ebfd
---> dea70d465cc1
Step 4/5 : RUN rm foo && touch file.txt
---> Running in 367e61e301ba
Removing intermediate container 367e61e301ba
---> 9dcca4810268
Step 5/5 : RUN rm -rf bar
---> Running in d176de336110
Removing intermediate container d176de336110
---> 2e2eee6b9bf8
Successfully built 2e2eee6b9bf8
Successfully tagged docker-fsl_app:latest
If I run docker inspect 2e2eee6b9bf8 (the outputed hash above) docker returns a bunch of data. Included in that are two sections:
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/de87e6b38f95b44137409b5a61b498781473bc05cfd74a01dd641245219c2a1f/diff:/var/lib/docker/overlay2/02d58096fd47908c82edbc34dd0205541e525afe804e88f517ff47ccf3beeee0/diff:/var/lib/docker/overlay2/91fb3592a0da4847071a51e7dda4f48b810a5d1ff0b22e34bb38a0ee52d13d09/diff:/var/lib/docker/overlay2/2e966b19c5984548a6adb172d092dd21b2bb73f6be839baa680dc524d5221063/diff",
"MergedDir": "/var/lib/docker/overlay2/3216972ae99360398a74720226b26b61f0c04142ad6aaa519c1a9dd36f7fb945/merged",
"UpperDir": "/var/lib/docker/overlay2/3216972ae99360398a74720226b26b61f0c04142ad6aaa519c1a9dd36f7fb945/diff",
"WorkDir": "/var/lib/docker/overlay2/3216972ae99360398a74720226b26b61f0c04142ad6aaa519c1a9dd36f7fb945/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:df64d3292fd6194b7865d7326af5255db6d81e9df29f48adde61a918fbd8c332",
"sha256:b9f91d14f5d797f43eeb5b56264cc697641d50dd5e9d17bf89f33cf0694f6559",
"sha256:97195b4b7c22c7eb8720edeb93feeb6901a34018ce1f3c90dc17f861438abf21",
"sha256:0f3d56ac5865b537686b1e324dfbf54edde5afd06e644903ad6b9af42eab01df",
"sha256:5ff5ef92db130446e0af4836ffba8fbf29d06643aa05a104cb4c7a4c9e462fc7"
]
},
I'm on osx. On osx I can run screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty to access the docker vm. Within the vm, I can actually look at the filesystem layers.
These are the layers in reverse order: /var/lib/docker/overlay2/de87e6b38f95b44137409b5a61b498781473bc05cfd74a01dd641245219c2a1f/diff:/var/lib/docker/overlay2/02d58096fd47908c82edbc34dd0205541e525afe804e88f517ff47ccf3beeee0/diff:/var/lib/docker/overlay2/91fb3592a0da4847071a51e7dda4f48b810a5d1ff0b22e34bb38a0ee52d13d09/diff:/var/lib/docker/overlay2/2e966b19c5984548a6adb172d092dd21b2bb73f6be839baa680dc524d5221063/diff
If you go to those locations you'll see just the files added or removed in that layer. So if I go to /var/lib/docker/overlay2/de87e6b38f95b44137409b5a61b498781473bc05cfd74a01dd641245219c2a1f/diff/opt within the vm and run ls -lah. This is the output:
drwxr-xr-x 2 root root 4.0K Jan 14 16:15 .
drwxr-xr-x 3 root root 4.0K Jan 14 16:15 ..
-rw-r--r-- 1 root root 0 Jan 14 16:15 file.txt
c--------- 1 root root 0, 0 Jan 14 16:15 foo
file.txt has been added and foo has been deleted (I think that's why foo doesn't have permissions, the specific details of what a "deleted" file is is unclear to me).
So for every build layer the diff of files added or deleted is added as a lyaer.

add-apt-repository fails during docker build

I am trying to get the dordoka/tomcat docker image up and running, but I get this error when running docker build:
Cannot add PPA: 'ppa:~webupd8team/ubuntu/y-ppa-manager'.
ERROR: '~webupd8team' user or team does not exist.
The command '/bin/sh -c apt-get update &&
apt-get install -y software-properties-common &&
add-apt-repository -y ppa:webupd8team/y-ppa-manager &&
add-apt-repository -y ppa:webupd8team/ubuntu/y-ppa-manager &&
apt-get update &&
apt-get install -y git build-essential curl wget software-properties-common'
returned a non-zero code: 1
The command that is failing is add-apt-repository -y ppa:webupd8team/ubuntu/y-ppa-manager. This command runs fine outside of docker. The proxy is configured correctly, as far as I can tell. Any ideas?
#mlowry Is there a particular reason why you have to run this as root?
I assume that when you run it as your user you have also the http_proxy exported ?
In this case you could youse --build-args to pass the http_proxy string.
Quick example:
ubuntu#ip-172-31-10-207:~/test$ docker build --build-arg http_proxy=$http_proxy .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM alpine:latest
---> e21c333399e0
Step 2/4 : ARG http_proxy
---> Running in fd0832692097
Removing intermediate container fd0832692097
---> 4c58ddefe37c
Step 3/4 : RUN export HTTP_PROXY=$http_proxy
---> Running in 913dc802ea8f
Removing intermediate container 913dc802ea8f
---> 9c3280343c13
Step 4/4 : RUN env
---> Running in 0d078193475a
HOSTNAME=0d078193475a
SHLVL=1
HOME=/root
http_proxy=http://domain\user:pass#proxy.com:8080
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
Removing intermediate container 0d078193475a
---> d4b8996fbb09
Successfully built d4b8996fbb09

docker error Unable to locate package cowsay

When I am running the build command:
$ docker build -t cowsay .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM
Unknown instruction: FROM
dev#ub:~/cowsay$ docker build -t cowsay .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM ubuntu:14.04
---> 90d5884b1ee0
Step 2 : RUN apt-get -y install cowsay
---> Running in 587aaba2824b
Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package cowsay
The command '/bin/sh -c apt-get -y install cowsay' returned a non-zero code: 100
Content of Dockerfile is as follow:
FROM ubuntu:14.04
RUN apt-get -y install cowsay
RUN apt-get -y install fortune
ENTRYPOINT ["/usr/games/cowsay"]
CMD ["Docker is so awesomoooooooo!"]
ONBUILD RUN /usr/games/fortune | /usr/games/cowsay
How can I avoid this error message?
Try and add RUN apt-get update first.
Once the packages are updated, you can install, for instance, cowsay.
See for instance this Dockerfile as an example of RUN apt-get commands:
FROM debian:jessie
RUN apt-get update && apt-get install -y cowsay
COPY docker.cow /usr/share/cowsay/cows/docker.cow
ENTRYPOINT ["/usr/games/cowsay","-f","docker"]
CMD ["moby","dock"]

Resources