Served many pages and forums and didn't find a solution. I have the simple docker container with executable .sh file. When I build and run it from Windows - all is fine. Now trying to build it from Ubuntu 18.04 with Docker version 19.03.5.
For rebuild use .sh script that I execute as bash install.sh
go build -o main.sh ./main
docker stop stats
docker container rm stats
docker image rm stats
docker build -t stats .
docker run --name stats -p 8080:8080 stats
My Dockerfile is:
FROM alpine:3.10.1
ARG appPath="app"
RUN mkdir /app/
COPY main.sh /app/main.sh
RUN chmod +x /app/main.sh
COPY resources /app/resources
RUN apk add --no-cache bash
WORKDIR /app
EXPOSE 8080
CMD /bin/bash -c 'ls' && /app/main.sh dev
The output 'install' call is the following:
bash install.sh
stats
stats
Untagged: stats:latest
Sending build context to Docker daemon 38.98MB
Step 1/10 : FROM alpine:3.10.1
---> b7b28af77ffe
Step 2/10 : ARG appPath="app"
---> Using cache
---> 08baa7336701
Step 3/10 : RUN mkdir /app/
---> Using cache
---> fb9870e78322
Step 4/10 : COPY main.sh /app/main.sh
---> Using cache
---> 79bf713855e3
Step 5/10 : RUN chmod +x /app/main.sh
---> Using cache
---> 88bf70f9c6ec
Step 6/10 : COPY resources /app/resources
---> Using cache
---> 2ebf95627a9e
Step 7/10 : RUN apk add --no-cache bash
---> Using cache
---> 39cd823e7f2f
Step 8/10 : WORKDIR /app
---> Using cache
---> 37e6fcea2d65
Step 9/10 : EXPOSE 8080
---> Using cache
---> 4250094c65f6
Step 10/10 : CMD /bin/bash -c 'ls' && /app/main.sh dev
---> Using cache
---> ed41a1efb15b
Successfully built ed41a1efb15b
Successfully tagged stats:latest
main.sh
resources
/bin/sh: /app/main.sh: not found
I don't understand what is wrong. main.sh is there. If I try to execute CMD /bin/bash -c 'ls' && bash main.sh dev then receive main.sh: main.sh: cannot execute binary file.
What is wrong there and how can I fix it?
UPD:
Renamed file that this was binary and shouldn't have .sh in the end.
And tryed again wi the following:
install.sh
#!/bin/bash
go build -o myapp ./main
docker stop stats
docker container rm stats
docker image rm stats
docker build -t stats .
docker run --name stats -p 8080:8080 stats
Dockerfile
FROM alpine:3.10.1
RUN mkdir /app/
COPY myapp /app/myapp
RUN chmod +x /app/myapp
COPY resources /app/resources
RUN apk add --no-cache bash
WORKDIR /app
EXPOSE 8080
CMD /bin/bash -c 'ls' && ./myapp dev
Output was the following:
....
Step 9/9 : CMD /bin/bash -c 'ls' && ./myapp dev
---> Running in 52fc24d26747
Removing intermediate container 52fc24d26747
---> 8d4f415e6dcd
Successfully built 8d4f415e6dcd
Successfully tagged stats:latest
myapp
resources
/bin/sh: ./myapp: not found
Tryed /app/myapp, ./myapp and it doesn't work.
I'm guessing the error message is misleading, and that the real problem is that some library or other Go runtime component is missing from inside your Docker image. Try building your app statically (which means all the things it needs will be bundled into the binary).
CGO_ENABLED=0 go build -o myapp ./main
(And yeah, don't call it main.sh if it's not a shell script. Unix doesn't care, but you are confusing the hell out of your human readers. And actually, don't call it that even if it is. You don't need to know whether grep is a binary, a shell script, or a Python program; the same convention makes sense for your own tools.)
Related
So I've just created my very first docker image (woohoo) and was able to run it on the original host system where it was created (Ubuntu 20.04 Desktop PC). The image was executed using docker run -it <image_id>. The expected command (defined in CMD which is just a bash script) was run, and the expected output was seen. I assumed this meant I successfully created my very first docker image and so I pushed this to Docker Hub.
Docker Hub
GitHub repo with original docker-compose.yml and Dockerfile
Here's the Dockerfile:
FROM ubuntu:20.04
# Required for Debian interaction
# (https://stackoverflow.com/questions/62299928/r-installation-in-docker-gets-stuck-in-geographic-area)
ENV DEBIAN_FRONTEND noninteractive
WORKDIR /home/benchmarking-programming-languages
# Install pre-requisites
# Versions at time of writing:
# gcc -- version (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
# make -- GNU Make 4.2.1
# curl -- 7.68.0
RUN apt update && apt install make build-essential curl wget tar -y
# Install `column`
RUN wget https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.35/util-linux-2.35-rc1.tar.gz
RUN tar xfz util-linux-2.35-rc1.tar.gz
WORKDIR /home/benchmarking-programming-languages/util-linux-2.35-rc1
RUN ./configure
RUN make column
RUN cp .libs/column /bin/
WORKDIR /home/benchmarking-programming-languages
RUN rm -rf util-linux-2.35-rc1*
RUN apt install python3 pip -y
RUN ln -s /usr/bin/python3 /usr/bin/python
RUN apt install default-jdk-headless -y
RUN apt install rustc -y
# Install GoLang
RUN wget https://go.dev/dl/go1.17.8.linux-amd64.tar.gz
RUN rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.8.linux-amd64.tar.gz
ENV PATH="/usr/local/go/bin:${PATH}"
# Install Haxe and Haxelib
RUN wget https://github.com/HaxeFoundation/haxe/releases/download/4.2.5/haxe-4.2.5-linux64.tar.gz
RUN tar xfz haxe-4.2.5-linux64.tar.gz
RUN ln -s /home/benchmarking-programming-languages/haxe_20220306074705_e5eec31/haxe /usr/bin/haxe
RUN ln -s /home/benchmarking-programming-languages/haxe_20220306074705_e5eec31/haxelib /usr/bin/haxelib
# # Install Neko (Haxe VM)
# RUN add-apt-repository ppa:haxe/snapshots -y
# RUN apt update
# RUN apt install neko -y
RUN if ! test -d /home/benchmarking-programming-languages; then mkdir /home/benchmarking-programming-languages && echo "Created directory /home/benchmarking-programming-languages."; fi
COPY . /home/benchmarking-programming-languages
RUN pip install -r /home/benchmarking-programming-languages/requirements_dev.txt
CMD [ "/home/benchmarking-programming-languages/benchmark.sh -v" ]
However, upon pulling the same image on my Windows 10 machine (same machine as above just dual booted) and a Windows 11 laptop using both the Docker Desktop application and the command line (docker pull mariosyian/benchmarking-programming-languages followed by docker run -it <image_id>). Both which give me the following error
Error invoking remote method 'docker-run-container': Error: (HTTP code 400) unexpected - failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/home/benchmarking-programming-languages/benchmark.sh -v": stat /home/benchmarking-programming-languages/benchmark.sh -v: no such file or directory: unknown
Despite this, running the image as a container with a shell (docker run -it <image_id> sh), I am successfully able to, not only see the file, but execute it with no errors! Can someone suggest a reason for why the error happens in the first place, and how to fix it?
In your Dockerfile you have specified the CMD as
CMD [ "/home/benchmarking-programming-languages/benchmark.sh -v" ]
This uses the JSON syntax of the CMD instruction, i.e. is an array of strings where the first string is the executable and each following string is a parameter to that executable.
Since you only have a single string specified docker tries to invoke the executable /home/benchmarking-programming-languages/benchmark.sh -v - i.e. a file named "benchmark.sh -v", containing a space in its name and ending with -v. But what you actually intended to do was to invoke the benchmark.sh script with the -v parameter.
You can do this by correctly specifying the parameter(s) as separate strings:
CMD ["/home/benchmarking-programming-languages/benchmark.sh", "-v"]
or by using the shell syntax:
CMD /home/benchmarking-programming-languages/benchmark.sh -v
I need to use bash in the scripts of a CI/CD pipeline, so I'm trying with this simple image:
FROM alpine:3.4
RUN apk update -q && apk add --no-cache bash -q
SHELL ["/bin/bash", "--login", "-c"]
RUN echo $0
What I get in my terminal is this:
$ docker build .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM alpine:3.4
---> b7c5ffe56db7
Step 2/4 : RUN apk update -q && apk add --no-cache bash -q
---> Using cache
---> 18b729da453c
Step 3/4 : SHELL ["/bin/bash", "--login", "-c"]
---> Using cache
---> 03ca0df4a543
Step 4/4 : RUN echo $0
---> Running in a65419dafc4b
/bin/bash
Removing intermediate container a65419dafc4b
---> 2963f9e0e563
Successfully built 2963f9e0e563
After that, I run that container and get this:
$ docker run -it 2963f9e0e563
/ $ echo $0
/bin/sh
/ $
(it runs as root but I changed "#" with "$" for this post)
Why is it using sh instead of bash?
The SHELL command only modifies the shell that is used to execute the instructions inside the Dockerfile.
If you want to change the shell that's used for the container runtime, you can add CMD ["/bin/bash"] to your Dockerfile in order to change the container default executable to /bin/bash. You could also specify the executable from the command line using docker run -it <image> /bin/bash.
[this is the error I'm getting after build command ]
Step 7/9 : RUN chmod +x /main.sh
---> Running in 6e880a009c7d
chmod: cannot access '/main.sh': No such file or directory
The command '/bin/sh -c chmod +x /main.sh' returned a non-zero code: 1
and here is my docker file
FROM centos:latest
MAINTAINER Aditya Gupta
#install git
RUN yum -y update
RUN yum -y install git
#make git repo folder, change GIT_LOCATION
RUN mkdir -p /home/centos/doimages/dockimg;cd /home/centos/doimages/dockimg;
RUN git clone https://(username):(password)#gitlab.com/abc/xyz.git (foldername);cd (foldername)/
Run chmod +x ./main.sh
RUN echo " ./main.sh\n "
EXPOSE Portnumber
When you perform a RUN step in a Dockerfile, a temporary container is launched, often with a shell parsing your command. When that command finishes, the container exits, and docker packages the filesystem changes as an image layer. That process is repeated from the beginning for each RUN line.
The key piece there is the shell exits, losing environment variables you've set, background processes you've run, and in this case, the current working directory you tried to set here:
RUN git clone https://(username):(password)#gitlab.com/abc/xyz.git (foldername);cd (foldername)/
Instead of a cd in a RUN command, you can update the value of WORKDIR:
RUN git clone https://(username):(password)#gitlab.com/abc/xyz.git (foldername)
WORKDIR foldername
You want to execute a shell file which does not exist on your docker machine. use ADD command to add your script to your docker image!
-- somewehe inside your dockerfile befor the execution ---
ADD ./PATH/ON/HOST/main.sh /PATH/YOU/LIKE/ON/DOCKER/MACHINE
Then try to build your docker machine
issue is resolved with workdir and cloning manually without docker file and then give the path to mainsh in dockerfile.
Running Docker Toolbox on Windows 10 host.
There is a Dockerfile:
FROM 16.04
...
RUN if [ some_condition ]; then ./foo.sh; fi
...
There is a foo.sh:
#!/bin/bash
...
echo 'Me working'
Now when trying to build the Docker image:
docker build -t name_of_the_image .
Getting error:
Step 7/12 : RUN ./foo.sh
---> Running in e7e0703d3f8f
/bin/sh: 1: ./foo.sh: not found
The command '/bin/sh -c ./foo.sh' returned a non-zero code: 127
I would assume error 127 would be the Docker doesn't see the bash. Any suggestion how to fix this?
Edit: already copying all files into the Docker, Dockerfile:
FROM ubuntu:16.04
MAINTAINER Mr Anderson "mr#anderson.com"
# set workdir
COPY . /app
WORKDIR /app
# Run scripts
RUN ./foo.sh
You'll need to copy/COPY the file into the container before you can execute/RUN the script.
Also since you're using a relative path when you call the script be sure to set a WORKDIR.
COPY ./foo.sh /app/foo.sh
WORKDIR /dir
RUN chmod +x /app/foo.sh
RUN if [ some_condition ]; then ./foo.sh; fi
Also make sure the script is executable.
After some further investigation:
Using CMD over RUN is not a perfect solution because of the way those commands work. RUN can be used any amount of times, to build Docker image layer by layer, while CMD can be executed only once when the image has been build.
In my case the solution was to:
Open ./foo.sh file with VIM and run: :set fileformat=unix and save the file.
Long story short: the line ending in the shell-script were incorrect and had to be converted to the Unix ones.
I want to run a pre-existing Docker image like so:
docker run -d --name cdt-selenium selenium/standalone-firefox:3.4.0-chromium
So there is no Dockerfile that I control for this image. However, I would like to copy some files into this container.
If I did control the Dockerfile, I would like to run these commands:
RUN mkdir -p /root/cdt-tests/csv-data
COPY ./csv-data/* /root/cdt-tests/csv-data
Is there a way to run those commands in the same line as the Docker run command above?
I tried this:
docker run -d --name cdt-selenium selenium/standalone-firefox:3.4.0-chromium
docker exec cdt-selenium mkdir -p /root/cdt-tests/csv-data
docker cp cdt-selenium:/root/cdt-tests/csv-data ./csv-data
but I get a permissions error on the docker exec line
All images have a FROM line, and that can be any other image. So you can make a Dockerfile with:
FROM selenium/standalone-firefox:3.4.0-chromium
USER root
RUN mkdir -p /root/cdt-tests/csv-data
COPY ./csv-data/* /root/cdt-tests/csv-data
USER seluser
that will build your own image with your commands run.
You'd build it and create your own tag:
docker build -t alexander/selenium:3.4.0-chromium .
And then run it:
docker run -d --name cdt-selenium alexander/selenium:3.4.0-chromium
Edit: the exec command you ran failed because docker runs this container as a different user. You can see that in their Dockerfile. To solve that, run the exec with the root user option (-u root):
docker exec -u root cdt-selenium mkdir -p /root/cdt-tests/csv-data