Docker doesn't have permission to execute bash file - docker

I have followed a guide to dockerise an Elixir/Phoenix project and I created a bash script, but docker doesn't have permssion to execute the file. I ran
docker-compose build
chmod u+x entrypoint.sh
docker-compose up
despite running the commands it still doesn't have permission. What am I doing wrong?

It is better to do the chmod inside a custom Dockerfile, build your own image, and run it through docker-compose as shown below,
RUN chmod +x entrypoint.sh
Doing it directly on the host works only if the docker compose is mounting that file as a volume bind when running the image..

As mentioned by VonC, you might need to create a custom docker image. Copy the file inside the image and then change the permission. You can look at an example of initializing a SQL Server 2017 database using entry point.sh at
https://www.handsonarchitect.com/2018/01/build-custom-sql-server-2017-linux.html

Related

How to copy a file from the host into a container while starting?

I am trying to build a docker image using the dockerfile, my purpose is to copy a file into a specific folder when i run the "docker run" command!
this my dockerfile code:
FROM openjdk:7
MAINTAINER MyPerson
WORKDIR /usr/src/myapp
ENTRYPOINT ["cp"]
CMD ["/usr/src/myapp"]
CMD ls /usr/src/myapp
After building my image without any error (using the docker build command), i tried to run my new image:
docker run myjavaimage MainClass.java
i got this error: ** cp: missing destination file operand after ‘MainClass.java’ **
How can i resolve this? thx
I think you want this Dockerfile:
FROM openjdk:7
WORKDIR /usr/src/myapp
COPY MainClass.java .
RUN javac MainClass.java
ENV CLASSPATH=/usr/src/myapp
CMD java MainClass
When you docker build this image, it COPYs your Java source file from your local directory into the image, compiles it, and sets some metadata telling the JVM where to find the resulting .class files. Then when you launch the container, it will run the single application you've packaged there.
It's common enough to use a higher-level build tool like Maven or Gradle to compile multiple files into a single .jar file. Make sure to COPY all of the source files you need in before running the build. In Java it seems to be common to build the .jar file outside of Docker and just COPY that in without needing a JDK, and that's a reasonable path too.
In the Dockerfile you show, Docker combines ENTRYPOINT and CMD into a single command and runs that command as the single main process of the container. If you provide a command of some sort at the docker run command, that overrides CMD but does not override ENTRYPOINT. You only get one ENTRYPOINT and one CMD, and the last one in the Dockerfile wins. So you're trying to run container processes like
# What's in the Dockerfile
cp /bin/sh -c "ls /usr/src/myapp"
# Via your docker run command
cp MainClass.java
As #QuintenScheppermans suggests in their answer you can use a docker run -v option to inject the file at run time, but this will happen after commands like RUN javac have already happened. You don't really want a workflow where the entire application gets rebuilt every time you docker run the container. Build the image during docker build time, or before.
Two things.
You have used CMD twice.
CMD can only be used once, think of it as the purpose of your docker image. Every time a container is run, it will always execute CMD if you want multiple commands, you should use RUN and then lastly, used CMD
FROM openjdk:
MAINTAINER MyPerson
WORKDIR /usr/src/
ENTRYPOINT ["cp"]
RUN /usr/src/myapp
RUN ls /usr/src/myapp
Copying stuff into image
There is a simple command COPY the syntax being COPY <from-here> <to-here>
Seems like you want to run myjavaimage so what you will do is
COPY /path/to/myjavaimage /myjavaimage
CMD myjavaimage MainClass.java
Where you see the arrows, I've just written dummy code. Replace that with the correct code.
Also, your Dockerfile is badly created.
ENTRYPOINT -> not sure why you'd do "cp", but it's an actual entrypoint. Could point to the root dir of your project or to an app that will be run.
Don't understand why you want to do ls /usr/src/myapp but if you do want to do it, use RUN and not CMD
Lastly,
Best way to debug docker containers are in interactive mode. That means ssh'ing in to your container, have a look around, run code, and see what is the problem.
Run this: docker run -it <image-name> /bin/bash and then have a look inside and it's usually the best way to see what causes issues.
This stackoverflow page perfectly answers your question.
COPY foo.txt /data/foo.txt
# where foo.txt is the relative path on host
# and /data/foo.txt is the absolute path in the image
If you need to mount a file when running the command:
docker run --name=foo -d -v ~/foo.txt:/data/foo.txt -p 80:80 image_name

Source files are updated, but CMD does not reflect

I'm new to docker and am trying to dockerize an app I have. Here is the dockerfile I am using:
FROM golang:1.10
WORKDIR /go/src/github.com/myuser/pkg
ADD . .
RUN curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
RUN dep ensure
CMD ["go", "run", "cmd/pkg/main.go"]
The issue I am running into is that I will update source files on my local machine with some log statements, rebuild the image, and try running it in a container. However, the CMD (go run cmd/pkg/main.go) will not reflect the changes I made.
I looked into the container filesystem and I see that the source files are updated and match what I have locally. But when I run go run cmd/pkg/main.go within the container, I don't see the log statements I added.
I've tried using the --no-cache option when building the image, but that doesn't seem to help. Is this a problem with the golang image, or my dockerfile setup?
UPDATE: I have found the issue. The issue is related to using dep for vendoring. The vendor folder had outdated files for my package because dep ensure was pulling them from github instead of locally. I will be moving to go 1.1 which support to go modules to fix this.
I see several things:
According to your Dockerfile
Maybe you need a dep init before dep ensure
Probably you need to check if main.go path is correct.
According to docker philosophy
In my humble opinion, you should create an image with docker build -t <your_image_name> ., executing that where your Dockerfile is, but without CMD line.
I would execute your go run <your main.go> in your docker run -d <your_image_name> go run <cmd/pkg/main.go> or whatever is your command.
If something is wrong, you can check exited containers with docker ps -a and furthermore check logs with docker logs <your_CONTAINER_name/id>
Other way to check logs is access to the container using bash and execute go run manually:
docker run -ti <your_image_name> bash
# go run blablabla

When I am going to extend mysql docker image, I can't add my own entrypoint shell

Recently, I am going to create an custom mysql image. I hope it automatically run a custom shell to do some initialization work after mysql server startup. This function will output a SQL result into a local file.
My question is : Though my new init.sh run very successfully (from logs), the container stop immediately after start up few seconds.
When I am doing this work, I refer another post on how to make new entrypoint.sh in custom Dockfile.
Add a new entrypoint to a docker image
I followed that post contents, created my own 'init.sh'. It includes the invoking of original entrypoint.sh
Dockfile:
FROM mysql:5.7
COPY init.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/init.sh
ENTRYPOINT ["init.sh"]
init.sh
#!/bin/bash
./entrypoint.sh
# here are some custom logic...
echo $PATH
I have removed almost all the custom logic in the init.sh.
As I have said, the image is created successfully, but container can not start up.
Can anyone give me some advice?
I have known why my script didn't startup mysql service.
I check the official mysql Dockfile. It specifies 'mysqld' as parameter when running the entrypoint shell file. After I follow the Dockfile, my script startup mysql service successfully.

How to set up run bash file when starting run docker image

I would like to run a bash file every time when I start to run the docker image, but couldn't figure how to do this with a few hours already. my bash file looks like,
#!/bin/bash
while true;
do
echo "hello world"
sleep 10
done
So what I am thinking about is, when I start running the docker, the bash file will also be running inside the docker image continuously, in this case, the bash file will do its job as long as the docker is on.
How to set this up? should I build this inside the docker image? or I can put bash file in run.sh so it happens when docker runs?
Just copy your script file with COPY or ADD in the docker file and then use the CMD command to run it..
For example, if u copy run.sh to /
Then in you dockerfile last line just add:
CMD run.sh
for more info please refer to: https://docs.docker.com/engine/reference/builder/ and search for 'CMD'
make sure that the file has the right privileges for running (otherwise, after COPY/ADD the file make RUN chmod +x run.sh
Summary:
//Dockerfile
// source image, for example node.js
FROM some_image
// copy run.sh script from your local file system into the image (to root dir)
ADD run.sh /
// add execute privillages to the script file (just in case it doesn't have)
RUN chmod +x run.sh
// default behaviour when containter will start
CMD run.sh
hope that's help.
Your Dockerfile needs look looke this
FROM <base_image>
ADD yourfile.sh /
CMD ['/yourfile.sh']

Docker mount happens before or after entrypoint execution

I'm building a Docker image to run my Spring Boot based application. I want to have user to be able to feed a run time properties file by mounting the folder containing application.properties into container. Here is my Dockerfile,
FROM java:8
RUN mkdir /app
RUN mkdir /app/config
ADD myapp.jar /app/
ENTRYPOINT ["java","-jar","/app/myapp.jar"]
When kicking off container, I run this,
docker run -d -v /home/user/config:/app/config myapp:latest
where /home/user/config contains the application.properties I want the jar file to pick up during run time.
However this doesn't work, the app run doesn't pick up this mounted properties file, it's using the default one packed inside the jar. But when I exec into the started container and manually run the entrypoint cmd again, it works as expected by picking up the file I mounted in. So I'm wondering is this something related to how mount works with entrypoint? Or I just didn't write the Dockerfile correctly for this case?
Spring Boot searches for application.properties inside a /config subdirectory of the current directory (among other locations). In your case, current directory is / (docker default), so you need to change it to /app. To do that, add
WORKDIR /app
before the ENTRYPOINT line.
And to answer your original question: mounts are done before anything inside the container is run.

Resources