How to debug docker run command - docker

I am issuing a command like below:
docker run -d myvm script.sh 10
The problem is, it is not working. So I want to see what happened when script.sh was executed or whether it got executed at all or not. The script is supposed to write something in a text file. But I am not getting any idea what is the error. When I login to the container as a user and execute the script myself, I do get proper result. So,
docker run -it myvm
and then,
script.sh 10
works fine. So how can I see what is going on?
Thanks

if i correctly understand what you ask, I think you are confusing about this command. Indeed, docker run command is applied to an image and not to a script.
Please refer to the following documentation :
https://docs.docker.com/engine/reference/run.
Now if you want to execute the script they are several ways to do that. Two examples:
CLI:
copy the script.sh and execut it if the container is running:
docker cp my_container_id:/script/path/host/script.sh /tmp/script.sh
docker exec -i my_container_id chmod +x /tmp/script && /bin/bash /tmp/script.sh 10
Dockerfile:
Create a Dockerfile :
https://docs.docker.com/engine/reference/builder/
With Dockerfile you customize your container based on one image.
Create a file called Dockerfile and add:
FROM ubuntu:latest
ADD /path/host/script.sh /tmp/script.sh
CMD [/tmp/script, "10"]
For example we use the ubuntu image and copy the script on the /tmp/ path in container and then we execut it at the boot.
Now you can build your image :
docker build -t foo /path/to/dockerfile/Dockerfile
and run :
docker run -d foo
Edit:
This answer no longer fits with the initial question.

Related

RUN pwd does not seem to work in my dockerfile

I am studying on Docker these days and confused that why RUN pwd just does not seem to work while running my docker file.
I am working on IOS
and the full content of my docker file can be seen as below:
FROM ubuntu:latest
MAINTAINER xxx
RUN mkdir -p /ln && echo hello world > /ln/wd6.txt
WORKDIR /ln
RUpwd
CMD ["more" ,"wd6.txt"]
as far as my understanding,
after building the docker image with the tag 'wd8'and running it, I supposed the result should show like this
~ % docker run wd8
::::::::::::::
wd6.txt
::::::::::::::
hello world
ln
however, the fact is without ln.
I have tried with RUN $pwd, and also added ENV at the beginning of my dockerfile, both do not work.
Please help point out where the problem is.
ps: so I should not expect to see the directory 'ln' on my disk, right? since it is supposed to be created within the container...?
enter image description here
1227
There are actually multiple reasons you don't see the output of the pwd command, some of them already mentioned in the comments:
the RUN statements in your Dockerfile are only executed during the build stage, i.e. using docker build and not with docker run
when using the BuildKit backend (which is the case here) the output of successfully run commands is collapsed; to see them anyway use the --progress=plain flag
running the same build multiple times will use the build cache of the previous build and not execute the command again; you can disable this with the --no-cache flag

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

Can't figure out how to use cmd correctly to execute script in docker

I am trying to figure out how to get the CMD command in dockerfile to run a script on startup for docker run I know that using the RUN command will get the image to prerun that script when building the image but I want it to run the script everytime I run a new container using that image. The script is just a simple script that outputs the current date/time to a file.
Here is the dockerfile that works if I use RUN
# Pull base image
FROM alpine:latest
# gcr.io/dev-ihm-analytics-platform/practice_docker:ulta
WORKDIR /root/
RUN apk --update upgrade && apk add bash
ADD ./script.sh ./
RUN ./script.sh
Here is the same dockerfile that doesnt work with CMD
# Pull base image
FROM alpine:latest
# gcr.io/dev-ihm-analytics-platform/practice_docker:ulta
WORKDIR /root/
RUN apk --update upgrade && apk add bash
ADD ./script.sh ./
CMD ["./script.sh"]
I have tried all sorts of things after the CMD command like ["/script.sh"], ["bash script.sh"], ["bash", "./script.sh"], bash script.sh but I always get an error and I don't know what I am doing wrong. All I want is to
docker run -it name_of_container bash
and then find that the script has executed be seeing there is an output file with the run information in the container once I am inside
There’s three basic ways to do this:
You can RUN ./script.sh. It will happen once, at docker build time, and be baked into your image.
You can CMD ./script.sh. It will happen once, and be the single command the container runs. If you provide some alternate command (docker run ... bash for instance) that runs instead of this CMD.
You can write a custom entrypoint script that does this first-time setup, then runs the CMD or whatever got passed on the command line. The main container process is the entrypoint, and it gets passed the command as arguments. This script (and whatever it does inside) will get run on every startup. This script can look something like
#!/bin/sh
./script.sh
exec "$#"
It needs to be separately COPYd into the image, and then you’d set something like ENTRYPOINT ["./entrypoint.sh"].
(Given the problem as you’ve actually described it — you have a shell script and you want to run it and inspect the file output in an interactive shell — I’d just run it at your local command prompt and not involve Docker at all. This avoids all of these sequencing and filesystem mapping issues.)
There are multiple ways to achieve what you want, but your first attempt, with the RUN ./script.sh line is probably the best.
The CMD and ENTRYPOINT commands are overridable on the command-line as flags to the container run command. So, if you want to ensure that this is run every time you start the container, then it shouldn't be part of the CMD or ENTRYPOINT commands.
Well, iam using the CMD command to start my Java applications and when the container is inside the WORKDIR iam executing the following:
CMD ["/usr/bin/java", "-jar", "-Dspring.profiles.active=default", "/app.jar"]
Have you tried to remove the "." in the CMD command so it looks like that:
CMD ["/script.sh"]
There might be a different syntax when using RUN or CMD.

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

Docker file: I want to invoke one script from docker file

I am creating one docker image name with soaphonda.
the code of docker file is below
FROM centos:7
FROM python:2.7
FROM java:openjdk-7-jdk
MAINTAINER Daniel Davison <sircapsalot#gmail.com>
# Version
ENV SOAPUI_VERSION 5.3.0
COPY entry_point.sh /opt/bin/entry_point.sh
COPY server.py /opt/bin/server.py
COPY server_index.html /opt/bin/server_index.html
COPY SoapUI-5.3.0.tar.gz /opt/SoapUI-5.3.0.tar.gz
COPY exit.sh /opt/bin/exit.sh
RUN chmod +x /opt/bin/entry_point.sh
RUN chmod +x /opt/bin/server.py
# Download and unarchive SoapUI
RUN mkdir -p /opt
WORKDIR /opt
RUN tar -xvf SoapUI-5.3.0.tar.gz .
# Set working directory
WORKDIR /opt/bin
# Set environment
ENV PATH ${PATH}:/opt/SoapUI-5.3.0/bin
EXPOSE 3000
RUN chmod +x /opt/SoapUI-5.3.0/bin/mockservicerunner.sh
CMD ["/opt/bin/entry_point.sh","exit","pwd", "sh", "/Users/ankitsrivastava/Documents/SametimeFileTransfers/Honda/files/hondascript.sh"]
My image creation is getiing successfull. I want that once the image creation is done it should retag and push in the docker hub. For that i have created the script which is below;
docker tag soaphonda ankiksri/soaphonda
docker push ankiksri/soaphonda
docker login
docker run -d -p 8089:8089 --name demo ankiksri/soaphonda
containerid=`docker ps -aqf "name=demo"`
echo $containerid
docker exec -it $containerid bash -c 'cd ../SoapUI-5.3.0;sh /opt/SoapUI-5.3.0/bin/mockservicerunner.sh "/opt/SoapUI-5.3.0/Honda-soapui-project.xml"'
Please help me how i can call the second script from docker file and the exit command is not working in docker file.
What you have to understand here is what you are specifying within the Dockerfile are the commands that gets executed when you build and run a Docker container from the image you have created using your Dockerfile.
So Docker image tag, push running should all done after you have built the Docker image from the Dockerfile. It cannot be done within the Dockerfile itself.
To achieve this kind of a thing you would have to use a build tool like Maven (an example) and automate the process of tagging, pushing the image. Also by looking at your image, I don't see any nessactiy to keep on tagging and pushing the image unless you are continuously updating the image. Also there is no point of using three FROM commands as it will unnecessarily make your Docker image size huge.

Resources