Docker unable to run a shell script inside a container using dockerfile - docker

I am facing a highly trivial problem wherein the shell script "httpd-service.sh" is not getting executed in the below Dockerfile.
FROM localhost:5000/httpd_custom_image:v6
WORKDIR /opt
ADD httpd-service.sh .
EXPOSE 80
CMD ["/bin/sh","/opt/httpd-service.sh"]
Below is the content of the httpd-service.sh
#!/bin/bash
/usr/local/apache2/bin/httpd
The script httpd-service.sh is getting copied inside /opt in container and has permissions.
Below is the docker version,
[root#vfecare-3 temp]# docker --version
Docker version 17.03.0-ce, build 3a232c8
Can someone let me know what is breaking here?

Got it working in the foreground with the below lines in the Dockerfile.
CMD ["-D", "FOREGROUND"]
ENTRYPOINT ["/usr/sbin/httpd"]

Related

Docker does not build image

I just got started with docker and was following fireship's tutorial, however I encountered a problem when I ran the docker build command. I was expecting a similar output as the video (timestamp). Instead, I got the following:
Dockerfile
FROM node:12
WORKDIR /app #maybe its this? There is no /app directory
COPY package*.json ./
RUN npm install
COPY . .
ENV PORT=8080
EXPOSE 8080
CMD ["npm","start"]
docker build command
docker build -t <my docker id>/firstapp:1.1 .
File tree
D:/
Code/
testing/
Docker/
test1/
Notes
Yes, I have a docker ID.
The docker build command stopped at COPY . ., rather than finishing at CMD ["npm","start"]
CWD (Windows): D:\Code\testing\Docker\test1
I ran the docker build command twice
Questions
Why is this happening?
How can it be fixed?
The reason this occurs is because fireship is running Linux (like Hans Kilian noted) and I am running Windows. To get your image ID, run the docker images command, which will list your images w/ their image ID.
However, I am still not sure why it does not complete all 8 steps.

Why does the ENTRYPOINT log output but not the CMD or RUN in Dockerfile

In this Dockerfile i have an ENTRYPOINT that calls a script that simply logs an echo "testing". This output works locally when I build and run the Dockerfile. It also logs to cloudwatch when I use in conjunction with a docker-compose for aws.
However the RUN and CMD commands do not output anything to the console or cloudwatch, how do i see their output? I would expect at least some errors
ENTRYPOINT bash -c "/migrate.sh"
WORKDIR /
RUN yarn
CMD ["yarn migration:run", "dist/src/main"]
I'm building just with docker build -t test:test . then docker run <imagename>
The RUN statement in the Dockerfile is only invoked when you build the container (at which point you should see the output of yarn in this case). When you docker run the container it will just execute the ENTRYPOINT and/or CMD (in this case the output of the ENTRYPOINT as there is no CMD)

How to run shell file as entrypoint when using docker image with tomcat:9.0.45-jdk8-adoptopenjdk-hotspot in a dockerfile?

I am creating a docker file using docker image tomcat:9.0.45-jdk8-adoptopenjdk-hotspot. To run the dockerfile I use the command docker run -it -p 8888:8080 tomcatcustom , this turns on the tomcat server.
I would like to run another custom .sh file along with tomcat server that gets executed with running the docker image. How could I define the Entrypoint in the dockerfile that I have created so that I can have both the tomcat as well as my .sh file executed ?
or is there any other option?
The Dockerfile can only have one Entrypoint that is executed, but nothing stops you from having a script as entrypoint that runs your custom script and tomcat.
E.g.
if you have a directory with
Dockerfile
custom.sh // your custom script
start.sh
where start.sh is
#!/usr/bin/env bash
./custom.sh &
catalina.sh run
and Dockerfile is
FROM tomcat:9.0.45-jdk8-adoptopenjdk-hotspot
COPY start.sh .
COPY custom.sh .
CMD "./start.sh"
In that case custom.sh is executed in the background (with &) so that tomcat is started in parallel.

Is CMD or ENTRYPOINT necessary to mention in Dockerfile?

I have read the docs about CMD and ENTRYPOINT
https://docs.docker.com/engine/reference/builder/#entrypoint
Here, they have mentioned in the table that "NO CMD and NO ENTYRPOINT is not allowed", But I created a Dockerfile without CMD and ENTRYPOINT and the image was built successfully.
Download alpine tar from here Alpine Tar
Dockerfile
from scratch
ADD alpine-minirootfs-3.11.2-x86_64.tar.gz /
COPY . /
Building the image:
docker build -t test:1 .
Sending build context to Docker daemon 2.724MB
Step 1/3 : from scratch
-----
Successfully tagged test:1
docker run -ti test:1 /bin/sh
/ #
It worked!! So why in the docs it's mentioned that either CMD or ENTRYPOINT is necessary?
Specifying a command at the end of the docker run command line supplies (or overrides) CMD; similarly, the docker run --entrypoint option supplies (or overrides) ENTRYPOINT. In your example you gave a command /bin/sh so there's something for the container to do; if you leave it off, you'll get an error.
As a matter of style your Dockerfiles should almost always declare a CMD, unless you're extending a base image that's already running the application automatically (nginx, tomcat). That will let you docker run the image and launch the application embedded in it without having to remember a more specific command-line invocation.
The following line from documentation is incorrect.
Dockerfile should specify at least one of CMD or ENTRYPOINT commands.
It should probably say -
CMD or ENTRYPOINT is necessary for running a container.

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

Resources