RUN pwd does not seem to work in my dockerfile - docker

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

Related

How can I prevent Docker from removing intermediate containers when executing RUN command?

The error I'm experiencing is that I want to execute the command "change directory" in my Docker machine, but every time I execute RUN instruction in my Dockerfile, it deletes the actual container (intermediate container).
DOCKERFILE
This happens when I execute the Dockerfile from above
How can I prevent Docker from doing that?
docker build --rm=false
Remove intermediate containers after a successful build (default true)
The current paths are different for Dockerfile and RUN (inside container).
Each RUN command starts from the Dockerfile path (e. g. '/').
When you do RUN cd /app, the "inside path" changes, but not the "Dockerfile path". The next RUN command will again be run at '/'.
To change the "Dockerfile path", use WORKDIR (see reference), for example WORKDIR /opt/firefox.
The alternative would be chaining the executed RUN commands, as EvgeniySharapov pointed out: RUN cd opt; ls; cd firefox; ls
on multiple lines:
RUN cd opt; \
ls; \
cd firefox; \
ls
(To clarify: It doesn't matter that Docker removes intermediate containers, that is not the problem in this case.)
When you use docker build --no-cache this will delete intermediate containers when you build an image. This may affect building times when you run build multiple times. Alternatively you can choose to put multiple shell commands into one shell command using \ and then use it as a RUN argument.
Mote tips could be found here

displaying help messages while docker build

I am building a Dockerfile and I would like to display some help messages while building it.
I also tried RUN echo "installing this" but as expected, it doesn't work.
So, How do I display help messages and if possible while running the docker build command in quiet mode.
I had a similar problem with docker build where RUN echo commands were showing . I was able to fix it by modifying the build command to
docker build -t hello-world ./ --progress=plain --no-cache
The important thing here is the --progress=plain option as docker defaults to auto and hides too much output. The --no-cache option is necessary to rebuild the container to show all of the output.
A priori RUN echo "installing this" should work and display something. However it would be somewhat bad practice to have a RUN layer with only a single echo command.
Indeed as mentioned in the page dev-best-practices:
If you need to use a version of Docker that does not include
multistage builds, try to reduce the number of layers in your image by
minimizing the number of separate RUN commands in your Dockerfile. You
can do this by consolidating multiple commands into a single RUN line
and using your shell’s mechanisms to combine them together.
For additional, related recommendations, there is also a page dockerfile_best-practices.
For the use case you mention in your question, you could either write
RUN echo "install this" && command that install this...
or maybe just
RUN set -x && command that install this...
to automatically display the command that is run during the docker build.
But if you use the docker build --quiet option, I am unsure it is possible to achieve what you want.
So if you really want to have some concise/quiet build log while displaying specific info messages, you could try removing docker build's --quiet option but combine set -x with redirections such as command that install this >/dev/null.

Geting a log of execution of current instructions when doing a 'docker run'

I am a newbie to Docker and I am trying to see if I can get logs for the following instructions when they are getting executed.
FROM ubuntu:16.04
ENV name John
ENTRYPOINT echo "Hello, $name"
My aim here is check how(the path etc.) the shell mode is working in executing the ENV here and also how the ENTRYPOINT is being executed.
I can imagine these kind of logs could be useful in debugging purposes, so probably I am missing something obvious. Any ideas please?
The Dockerfile instructions don’t do much; they record some state in fields in the built Docker image. As #BrayanCaldera’s answer indicates, you’ll see these go by in the docker build output, but nothing runs during container build time.
If the ENTRYPOINT is a full-blown script then you can use usual script debugging techniques on it to see what happens when the container starts up. For instance:
#!/bin/sh
# Print out every command as it executes
set -x
# Print out the current environment
env
# Run the actual command
exec "$#"
To tell the Docker image what to do by default when you docker run you should usually use the CMD directive. If you need to do pre-launch setup then an ENTRYPOINT script that uses exec "$#" to run the CMD is a typical path.
For see the logs on terminal you only need to execute this line:
docker build --rm -f dockerfile -t log:latest .
If you need to store these logs in a file you only need to execute this line:
docker build -t logs . > image.log

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

How to debug docker run command

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.

Resources