I have a docker-compose project made up of five docker containers, three of which use an entrypoint.sh file. None of these three can find the entrypoint.sh file after building.
Ive tried several variations on the syntax but I am very new to docker and wouldnt know a syntax error if I was staring right at it. The build process for each completes without errors, but when I try to bring them online they cannot find the entrypoint file and continually restart in a loop.
The Dockerfile for one such
(a bunch of confidential stuff I cant post here)
# Enable apache modules
RUN sudo a2enmod actions headers alias deflate mime expires filter setenvif include rewrite
# Create a log file
RUN mkdir /var/www/logs
RUN chmod -R 777 /var/www/logs
#Open up needed ports
EXPOSE 8081
EXPOSE 80
ADD entrypoint.sh /
ENTRYPOINT ./entrypoint.sh
aaand the error
ss-fe-webserver | /bin/sh: 1: ./entrypoint.sh: not found
Its worth noting that I am running Docker for Windows, and these Dockerfiles were written by a Mac user. As long as this error persists, the servers continually restart and do not stay online.
Put your entrypoint at / path. It seems like you are using WORKDIR somewhere which is causing this conflict.
Prefer using COPY instead of ADD in this case.
Provide executable permissions to your entrypoint script.
Here is how it may look like at the end -
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
You add the entrypoint.sh on root folder as "/".
ADD entrypoint.sh /
But you still call the entrypoint.sh on ./ as workdir folder.
ENTRYPOINT ./entrypoint.sh
You try:
ENTRYPOINT /entrypoint.sh
or:
ADD entrypoint.sh ./
Related
I'm trying to deploy an Angular application onto Openshift (i.e an angular docker container on Openshift). However, I'm facing difficulty modifying the default.conf file within nginx in the container, which I think also caused the error at line 9.
Here's the error log on Openshift:
Here's my dockerfile:
FROM node:latest as build
WORKDIR /usr/local/app
COPY ./ /usr/local/app/
RUN npm install
RUN npm run build
FROM nginxinc/nginx-unprivileged
COPY --from=build /usr/local/app/dist/ng-adminx /usr/share/nginx/html
COPY --from=build /usr/local/app/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
For context,
I'm not familiar with how permissions work on Openshift.
Also, this build works perfectly fine locally but fails on Openshift.
I think chmod or chown might be the solution. Would greatly appreciate any suggestion on how I should modify my dockerfile or navigate this! Thanks!
You will need to use chmod to be able to modify the default.conf file.
For simplicity, you can use chmod 777 <filepathname>.
How does 777 come about? You can think of it as the permissions for read, write, execute for file owner, group and user respectively. 1 = allowed. 0 = not allowed.
So 7 in binary is 111.
file owner
group
other users
rwx
rwx
rwx
111
111
111
I have this Dockerfile setup:
FROM node:14.5-buster-slim AS base
WORKDIR /app
FROM base AS production
ENV NODE_ENV=production
RUN chown -R node:node /app
RUN chmod 755 /app
USER node
... other copies
COPY ./scripts/startup-production.sh ./
COPY ./scripts/healthz.sh ./
CMD ["./startup-production.sh"]
The problem I'm facing is that I can't execute ./healthz.sh because it's only executable by the node user. When I commented out the two RUN and the USER commands, I could execute the file just fine. But I want to enforce the executable permissions only to the node for security reasons.
I need the ./healthz.sh to be externally executable by Kubernetes' liveness & rediness probes.
How can I make it so? Folder restructuring or stuff like that are fine with me.
In most cases, you probably want your code to be owned by root, but to be world-readable, and for scripts be world-executable. The Dockerfile COPY directive will copy in a file with its existing permissions from the host system (hidden in the list of bullet points at the end is a note that a file "is copied individually along with its metadata"). So the easiest way to approach this is to make sure the script has the right permissions on the host system:
# mode 0755 is readable and executable by everyone but only writable by owner
chmod 0755 healthz.sh
git commit -am 'make healthz script executable'
Then you can just COPY it in, without any special setup.
# Do not RUN chown or chmod; just
WORKDIR /app
COPY ./scripts/healthz.sh .
# Then when launching the container, specify
USER node
CMD ["./startup-production.sh"]
You should be able to verify this locally by running your container and manually invoking the health-check script
docker run -d --name app the-image
# possibly with a `docker exec -u` option to specify a different user
docker exec app /app/healthz.sh && echo OK
The important thing to check is that the file is world-executable. You can also double-check this by looking at the built container
docker run --rm the-image ls -l /app/healthz.sh
That should print out one line, starting with a permission string -rwxr-xr-x; the last three r-x are the important part. If you can't get the permissions right another way, you can also fix them up in your image build
COPY ./scripts/healthz.sh .
# If you can't make the permissions on the original file right:
RUN chmod 0755 *.sh
You need to modify user Dockerfile CMD command like this : ["sh", "./startup-production.sh"]
This will interpret the script as sh, but it can be dangerous if your script is using bash specific features like [[]] with #!/bin/bash as its first line.
Moreover I would say use ENTRYPOINT here instead of CMD if you want this to run whenever container is up
I am trying to use ENTRYPOINT and whenever I do that I am getting an error as no such file or directory
Dockerfile:
FROM ubuntu:18.04
COPY . /home
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s /usr/local/bin/docker-entrypoint.sh
WORKDIR /home
RUN chmod 777 /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["/bin/bash"]
I have tried giving it permission, tried running it with absolute path also tried this, tried it with #!/bin/bash & #!/bin/sh and in the end, I still get the file not found error.
I am not sure what the problem is.
The question you asked:
I don't remember exactly why, but the file isn't being found because you're calling it docker-entrypoint.sh rather than ./docker-entrypoint.sh.
The question you'll ask soon:
That doesn't entirely fix your problem. You've added execute privileges to the copy of docker-entrypoint.sh in /usr/local/bin, but there's another copy of the file in /home that gets found first and doesn't have execute privileges. You'll get a permissions error when you try to use it. An easy workaround (depending on what you want to do) consists of a modified entrypoint:
ENTRYPOINT ["/bin/bash", "docker-entrypoint.sh"]
Extra details if you'll be using Docker a lot:
Being able to enter a container or image to examine its contents is invaluable. For ubuntu-based images, write down the following line somewhere (replace bash with sh for basically every other linux OS):
docker run -it --rm --entrypoint=bash my_image_name
This will open up a shell in that image and let you play around in the same environment the Dockerfile is running in and debug whatever is causing you problems.
I have a Dockerfile like:
FROM frolvlad/alpine-oraclejdk8:slim
ADD build/libs/zuul*.jar /app.jar
ADD src/main/script/startup.sh /startup.sh
EXPOSE 8080 8999
ENTRYPOINT ["/startup.sh"]
startup.sh looks like:
#!/bin/sh
set -e
if [ $# -eq 0 ]
then
echo "Environment value required"
exit 1
fi
java -jar -Xms400m -Xmx400m -Dlog4j.configurationFile=log4j2-qa2.xml -Djava.security.egd=file:/dev/./urandom -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.rmi.port=8999 app.jar
But when I run it with docker run, I got docker: Error response from daemon: Container command '/startup.sh' not found or does not exist... The shell script has execute permission.
I used the same way to run my other apps and they're all working fine. I wrote the files in Mac and tried to run the container in a Linux machine.
It turns out to be the ^M DOS-style line ending character that caused the issue. But since I'm editing in Mac and I checked several times with vim, I'm pretty sure the starting script in my local machine doesn't have that char. But when opened with vim inside the container, I can see ^M everywhere. So somehow that char gets added to startup.sh when copied into the image, which is weird. That prevents the script from being invoked.
The solution is to add dos2unix filename before the ENTRYPOINT in Dockerfile. But make sure that your base image has that utility.
The shell script has execute permission.
Are you sure though? (I mean within the container, onced ADDed)
To be sure, I would use the Dockerfile:
EXPOSE 8080 8999
COPY src/main/script/startup.sh /startup.sh
RUN chmod 755 /startup.sh
WORKDIR /
ENTRYPOINT ["/startup.sh"]
A container exits when its main process exits. So check that /startup.sh is not ending.
Particularly check that this java
java -jar -Xms400m -Xmx400m -Dlog4j.configurationFile=log4j2-qa2.xml \
-Djava.security.egd=file:/dev/./urandom \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=8999 \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.rmi.port=8999 \
app.jar
I think the trouble here is when you specify path like /app.jar, it is really difficult to make out where the current working directory actually is.
It can be any where and I suspect Docker must have accidentally copy your start.sh to a place whatever at that point ./ is.
You might want to ssh into the container and do a find to search and see where startup.sh is sitting.
docker ps -a - Find docker container ID
docker -i -t [CONTAINER_ID] /bin/bash - SSH inside
find . -name "startup.sh" - Look for file.
If you intend to copy the files through using ./ (current working directory), I think it would be better to specify where current is. And you can do this using the WORKDIR keyword.
Example:
WORKDIR /path/to/workdir
The WORKDIR instruction sets the working directory for any RUN, CMD,
ENTRYPOINT, COPY and ADD instructions that follow it in the
Dockerfile. If the WORKDIR doesn’t exist, it will be created even if
it’s not used in any subsequent Dockerfile instruction.
That way docker will not get confused.
See:
https://docs.docker.com/engine/reference/builder/#/workdir
I had a similar problem which led me to this thread, however my issue was not quite the exact same as yours. For me the problem was that I was using an alpine base image and my script was referencing #!/bin/bash, I just had to update mine to #!/bin/sh at the top of my script instead.
Is there a reason I need to chmod +x on my entrypoint script? It didn't appear Redis was doing this in their dockerfile (https://github.com/docker-library/redis/blob/109323988b7663bceaf4a01c3353f8934dfc002e/2.8/Dockerfile) for their entrypoint script.
Dockerfile:
# Generic Docker Image for Running Node app from Git Repository
FROM node:0.10.33-slim
ENV NODE_ENV production
# Add script to pull Node app from Git and run the app
COPY docker-node-entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 8080
CMD ["--help"]
redis don't need to do it because their script already have exec flag:
~/redis/2.8$ ls -l docker-entrypoint.sh
-rwxrwxr-x 1 igor igor 109 Dec 3 23:52 docker-entrypoint.sh
if you will do it for your docker-node-entrypoint.sh script you would not need chmod in Dockerfile too.
This is possible because the git core.fileMode option by default is true, so the executable bit of a file is honored.
Docker will copy files into the container with the permissions of their source. If you strip the Linux executable bits somewhere in the chain of pushing to your code repo, or on your build host, then you'll need to add those execute permissions back. I've seen this issue most often reported by Windows users, who are downloading code to a filesystem that doesn't support the Linux permission bits. Hopefully we'll get a COPY --chmod solution soon that will eliminate the need for an extra layer.
Try this way
RUN ["chmod", "+x", "/entrypoint.sh"]
it have worked for me