displaying help messages while docker build - docker

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.

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 does one install modules/stuff in docker if it requires interactive install?

I have been facing this problem for a long time now. Whenever I try to install anything on docker during build, that requires interactive install, the build "hangs" at the interaction screen. For example, for a particular project, I needed to install sddm in docker (Yeah, yeah I know I am stupid). Now, the build simply hangs at the step wherein I am supposed to select my keyboard layout. How do I go about such problems?
PS: Not all installation scripts are shell scripts that can be modified (like apt install sddm -y).
PS: spawn and echo is not always helpful.
As I didn't completely undestand the problem when I posted my first answer. Here's another possible solution:
run the base container
exec into the container with bash docker exec -it mycontainer bash
install needed software interactively
create image from running container with docker commit mycontainer mytag
Well, the answer was pretty easy actually. The ENV variable was to be set properly
ENV DEBIAN_FRONTEND=noninteractive

How to hide user and pass in curl command in dockerfile

I Have a dockerfile and in one of last steps, I download a WAR file from artifactory, so I can use it in the containers in the webapps/ directory.
Thing is I don´t want to show user and pass of curl -u command. How can I hide both users and password in following command? Is there a way in docker to hide/encrypt passwords?
RUN curl -u user:pass -O "https://artifactory.xxxx.com:443/artifactory/api/api-0.0.1-SNAPSHOT.war"
You can use multi stage build to achieve a lightweight image, but you have to use one single docker build, instead of two. Like this single Dockerfile:
FROM maven as build
(... Your app build....)
FROM tomcat
COPY --from=build artifact.war /dest/dir
Everything before the second FROM is discarded from the resulting image, so it will contain Tomcat, not Maven, and your copied artifact.
You can't hide the contents of RUN commands from docker history.
You should download the artifact outside the Dockerfile. A script that did the curl command and then ran docker build might simplify things for you. In addition to not exposing the credentials via docker history, this also avoids committing them to source control, makes it possible to build the image even if your Artifactory is unreachable, and simplifies a developer-oriented sequence where they need to build a temporary image out of something they've built themselves.
According to the documentation, it could be done with this new BuildKit feature RUN --mount=type=secret:
# syntax=docker/dockerfile:1.2
FROM ubuntu:22.04
RUN --mount=type=secret,id=creds,target=/tmp/artifactory.credentials \
curl -k /tmp/artifactory.credentials -O <URL>
# REST of the DockerFile
Then you can build this image like this:
docker build -secret id=creds,src=$HOME/creds/artifactory.curl .
Content of the $HOME/creds/artifactory.curl:
-u USER:PASS
For additional info on -k, please follow the official documentation
The official cUrl documentation says -K not -k

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

I found an image on docker hub that I like but doesn't meet my needs. How do I update it and make it my own?

I found an image on docker (https://hub.docker.com/r/realbazso/horizon) that I like. I am trying to update this to where it runs the most current version of this software.
I tested running the image with the arguments provided and it works great, but the version of the VMWare Horizon client that the image has does not have an updated SSL library and cannot connect to the servers I need it to without throwing an SSL error.
I'm super new to docker, but I was wondering if anyone could help me with this. I'm wanting to install it on the ubuntu:14.04 image, but I'm just not able to wrap my head around it.
I am going to add some more information to #user2915097's answer.
The first thing to do when you want to edit/update an already existing image is to see if you can find its Dockerfile. Fortunately, this repo has a Dockerfile attached to it so it makes it easier. I commented the file so that you can understand better what is going on:
# Pulls the ubuntu image. This will serve as the base image for the container. You could change this and use ubuntu:16.04 to get the latest LTS.
FROM ubuntu:14.04
# RUN will execute the commands for you when you build the image from this Dockerfile. This is probably where you will want to change the source
RUN echo "deb http://archive.canonical.com/ubuntu/ trusty partner" >> /etc/apt/sources.list && \
dpkg --add-architecture i386 && \
apt-get update && \
apt-get install -y vmware-view-client
# CMD will execute the command (there can only be one!) when you start/run the container
CMD /usr/bin/vmware-view
A good resource to understand those commands is https://docs.docker.com/engine/reference/builder/. Make sure to visit that page to learn more about Dockerfile!
Once you have a Dockerfile ready to build, navigate to the folder where your Dockerfile is and run:
# Make sure to change the argument of -t
docker build -t yourDockerHubUsername/containerName .
You might need to modify your Dockerfile a few times before it works correctly. If you are having issues with Docker using cached data
as you have the recipe, if you look at
https://hub.docker.com/r/realbazso/horizon/~/dockerfile/
you should create a directory, put this Dockerfile in, modify it, build another image
docker build -t tucker/myhorizon .
launch it, test it, modify again the Dockerfile maybe.
Check the doc R0MANARMY listed

Resources