Docker: `exec format error` on `RUN apt update` - docker

This Dockerfile:
FROM ubuntu:latest
COPY . /srv/keller
WORKDIR /srv/keller
RUN DEBIAN_FRONTEND=noninteractive apt-get update
results in
Sending build context to Docker daemon 1.167 MB
Step 0 : FROM ubuntu:latest
---> d9fad37da739
Step 1 : COPY . /srv/keller
---> 0691d53a9ddb
Removing intermediate container 76978e260250
Step 2 : WORKDIR /srv/keller
---> Running in 7d47ac19f397
---> 924513b02e82
Removing intermediate container 7d47ac19f397
Step 3 : RUN DEBIAN_FRONTEND=noninteractive apt-get update
---> Running in 97284e8842bc
exec format error
[8] System error: exec format error
on Raspbian GNU/Linux 9. What is the problem here? Note that this is not about entrypoint/command. This error occurs on apt update.

You are trying to run an intel x86 64 image: ubuntu:latest on a raspberry pi (an ARM64), it cannot work out of the box...
Either you can change your base image to be compatible with your host (ex: arm64v8/ubuntu).
Or you can install qemu:
apt install -y qemu qemu-system-x86 binfmt-support qemu-user-static
and register it in docker:
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

This happened to me while setting up pod in the cloud that runs Debian, while my machine is M1. I had to push some images to a private docker repo, but when I pushed them, I noticed the uploaded ones where not compatible with the architecture of the pod in the cluster.
My fix was pulling the correct image docker pull --platform=linux/amd64 python:3.9.16-buster and then using that one istead of the pulled by just doing docker pull --platform=linux/amd64 python:3.9.16-buster.

you are missing the export and a semi-colon, this should be
RUN export DEBIAN_FRONTEND=noninteractive; apt-get update
or you can use the && syntax
RUN export DEBIAN_FRONTEND=noninteractive && apt-get update

Related

Installing python3.10 in ubuntu container

I am looking for some help in writing docker file for Ubuntu 18.04 version which installs Python3.10.
Currently it is written in such a way that it gets the default version of the Python3 (i.e. 3.6) along with the ubuntu 18.04.
Here the question is, is there any way that I can get the Python3.10 with Ubuntu 18.04? The requirement is to use either slim or non-slim versions of Python3.10 Bulls eye image from docker hub
you can use ubuntu 18 docker image, then install python 3.10 inside it.
FROM ubuntu:18.04
RUN apt-get -y update && apt -get install software-properties-common /
&& add-apt-repository ppa:deadsnakes/ppa && apt install python3.10
I am able to build the image on ubuntu 18.04 by including python3.10
Step-1: Write a docker file
FROM python:3.10-bullseye
RUN mkdir WORK_REPO
RUN cd WORK_REPO
WORKDIR /WORK_REPO
ADD hi.py .
CMD ["python", "-u", "hi.py"]
Step-2: Build the image
docker build -t image_name .
Step-3: Run the docker image
docker run image_name
Step-4: Connect to the container and check the Python version
I hope this would be helpful for someone who is completely new in writing dockerfile.
Many Thanks,
Suresh.

docker image run failing, ipmi_exporter for Prometheus

I'm trying to create a docker image of soundcloud/ipmi-exporter to run with Prometheus on Ubuntu Bionic with Docker 19.03.6, build 369ce74a3c. Docker on my OS X laptop is Docker version 20.10.2, build 2291f61. I am forced to build the (customized) image on my laptop because Bionic has a version of golang that's older than what ipmi-exporter wants, and I'm not allowed to update the Ubuntu server.
Anyway, can someone tell me what I'm doing wrong in my Dockerfile?
# Container image
FROM quay.io/prometheus/golang-builder:1.13-base AS builder
ADD . /go/src/github.com/soundcloud/ipmi_exporter/
RUN cd /go/src/github.com/soundcloud/ipmi_exporter && make
# Container image
FROM ubuntu:18.04
WORKDIR /
RUN apt-get update && apt-get install freeipmi-tools -y --no-install-recommends && rm -rf /var/lib/apt/lists/*
COPY --from=builder /go/src/github.com/soundcloud/ipmi_exporter/ipmi_exporter /bin/ipmi_exporter
EXPOSE 8888
ENTRYPOINT ["ipmi_exporter"]
CMD ["--config.file", "/ipmi_remote.yml"]
CMD ["--web.listen-address=":8889"" "--freeipmi.path=/etc/freeipmi" "--log.level="debug""]
When I run the image all I see is
ipmi_exporter: error: unexpected /bin/sh, try --help
I have ipmi_exporter running on the OS directly and I never configured a config.yml. What config.yml is the Dockerfile author talking about? It's mentioned in the last line of https://github.com/soundcloud/ipmi_exporter/blob/master/Dockerfile
The image lives here: https://github.com/soundcloud/ipmi_exporter The sample/example Dockerfile refers to a config.yaml which this software does not use.
I just can't figure out how to make the image pull in the config file I specify.

Changed file is not picked up by docker

I have a dockerfile looking like this
FROM debian:bullseye-slim
RUN apt-get update; \
apt-get install -y libssl-dev; \
apt-get clean
COPY ./runner /runner
CMD /runner
I build the image like this:
docker build -f RunnerDockerfile -t $(RUNNER_IMG) target/release
Even though my executable (runner) changes, it's not picked up by Docker, i.e. Docker uses the cache.
According to my understanding of the docs, if the hash of a file in a COPY statement is changed, it should be be picked up by Docker.
Example run
md5sum target/release/runner
32169761853677f5f7bc03acb7bbe19b target/release/runner
Then I make a change:
md5sum target/release/runner
0075f725ce4f2cd779706b2fb9f83218 target/release/runner
When rebuilding the Docker images I get this
docker build -f RunnerDockerfile -t "runner:latest" target/release
Sending build context to Docker daemon 513.4MB
Step 1/4 : FROM debian:bullseye-slim
---> f8000d381a2c
Step 2/4 : RUN apt-get update; apt-get install -y libssl-dev; apt-get clean
---> Using cache
---> fcd7212dd477
Step 3/4 : COPY ./runner /runner
---> Using cache
---> 1a79d547a9b5
Step 4/4 : CMD /runner
---> Using cache
---> a45a0fd57dd9
Successfully built a45a0fd57dd9
Successfully tagged runner:latest
I.e. it's using the cache for the COPY.
Am I doing something wrong or is this a bug?

Cannot run my docker image

This is the Dockerfile I created for testing purposes.
FROM ubuntu:latest
MAINTAINER Kapil Gupta "kpgupta98#gmail.com"
RUN apt-get update
RUN apt-get install -y wget
RUN apt-get install -y build-essential tcl8.5
RUN apt-get install -y git
EXPOSE 9999
ENTRYPOINT ["myGit"]
WORKDIR /home
I ran this command for installing the image :
docker build -t mygit .
Output of docker images :
REPOSITORY TAG IMAGE ID CREATED SIZE
mygit latest 1474c446365f 39 minutes ago 414.5 MB
redis latest dc2bd412c10c 7 weeks ago 438.8 MB
ubuntu latest c73a085dc378 9 weeks ago 127.1 MB
Output of docker run -i -t mygit:latest :
docker: Error response from daemon: invalid header field value "oci runtime error: container_linux.go:247: starting container process caused \"exec: \\\"myGit\\\": executable file not found in $PATH\"\n".
I don't understand what the error means and how to correct it. Please explain the error in your answer too.
The issue is this line:
ENTRYPOINT ["myGit"]
You're telling it to run the command "myGit" when it runs the Dockerfile. That program doesn't exist. The ENTRYPOINT reference is here .
If you just want a shell for your testing, you could just change it to:
ENTRYPOINT ["/bin/bash"]

How to force Docker for a clean build of an image

I have build a Docker image from a Docker file using the below command.
$ docker build -t u12_core -f u12_core .
When I am trying to rebuild it with the same command, it's using the build cache like:
Step 1 : FROM ubuntu:12.04
---> eb965dfb09d2
Step 2 : MAINTAINER Pavan Gupta <pavan.gupta#gmail.com>
---> Using cache
---> 4354ccf9dcd8
Step 3 : RUN apt-get update
---> Using cache
---> bcbca2fcf204
Step 4 : RUN apt-get install -y openjdk-7-jdk
---> Using cache
---> 103f1a261d44
Step 5 : RUN apt-get install -y openssh-server
---> Using cache
---> dde41f8d0904
Step 6 : RUN apt-get install -y git-core
---> Using cache
---> 9be002f08b6a
Step 7 : RUN apt-get install -y build-essential
---> Using cache
---> a752fd73a698
Step 8 : RUN apt-get install -y logrotate
---> Using cache
---> 93bca09b509d
Step 9 : RUN apt-get install -y lsb-release
---> Using cache
---> fd4d10cf18bc
Step 10 : RUN mkdir /var/run/sshd
---> Using cache
---> 63b4ecc39ff0
Step 11 : RUN echo 'root:root' | chpasswd
---> Using cache
---> 9532e31518a6
Step 12 : RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
---> Using cache
---> 47d1660bd544
Step 13 : RUN sed 's#session\s*required\s*pam_loginuid.so#session optional pam_loginuid.so#g' -i /etc/pam.d/sshd
---> Using cache
---> d1f97f1c52f7
Step 14 : RUN wget -O aerospike.tgz 'http://aerospike.com/download/server/latest/artifact/ubuntu12'
---> Using cache
---> bd7dde7a98b9
Step 15 : RUN tar -xvf aerospike.tgz
---> Using cache
---> 54adaa09921f
Step 16 : RUN dpkg -i aerospike-server-community-*/*.deb
---> Using cache
---> 11aba013eea5
Step 17 : EXPOSE 22 3000 3001 3002 3003
---> Using cache
---> e33aaa78a931
Step 18 : CMD /usr/sbin/sshd -D
---> Using cache
---> 25f5fe70fa84
Successfully built 25f5fe70fa84
The cache shows that aerospike is installed. However, I don't find it inside containers spawn from this image, so I want to rebuild this image without using the cache. How can I force Docker to rebuild a clean image without the cache?
There's a --no-cache option:
docker build --no-cache -t u12_core -f u12_core .
In older versions of Docker you needed to pass --no-cache=true, but this is no longer the case.
In some extreme cases, your only way around recurring build failures is by running:
docker system prune
The command will ask you for your confirmation:
WARNING! This will remove:
- all stopped containers
- all volumes not used by at least one container
- all networks not used by at least one container
- all images without at least one container associated to them
Are you sure you want to continue? [y/N]
This is of course not a direct answer to the question, but might save some lives... It did save mine.
To ensure that your build is completely rebuild, including checking the base image for updates, use the following options when building:
--no-cache - This will force rebuilding of layers already available
--pull - This will trigger a pull of the base image referenced using FROM ensuring you got the latest version.
The full command will therefore look like this:
docker build --pull --no-cache --tag myimage:version .
Same options are available for docker-compose:
docker-compose build --no-cache --pull
Note that if your docker-compose file references an image, the --pull option will not actually pull the image if there is one already.
To force docker-compose to re-pull this, you can run:
docker-compose pull
The command docker build --no-cache . solved our similar problem.
Our Dockerfile was:
RUN apt-get update
RUN apt-get -y install php5-fpm
But should have been:
RUN apt-get update && apt-get -y install php5-fpm
To prevent caching the update and install separately.
See: Best practices for writing Dockerfiles
Most of information here are correct.
Here a compilation of them and my way of using them.
The idea is to stick to the recommended approach (build specific and no impact on other stored docker objects) and to try the more radical approach (not build specific and with impact on other stored docker objects) when it is not enough.
Recommended approach :
1) Force the execution of each step/instruction in the Dockerfile :
docker build --no-cache
or with docker-compose build :
docker-compose build --no-cache
We could also combine that to the up sub-command that recreate all containers:
docker-compose build --no-cache &&
docker-compose up -d --force-recreate
These way don't use cache but for the docker builder and the base image referenced with the FROM instruction.
2) Wipe the docker builder cache (if we use Buildkit we very probably need that) :
docker builder prune -af
3) If we don't want to use the cache of the parent images, we may try to delete them such as :
docker image rm -f fooParentImage
In most of cases, these 3 things are perfectly enough to allow a clean build of our image.
So we should try to stick to that.
More radical approach :
In corner cases where it seems that some objects in the docker cache are still used during the build and that looks repeatable, we should try to understand the cause to be able to wipe the missing part very specifically.
If we really don't find a way to rebuild from scratch, there are other ways but it is important to remember that these generally delete much more than it is required. So we should use them with cautious overall when we are not in a local/dev environment.
1) Remove all images without at least one container associated to them :
docker image prune -a
2) Remove many more things :
docker system prune -a
That says :
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all images without at least one container associated to them
- all build cache
Using that super delete command may not be enough because it strongly depends on the state of containers (running or not).
When that command is not enough, I try to think carefully which docker containers could cause side effects to our docker build and to allow these containers to be exited in order to allow them to be removed with the command.
With docker-compose try docker-compose up -d --build --force-recreate
I would not recommend using --no-cache in your case.
You are running a couple of installations from step 3 to 9 (I would, by the way, prefer using a one liner) and if you don't want the overhead of re-running these steps each time you are building your image you can modify your Dockerfile with a temporary step prior to your wget instruction.
I use to do something like RUN ls . and change it to RUN ls ./ then RUN ls ./. and so on for each modification done on the tarball retrieved by wget
You can of course do something like RUN echo 'test1' > test && rm test increasing the number in 'test1 for each iteration.
It looks dirty, but as far as I know it's the most efficient way to continue benefiting from the cache system of Docker, which saves time when you have many layers...
You can manage the builder cache with docker builder
To clean all the cache with no prompt:
docker builder prune -af
GUI-driven approach: Open the docker desktop tool (that usually comes with Docker):
under "Containers / Apps" stop all running instances of that image
under "Images" remove the build image (hover over the box name to get a context menu), eventually also the underlying base image

Resources