Docker `COPY` file not working - docker

I have a relatively simple dockerfile
FROM python:3.6.5-alpine
COPY somebinary /usr/local/bin/
COPY install.sh /install.sh
RUN /install.sh
The binary gets copied across just fine (when I run the container to check) but the script doesn't seem to get copied across so that when I try to run it I get:
Step 4/5 : COPY install.sh /install.sh
---> 38ecc6dbad13
Step 5/5 : RUN /install.sh
---> Running in 0b06962d6e1b
/bin/sh: /install.sh: not found
The command '/bin/sh -c /install.sh' returned a non-zero code: 127
The same happens with any other test files I make, they aren't available when the image is run. Other people have had success running the exact same script so I suspect it could be to do with the fact that I'm running docker through Git Bash on Windows? Could it be a permissions thing?
e: I went and tried running through powershell and got the same error, so perhaps git bash is a red herring

It seems your install.sh script is having ^M characters.
Try saving your install.sh into unix format. dos2unix
Use notepad++ or sublime or any other editor which support converting end of lines from Windows to UNIX format.

Related

Command from within Docker image doesn't work in Dockerfile RUN statement

EDIT to provide MRE:
Steps to reproduce (using Docker CLI, now, for reproducibility)
project_directory
Dockerfile
directory_to_cd_into
gradlew
Dockerfile:
From debian:9
RUN cd /directory_to_cd_into
# also tried RUN cd ./directory_to_cd_into
Running docker build yields /bin/sh: 1: cd: can't cd to /directory_to_cd_into
So the problem is cd -- which means I must be missing something really basic about container directory structure.
Also tried WORKDIR
Happy to add more info.
Original:
From within my container, I can successfully build using gralde as follows:
cd directory/with/gradlew && chmod +x gradlew && ./gradlew build
But when I put this in my Dockerfile and try to build the container, it fails with "file or directory gradlew does not exist":
RUN cd directory/with/gradlew && chmod +x gradlew && ./gradlew build.
From this question, Unable to change directories while building docker Image using Dockerfile , I am aware that cd resets with every RUN statement -- but I'm doing this all from within a single RUN.
Everything prior to this RUN statement is held constant, i.e., if I comment out the RUN, and build interactively from the command line in the image, it builds fine.
If it matters, I'm doing all this from within a GitHub codespace; I'm not using the Docker CLI directly.
What am I doing wrong?
--
EDIT: I must be trying to include/cd directories from outside the build context. I'm not sure how to fix that yet -- maybe with COPY?

Docker permissions between build and run differ

I just started playing around with Docker yesterday and am having issues between the build environment and the run environment. Build wise I have issues like...
RUN install.sh
/bin/sh: 1: install.sh: Permission denied
the command '/bin/sh -c install.sh' returned a non-zero code: 126
or ...
RUN . sourceme.env
/bin/sh: 1: .: sourceme.env: not found
The command '/bin/sh -c . sourceme.env' returned a non-zero code: 2
I build using 'sudo docker build -t joes' and
I run using 'sudo docker run -it joes'
The frustrating thing is that after build failure I can run it, see that I am in the working directory I expected, and run the command that failed during building successfully. So why the discrepancy?
This is on a linux system and I'm using 'FROM ubuntu:18.04'
To bypass the RUN install.sh error I used
RUN /bin/sh install.sh
which converts to
/bin/sh -c /bin/sh install.sh
Post your entire Dockerfile. The problem is you haven't pointed to the correct location. When you copy it, copy it in and then supply it with the absolute path.
e.g.
COPY install.sh /install.sh
CMD ./install.sh
EDIT: if your containers main job is to run the install.sh script then use it with CMD and not RUN. Use run to build env and evth else.
Using the RUN instruction in a Dockerfile with 'source' does not work Seems to be the bulk of my issue
That along with running multiple RUN commands instead of RUN ... && ... && ... etc

airflow exporter - binary build dockerfile error

When I build binary and package to alpine image for airflow exporter with my Dockerfile I am getting error.
Not sure how to fix this error.
+++++ Error while docker build +++++++++
---> Running in caebfe9a04a0
stat mage.go: no such file or directory
The command '/bin/sh -c cd /go/src/github.com/airflow_exporter/; go run mage.go binary' returned a non-zero code: 1
+++++++++++++++
++++++++++++++++ My Dockerfile +++++++++++++++++
FROM golang:1.11.1 AS builder
RUN mkdir -p /go/src/github.com/airflow_exporter
ADD . /go/src/github.com/airflow_exporter
RUN cd /go/src/github.com/airflow_exporter/;
go run mage.go binary
FROM alpine:3.4
COPY --from=builder /go/src/github.com/airflow_exporter/bin/*/airflow_exporter /airflow_exporter
EXPOSE 9112
ENTRYPOINT [ "/airflow_exporter" ]
+++++++++++++++++++++++++++++++++
The first line in your docker build output shows that the binary file mage.go is not in the expected location (stat mage.go: no such file or directory). Check through the steps that lead up to reading that binary. I would look through the following:
Check that the directory from which your docker file is being run
actually contains the mage.go binary, since you are adding the
contents of your pwd to the airflow_exporter (ADD .
/go/src/github.com/airflow_exporter)
Try adding the full file path to mage.go
If the above fails, try running your own stat commands on the file throughout the process, and continue breaking down the problem from there

Why not found, while it does exist?

At windows 10, when I run:
$ docker build .
I get this error in console:
RUN /provision/provision.sh
---> Running in e66928c3c893
/bin/sh: 1: /provision/provision.sh: not found
My folder files:
/Dockerfile
/provision
/provision/provision.sh
So why I get /bin/sh: 1: /provision/provision.sh: not found error, although /provision/provision.sh exists ?
EDIT
I tried:
ADD provision /provision
And I tried:
COPY provision /provision
Didn't work..
Step 7 : COPY provision /provision
---> c5d07de6948d
Removing intermediate container 85768981a7f0
Step 8 : RUN /provision/provision.sh
---> Running in 8426a8526514
/bin/sh: 1: /provision/provision.sh: not found
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
The command '/bin/sh -c /provision/provision.sh' returned a non-zero code: 127
provision/provision.sh exists in your docker build context (on your host), but you need to copy (COPY) it first to the image:
COPY provision/provision.sh /provision/provision.sh
# or
COPY provision /provision/
RUN chmod 755 /provision/provision.sh && \
/provision/provision.sh
As mentioned in the doc:
If <src> is a directory, the entire contents of the directory are copied, including filesystem metadata.
Note: The directory itself is not copied, just its contents.
RUN will execute a command in an intermediate container launched with the Dockerfile content compiled up to that line.
It means it execute something in the context of the container, not in the context of your host.
In my case, the provision.sh file was a dos line ending file. I needed to re-save the file using Unix line endings.
I found those two answers very helpful to fix the problem:
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
at Using the RUN instruction in a Dockerfile with 'source' does not work
And this:
./configure : /bin/sh^M : bad interpreter

Dockerfile manual install of multiple deb files

Working with Docker and I notice almost everywhere the "RUN" command starts with an apt-get upgrade && apt-get install etc.
What if you don't have internet access and simply want to do a "dpkg -i ./deb-directory/*.deb" instead?
Well, I tried that and I keep failing. Any advice would be appreciated:
dpkg: error processing archive ./deb-directory/*.deb (--install):
cannot access archive: No such file or directory
Errors were encountered while processing: ./deb-directory/*.deb
INFO[0002] The command [/bin/sh -c dpkg -i ./deb-directory/*.deb] returned a non-zero code: 1`
To clarify, yes, the directory "deb-directory" does exist. In fact it is in the same directory as the Dockerfile where I build.
This is perhaps a bug, I'll open a ticket on their github to know.
Edit: I did it here.
Edit2:
Someone answered a better way of doing this on the github issue.
* is a shell metacharacter. You need to invoke a shell for it to be expanded.
docker run somecontainer sh -c 'dpkg -i /debdir/*.deb'
!!! Forget the following but I leave it here to keep track of my reflexion steps !!!
The problem comes from the * statement which doesn't seem to work well with the docker run dpkg command. I tried your command inside a container (using an interactive shell) and it worked well. It looks like dpkg is trying to install the so called ./deb-directory/*.deb file which doesn't exist instead of installing all the .deb files contained there.
I just implemented a workaround. Copy a .sh script in your container, chmod +x it and then use it as your command.
(FYI, prefer using COPY instead of ADD when the file isn't remotely copied. Check the best practices for writing Dockerfiles for more info.)
This is my Dockerfile for example purpose:
FROM debian:latest
MAINTAINER Vrakfall <jeremy#artphotolaurent.be>
COPY install.sh /
#debdir is a directory
COPY debdir /debdir
RUN chmod +x /install.sh
CMD ["/install.sh"]
The install.sh (copied at the root directory) simply contains:
#!/bin/bash
dpkg -i /debdir/*.deb
And the following
docker build -t debiantest .
docker run debiantest
works well and install all the packages contained in the /debdir directory.

Resources