Dockerfile permissions not taking effect - docker

My goal is to have /ssc/bin/put-and-submit.sh to be executable. I looked at another question, but do not think it applies.
FROM perl:5.20
ENV PERL_MM_USE_DEFAULT 1
RUN cpan install Net::SSL inc:latest
RUN mkdir /ssc
COPY /ssc /ssc
RUN chmod a+rx /ssc/bin/*.sh
ENTRYPOINT ["/ssc/bin/put-and-submit.sh"]
stat /ssc/bin/put-and-submit.sh
File: '/ssc/bin/put-and-submit.sh'
Size: 1892 Blocks: 8 IO Block: 4096 regular file
Device: 7ah/122d Inode: 293302 Links: 1
Access: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2021-01-27 04:14:43.000000000 +0000
Modify: 2021-01-27 04:14:43.000000000 +0000
Change: 2021-01-27 04:52:44.700000000 +0000
Birth: -
I read the question below, and believe that circumstance is when another layer is added, it overwrites the previous one. In my case, I start with a Perl image, add a few CPAN libraries, copy a few files and then ask it to change permissions.
Dockerfile "RUN chmod" not taking effect

I remember I had this problem too and it basically only worked when I just replaced the default /usr/local/bin/docker-php-entrypoint WITHOUT firing the ENTRYPOINT command (to use a custom entrypoint script).
So in your case you have to find out what the default entrypoint file is perl is using (must also be in /usr/local/bin) and maybe replace that.
Sorry it's not the exact "right" solution but in my case it worked out fine and good enough.
So what I'm doing for example for my PHP-FPM containers is the following (note that ENTRYPOINT is commented out):
COPY docker-entrypoint.sh /usr/local/bin/docker-php-entrypoint
RUN chmod +x /usr/local/bin/docker-php-entrypoint
# ENTRYPOINT ["/usr/local/bin/docker-php-entrypoint"]
Just in case, my sh script looks like this (only starts supervisor):
#!/bin/sh
set -e
echo "Starting supervisor service"
exec supervisord -c /etc/supervisor/supervisord.conf
I hope this gets you somewhere mate, cheers

Related

Cronjob in docker container not running

Okay so firstly I read some posts on this topic. That is how I ended up with my solution. Still I don’t find my mistake. Also I am more of a beginner.
So this is my docker file:
FROM conda/miniconda3
WORKDIR /app
RUN apt-get update -y
RUN apt-get install cron -y
RUN apt-get install curl -y
RUN conda update -n base -c defaults conda
RUN conda install mamba -n base -c conda-forge
COPY ./environment.yml ./environment.yml
RUN mamba env create -f environment.yml
# Make RUN commands use the new environment:
SHELL ["conda", "run", "--no-capture-output", "-n", "d2", "/bin/bash", "-c"]
#Setup cron
COPY ./cronjob /etc/cron.d/cronjob
RUN crontab /etc/cron.d/cronjob
RUN chmod 0600 /etc/cron.d/cronjob
RUN touch ./cron.log
COPY ./ ./
RUN ["chmod", "+x", "run.sh"]
ENTRYPOINT ["sh", "run.sh"]
CMD ["cron", "-f"]
What I want to do:
Run my run.sh (I managed to do that.)
Setup a cronjob inside my container which is defined in a file called cronjob (see content below)
My cronjob is not working. Why?
Note that cron.log is empty. It is never triggered.
Also the output of crontab -l (run inside of the container) is:
$ crontab -l
# Updates every 15 minutes.
*/15 * * * * /bin/sh /app/cron.sh >> /app/cron.log 2&>1
cronjob
# Updates every 15 minutes.
*/15 * * * * /bin/sh /app/cron.sh >> /app/cron.log 2&>1
As Saeed pointed out already, there is reason to believe you did not place your cron.sh script inside the container.
On top of that cron is programmed such that it does not log failed invocations anywhere. You can try to turn on some debug logging (I almost had to search cron's source to find the right settings years ago). Finally cron will send it's debug output to syslog - but in your container only cron is running, so the log entries are probably lost on that stage again.
That ultimately means you are in the dark and need to find the needle. But installing the script is a first good attempt.
As Saeed said in this comment
First of all, your cronjob command is wrong. You should have 2>&1 instead of 2&>1. Second. run ls -lh /app/cron.sh to see if your file is copied. Also be sure cron.sh is in the directory where your Dockerfile is.
2&>1 was the mistake that I had made.
I had a similar issue with the crontab not being read
I was also using something like:
COPY ./cronjob /etc/cron.d/cronjob
Locally the cronjob file had permissions of 664 instead of 644. This was causing cron to log Sep 29 16:21:01 0f2c2e0ddbfd cron[389]: (*system*crontab) INSECURE MODE (group/other writable) (/etc/cron.d/crontab) (I actually had to install syslog-ng to see this happen).
Turns out cron will refuse to read cron configurations if they are writeable by others. I guess it makes sense in hindsight but I was completely oblivious to this.
Changing my cronjob file permissions to 644 fixed this for me (I did this on my local filesystem, the Dockerfile copies permissions over)
only you need to root right then it will solve issuse
*/15 * * * * root /bin/sh /app/cron.sh >> /app/cron.log 2&>1

Getting ENOENT running a binary copied into my Docker container

I have a Dockerfile which looks something like this
FROM node:8.15.0-alpine
# ARGs and LABELs...
RUN apk add --no-cache curl
COPY src/scripts scripts/
COPY src/scripts/update_mmdb.sh /etc/periodic/weekly/update_mmdb
RUN /etc/periodic/weekly/update_mmdb
RUN mkdir -p /root/myapp/bin
COPY src/docker/bin/program_running_in_a_separate_process /root/myapp/bin/
WORKDIR /root/myapp
# Some more COPY-ing
COPY src/myapp/docker/cmd.sh /
CMD /cmd.sh
When I go to run my container I get an ENOENT error when my app attempts to spin up program_running_in_a_separate_process.
I investigated by doing docker exec -it myapp sh and attempting to run the binary directly. I successfully was able to stat it:
# stat program_running_in_a_separate_process
File: program_running_in_a_separate_process
Size: 14689327 Blocks: 28696 IO Block: 4096 regular file
Device: 39h/57d Inode: 15073498 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-01-14 01:08:09.000000000
Modify: 2020-01-14 01:08:09.000000000
Change: 2020-01-14 01:08:09.000000000
, it came up when I ran ls from /root/myapp/, I even ran chmod +x to be sure, but sure enough when I go to run program_running_in_a_separate_process, I get sh: ./program_running_in_a_separate_process: not found
How could this be?

How to fix "exec user process caused no such file or directory"

I'm trying to use tini in my Dockerfile but I'm getting an error.
I used the code example from the tini readme file.
# ... code which builds /app/foo
# Add Tini
ENV TINI_VERSION v0.18.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini", "--"]
# Run the program when the container starts
CMD ["/app/foo"]
I expect my program to run without having PID=1 but instead I get: standard_init_linux.go:207: exec user process caused "no such file or directory"
EDIT:
/app/foo is created in the beginning of the Dockerfile. There is no problem with /app/foo. As proof of this, if I comment out the ENTRYPOINT line (or remove all the tini related code), my /app/foo runs fine except for the fact that it has PID=1
Another cause: incorrect line ends in the file. Linux expects LFs, and if your host is Windows, the script you want to run will have CRLFs.
Another cause could be that a script is called for which the first line points to an unavailable shell.
For example, when the first line of the script (also known as the shebang) is
#!/bin/bash
Then this requires bash on the system. Changing bash to the default sh(ell) for the system can be a solution. So, replace by
#!/bin/sh
Alternatively, on some systems bash is not in /bin, but in /usr/bin/env. So, replace by
#!/usr/bin/env bash
or
#!/usr/bin/env sh
As David mentions, you need to check what is getting downloaded. If you run this by hand in an Alpine image, you'll see the exact issue:
$ docker run -it --rm alpine /bin/sh
/ # apk add file
...
/ # apk add curl
...
/ # curl -sSL https://github.com/krallin/tini/releases/download/v0.18.0/tini >tini
/ # chmod 755 tini
/ # file tini
tini: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=38c262787814dc459678c8f24710bbde944b7e56, stripped
/ # ldd tini
/lib64/ld-linux-x86-64.so.2 (0x7f1beab2a000)
libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f1beab2a000)
Error relocating tini: __fprintf_chk: symbol not found
/ # ./tini
/bin/sh: ./tini: not found
/ # ls -al /lib64/ld-linux-x86-64.so.2
ls: /lib64/ld-linux-x86-64.so.2: No such file or directory
Note the dynamically linked part, and the fact that it is looking for libc. The error in an Alpine scenario is telling you that libc doesn't exist. You'd also see this with a scratch image.
You'll want to either get a version of tini that is completely statically compiled, or switch to a system with libc installed. For the former, with tini, that's as easy as downloading a different URL:
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static /tini

Docker entrypoint can't find file

I have a very simple docker build file:
FROM openjdk:10
ENV JENAVERSION=3.7.0
RUN mkdir /fuseki
RUN wget http://apache.claz.org/jena/binaries/apache-jena-fuseki-$JENAVERSION.tar.gz -P /tmp \
&& tar -zxvf /tmp/apache-jena-fuseki-$JENAVERSION.tar.gz -C /tmp \
&& mv -v /tmp/apache-jena-fuseki-$JENAVERSION/* /fuseki
EXPOSE 3030
ENTRYPOINT ["/bin/bash", "/fuseki/fuseki-server"]
I've tried different variations on CMD and ENTRYPOINT, but nothing allows "fuseki-server" to execute. Always a "No such file or directory" error. If I manually create an empty container from openjdk:10, and execute each command manually, it works fine. What's going on?
I think the issue is the line ending - the entrypoint needs to have LF line ending.
I get the same error when my entrypoint has CLRF line ending.
If I build and run your Dockerfile, I get a different error from what you've described. I see:
Can't find jarfile to run
If you look at the fuseki-server shell script, it's trying to find the jar file relative either to your current directory or to the $FUSEKI_HOME environment variable:
export FUSEKI_HOME="${FUSEKI_HOME:-$PWD}"
if [ ! -e "$FUSEKI_HOME" ]
then
echo "$FUSEKI_HOME does not exist" 1>&2
exit 1
fi
JAR1="$FUSEKI_HOME/fuseki-server.jar"
JAR2="$FUSEKI_HOME/jena-fuseki-server-*.jar"
JAR=""
So if you set the FUSEKI_HOME environment variable in your
Dockerfile:
ENV FUSEKI_HOME=/fuseki
Then the container starts up without errors:
[2018-06-04 14:02:17] Server INFO Apache Jena Fuseki 3.7.0
[2018-06-04 14:02:17] Config INFO FUSEKI_HOME=/fuseki
[2018-06-04 14:02:17] Config INFO FUSEKI_BASE=/run
[2018-06-04 14:02:17] Config INFO Shiro file: file:///run/shiro.ini
[2018-06-04 14:02:18] Server INFO Started 2018/06/04 14:02:18 UTC on port 3030
Wow... After going through #larsk's suggestion it occurred to me to change the entrypoint to
ENTRYPOINT ["tail", "-f", "/dev/null"]
and go into the container to see what was actually there. It turns out that I was accidently overwriting the /fuseki folder with a volume declaration in the compose file I was using. (facepalm...)

Why won't my docker-entrypoint.sh execute?

My ENTRYPOINT script doesn't execute and throws standard_init_linux.go:175: exec user process caused "no such file or directory". Why so?
Doesn't Work
$ docker build -t gilani/trollo . && docker run gilani/trollo
Sending build context to Docker daemon 126 kB
Step 1 : FROM vault:latest
---> 1f127f53f8b5
Step 2 : MAINTAINER Amin Shah Gilani <gilani#payload.tech>
---> Using cache
---> 86b885ca1c81
Step 3 : COPY vaultConfig.json /vault/config
---> Using cache
---> 1a2be2fa3acd
Step 4 : COPY ./docker-entrypoint.sh /
---> Using cache
---> 0eb7c1c992f1
Step 5 : RUN chmod +x /docker-entrypoint.sh
---> Running in 251395c4790f
---> 46aa0fbc9637
Removing intermediate container 251395c4790f
Step 6 : ENTRYPOINT /docker-entrypoint.sh
---> Running in 7434f052178f
---> eca040859bfe
Removing intermediate container 7434f052178f
Successfully built eca040859bfe
standard_init_linux.go:175: exec user process caused "no such file or directory"
Dockerfile:
FROM vault:latest
MAINTAINER Amin Shah Gilani <gilani#payload.tech>
COPY vaultConfig.json /vault/config
COPY ./docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
docker-entrypoint.sh:
#!/bin/bash
echo 'Hello World!'
Works
$ docker build -t gilani/trollo . && docker run gilani/trollo
Sending build context to Docker daemon 126 kB
Step 1 : FROM vault:latest
---> 1f127f53f8b5
Step 2 : MAINTAINER Amin Shah Gilani <gilani#payload.tech>
---> Using cache
---> 86b885ca1c81
Step 3 : COPY vaultConfig.json /vault/config
---> Using cache
---> 1a2be2fa3acd
Step 4 : ENTRYPOINT echo 'hello world'
---> Using cache
---> ef5792a1f252
Successfully built ef5792a1f252
'hello world'
Dockerfile:
FROM vault:latest
MAINTAINER Amin Shah Gilani <gilani#payload.tech>
COPY vaultConfig.json /vault/config
ENTRYPOINT ["echo", "'hello world'"]
I was tearing my hair out with an issue very similar to this. In my case /bin/bash DID exist. But actually the problem was Windows line endings.
In my case the git repository had an entry point script with Unix line endings (\n). But when the repository was checked out on a windows machine, git decided to try and be clever and replace the line endings in the files with windows line endings (\r\n).
This meant that the shebang didn't work because instead of looking for /bin/bash, it was looking for /bin/bash\r.
The solution for me was to disable git's automatic conversion:
git config --global core.autocrlf input
Then check out the repository again and rebuild.
Some more helpful info here:
How to change line-ending settings
and here
http://willi.am/blog/2016/08/11/docker-for-windows-dealing-with-windows-line-endings/
the vault:latest image does not contain /bin/bash which you try to call with your shebang #!/bin/bash. You should either change that to #!/bin/sh or completely remove the shebang from your script.
Another possibility:
Check that the file is not saved with Windows line endings (CRLF). If it is, save it with Unix line endings (LF) and it will be found.
Without seeing your image, my initial idea is that you don't have /bin/bash in your image. Changing the first line of your docker-entrypoint.sh to:
#!/bin/sh
will likely resolve it.
I struggled for hours because I haven't noticed anywhere explained that you need to copy the file in the location where the VM can access the file, preferably globally like so:
COPY docker-entrypoint.sh /usr/local/bin/
(I had thought it should just be automatically accessible since it's part of the dockerfile context)
Gosh I struggled for 2–3 hours!!
Thanks to #Ryan Allen
For my case it was CRLF problem. I am working on puppet manifests over ATOM for jenkins setup.
Make sure if you are using ATOM or any other IDE on windows, when you take your file ( especially .sh) to unix, convert it to unix format. It worked like magic once converted.
Here is what I added in my puppet file:
exec {'dos2unix':
path => ['/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/opt/puppetlabs/bin'],
command => 'dos2unix /dockerwork/puppet/jenkins/files/*',
subscribe => File['/dockerwork/puppet/jenkins/files/init.sh'],
}
I came here with a similar issue while troubleshooting my attempt to build a Dockerfile "entry point" (entrypoint.sh) bash shell script (to be executed within the .NET Core SDK 2.2 image). The start of the script had the line #!/bin/bash, and during execution of docker-compose up (after successfully building with docker-compose build, the logging reported web_1 | ./entrypoint.sh: line 1: #!/bin/bash: No such file or directory.
Checking the file with VS Code, I noticed it was reporting the following encoding:
UTF-8 with BOM
Clicking on this, I would get the option to Save with encoding:
I chose to save as UTF-8 (utf8), which resolved the issue.
NOTE: I also found this SO article What's the difference between UTF-8 and UTF-8 without BOM?
My case was that the alpine image I was using didn't come with bash at all...
RUN apk-install bash did the trick obviously
Another reason this error comes up is if your Windows User password changes.
In my case my entrypoint.sh line endings were LF but I was still getting the error. Our admin has a mandatory password reset about every month or so. Whenever this happens I would run into the error. If this is your reason you may need to reset your credentials in docker settings under "Shared Drives".
Unselect the drive and apply. Then reselect the drive and apply. It will prompt you for your password.
This problem is to do with line endings and I solved it with the solution below
Convert the DOS file to a unix format. This removes any wired line endings.
dos2unix - is available in alpine as well as other Linux distributions.
I used it like so: RUN apk add dos2unix && dos2unix /entry.sh
Sorry for hacking -- this is not a response to the question, but a description of a different problem and it's solution that has the same symptoms.
I had
ENTRYPOINT ["/usr/bin/curl", "-X", "POST", "http://myservice:8000", \
"-H", "Content-Type: application/json", \
"-d", '{"id": "test"}' \
]
I was getting the error:
/bin/bash: [/usr/bin/curl,: No such file or directory
It turns out it's the single quotes that messed it up. Docker documentation has a note:
The exec form is parsed as a JSON array, which means that you must use double-quotes (“) around words not single-quotes (‘).
Blockquote
Solution -- use double quotes instead of single and escape nested double quotes:
ENTRYPOINT ["/usr/bin/curl", "-X", "POST", "http://myservice:8000", \
"-H", "Content-Type: application/json", \
"-d", "{\"id\": \"test\"}" \
]
None of the solutions worked for me but I was able to solve the error by setting WORKDIR to the same directory that contained the entrypoint script. No amount of cd'ing would work but somehow WORKDIR solved it

Resources