I am trying to create a docker image and tag it at the same time. This way I can create a script that uses the -t option in the "docker build" command. Thus staff members that deploy new images does not need to type docker commands, they simply run the script.
The problem that I have is that the "docker build" command also starts the image. This causes the docker build command to get 'stuck' when it gets to the point where the image runs, because the image is suppose to run indefinitely, it is a service, thus the build command never finishes, and the result is that the tag mentioned in the "-t" part of the build command never gets applied to the new image.
So there is no way to identify new images because none of them have tags. I can fix it by terminating the build command with Ctrl+C and then afterwards using the "docker tag" command. But that means that I cannot put the build and tag commands in a bash script, because I have to tag the image ID and not the name. Which changes every time I run the docker build command.
I have tried the following:
Hitting Ctrl+C to terminate the application running inside the new image. This does end the current running application. But this terminates the docker build command as well. Thus the image tag never gets applied.
I have tried using "docker ps" in another terminal to find the currently running container and stopping it with "docker stop ID". This also stops the application / container but this generates an error on the docker build command and once again doesn't finish and doesn't apply the tag.
This is what I see after I have tried steps 1 or 2 above and run a "docker image list" command, the neither the tag field nor the repository field being set:
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> df355e74685b 6 minutes ago 493MB
openjdk latest e92ef2c3a3dd 12 days ago 470MB
openjdk 8 b84359d0cbce 3 weeks ago 488MB
portainer/portainer latest da2759008147 4 weeks ago 75.4MB
My docker build command :
sudo docker build -t slite/cloud-db-host -f slite/cloud/db/Dockerfile.Host.docker .
And here is my docker file:
FROM openjdk:8
LABEL maintainer="techss.co.za"
LABEL vendor="techss.co.za"
LABEL app="slite-db-host"
LABEL repository="slite"
COPY slite/cloud/db /slite/cloud/db
COPY slite/lib/java /slite/lib/java
EXPOSE 51173
WORKDIR .
RUN javac slite/cloud/db/*.java && javac slite/lib/java/*.java && java slite.cloud.db.SliteDBHost
ENTRYPOINT ["java","slite.cloud.db.SliteDBHost"]
Here is the output from docker build:
Sending build context to Docker daemon 13.43MB
Step 1/11 : FROM openjdk:8
---> b84359d0cbce
Step 2/11 : LABEL maintainer="techss.co.za"
---> Running in 3dc3f0fcea2c
Removing intermediate container 3dc3f0fcea2c
---> 0946737c1386
Step 3/11 : LABEL vendor="techss.co.za"
---> Running in c289dd741158
Removing intermediate container c289dd741158
---> 00d5a7f3d7e5
Step 4/11 : LABEL app="slite-db-host"
---> Running in 1d7e953bdf6f
Removing intermediate container 1d7e953bdf6f
---> 4540390e8bb5
Step 5/11 : LABEL repository="slite"
---> Running in c366a92becb5
Removing intermediate container c366a92becb5
---> c9be0ef5e6da
Step 6/11 : COPY slite/cloud/db /slite/cloud/db
---> f3efeb406aef
Step 7/11 : COPY slite/lib/java /slite/lib/java
---> 797bf7df8335
Step 8/11 : EXPOSE 51173
---> Running in 93389673e9cc
Removing intermediate container 93389673e9cc
---> abfb10413edf
Step 9/11 : WORKDIR .
---> Running in 77a67baa9be6
Removing intermediate container 77a67baa9be6
---> 7d313395f072
Step 10/11 : RUN javac slite/cloud/db/*.java && javac slite/lib/java/*.java && java slite.cloud.db.SliteDBHost
---> Running in 99edcf79d5f4
Sun Jul 07 18:47:02 UTC 2019 Listening on port 51173
It just hangs on the last line, I assume it's waiting for the application running inside the container to end, which will never happen because it's a service. So how do I force docker build to carry on, even though the container is running, thus applying the needed tags. Or force docker build to NOT start the image but simply create it, which would be first prize.
Just replace RUN with CMD and it will not be runned during the build:
CMD ["sh","-c","javac slite/cloud/db/*.java && javac slite/lib/java/*.java && java slite.cloud.db.SliteDBHost"]
Cheers
Any RUN instruction will be executed when the Docker image is built. I suspect your issue will be fixed if you change line 10 of your Dockerfile.
Before:
RUN javac slite/cloud/db/*.java && javac slite/lib/java/*.java && java slite.cloud.db.SliteDBHost
After:
RUN javac slite/cloud/db/*.java && javac slite/lib/java/*.java
Related
Below is my Docker file
ARG tag_info=latest
FROM alpine:${tag_info} AS my_apline
ARG message='Hello World'
RUN echo ${message}
RUN echo ${message} > myfile.txt
RUN echo "Hi Harry"
When i run docker image build -t myimage:v1_0 - < Dockerfile
the output is :
Sending build context to Docker daemon 2.048kB
Step 1/6 : ARG tag_info=latest
Step 2/6 : FROM alpine:${tag_info} AS my_apline
latest: Pulling from library/alpine
cbdbe7a5bc2a: Already exists
Digest: sha256:9a839e63dad54c3a6d1834e29692c8492d93f90c59c978c1ed79109ea4fb9a54
Status: Downloaded newer image for alpine:latest
---> f70734b6a266
Step 3/6 : ARG message='Hello World'
---> Running in 74bcc8897e8e
Removing intermediate container 74bcc8897e8e
---> d8d50432d375
Step 4/6 : RUN echo ${message}
---> Running in 730ed8e1c1d3
Hello World
Removing intermediate container 730ed8e1c1d3
---> 8417e3167e80
Step 5/6 : RUN echo ${message} > myfile.txt
---> Running in c66018331383
Removing intermediate container c66018331383
---> 07dc27d8ad3d
Step 6/6 : RUN echo "Hi Harry"
---> Running in fb92fb234e42
Hi Harry
Removing intermediate container fb92fb234e42
---> a3bec122a77f
It displays "Hi Harry" and "Hello World" in the middle (which I do not understand why)
Why "Hi Harry and "Hello World" is not displayed when i spin the container from image file?
Because the RUN command executes the commands when you are building the image not when you are spinning up the container using the image. It is used to alter the image like adding new packages using apt-get or changing file permissions etc
If you need something to run when the container is starting you need to use command to entrypoint instructions
From the docker official documentation:
The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile.
You should use CMD if you want to obtain the described behavior.
The main purpose of a CMD is to provide defaults for an executing container. These defaults can include an executable, or they can omit the executable, in which case you must specify an ENTRYPOINT instruction as well.
This has three forms:
- CMD ["executable","param1","param2"] (exec form, this is the preferred form)
- CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
- CMD command param1 param2 (shell form)
I am new to docker. Excuse my ignorance on this topic.
I created a dockerfile with the intent on running the windows steam application. this is my docker file.
# escape=`
FROM mcr.microsoft.com/windows/servercore:ltsc2019
ADD https://steamcdn-a.akamaihd.net/client/installer/SteamSetup.exe c:\SteamSetup.exe
RUN c:\SteamSetup.exe /S
ENTRYPOINT ["c:\Program Files (x86)\Steam\Steam.exe"]
I verified that in the docker image Steam is installed at c:\Program Files (x86)\Steam\Steam.exe I attached to the docker with a powershell entrypoint and was able to run "& c:\Program Files (x86)\Steam\Steam.exe" I cannot however get the docker image to launch steam on its own. I gt the error below.
PS C:\Users\AJWHEELE\Desktop\dockers\steamOS> docker build -t ajwtech/windowstest .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM mcr.microsoft.com/windows/servercore:ltsc2019
---> 80e84fd280e2
Step 2/4 : ADD https://steamcdn-a.akamaihd.net/client/installer/SteamSetup.exe c:\SteamSetup.exe
Downloading [==================================================>] 1.574MB/1.574MB
---> Using cache
---> d39ad50d3754
Step 3/4 : RUN c:\SteamSetup.exe /S
---> Using cache
---> 33cdd5566dad
Step 4/4 : ENTRYPOINT ["c:\Program Files (x86)\Steam\Steam.exe"]
---> Running in 65027c59352a
Removing intermediate container 65027c59352a
---> e92095819109
Successfully built e92095819109
Successfully tagged ajwtech/windowstest:latest
PS C:\Users\AJWHEELE\Desktop\dockers\steamOS> docker run --rm -e DISPLAY=192.168.1.119:0 ajwtech/windowstest:latest
The filename, directory name, or volume label syntax is incorrect.
PS C:\Users\AJWHEELE\Desktop\dockers\steamOS>
Also I am trying to get Steam to launch so that I can see the user interface. currently I am on a windows 10 machine trying to use VcXsrv.
Thanks,
Adam
I'm Test Automation engineer and working in big product company. Companies big monolithic project being divided and parts are departuring into clouds. As part of such redesign Test Automation projects should also get cloudy. Our typical TA project based on groovy, selenium, testng and maven. Now I want to try the option of putting whole TA maven project into Docker image\container. Its works well, but on the very first run it starts download dependencies into local .m2 repository. I want to speed up and have this task done on a creation image stage.
Here is a my DOCKERFILE:
FROM maven:3.3-jdk-8
LABEL description="Embedded portal-web-testing"
MAINTAINER NNN
COPY ./settings.xml /root/.m2/
COPY ./acceptance-tests ./acceptance-tests
WORKDIR acceptance-tests
RUN mvn dependency:go-offline --debug >log
RUN ls /root/.m2/
#RUN mvn test
ENTRYPOINT ["bash"]
And here is a log:
Step 1 : FROM maven:3.3-jdk-8
---> 7addddbdd730
Step 2 : LABEL description "Embedded portal-web-testing"
---> Running in 1d195ccb9c57
---> f5372b024ca0
Removing intermediate container 1d195ccb9c57
Step 3 : MAINTAINER NNN
---> Running in 03ebbffda680
---> cb12da3d8ec6
Removing intermediate container 03ebbffda680
Step 4 : COPY ./settings.xml /root/.m2/
---> 164999e1f63a
Removing intermediate container 1e1778d2533b
Step 5 : COPY ./acceptance-tests ./acceptance-tests
---> 7d93fff4193e
Removing intermediate container a5d04eb30591
Step 6 : WORKDIR acceptance-tests
---> Running in f15111475fc6
---> beb4d090362b
Removing intermediate container f15111475fc6
Step 7 : RUN mvn dependency:go-offline --debug >log
---> Running in 2c09f1869143
---> 62326c2bb073
Removing intermediate container 2c09f1869143
Step 8 : RUN ls /root/.m2/
---> Running in 91b602f529da
settings.xml
---> b7bc32199ab3
Removing intermediate container 91b602f529da
Step 9 : ENTRYPOINT bash
---> Running in 3167f5a6d923
---> 94b3e0b146da
Removing intermediate container 3167f5a6d923
Successfully built 94b3e0b146da
On Step 7 surely files being downloaded, but looks like not stored.
Following console command shows that there are no updates in local .m2 folder:
root#37f5a0d04232:/acceptance-tests# ls /root/.m2
settings.xml
If I try to run same command again from command line inside a container (when image is created and container had started):
root#37f5a0d04232:/acceptance-tests# mvn dependency:go-offline
Massive downloads starts and repository folder finally appeared under .m2
root#37f5a0d04232:/acceptance-tests# ls /root/.m2
repository settings.xml
I struggle to understand why changes caused by maven command from Dockerbuild file did not stored as docker layer.
I am using Docker 1.12 and maven 3.3.3
/root/.m2 is a volume that is why it gets cleared when docker container is launched. This can be avoided by caching the content in a custom directory and then copying it to /root/.m2 when container is launched.
Fortunately maven image is pre-baked with all the copying logic so you just have to point repository as:
RUN mvn -B -f /tmp/pom.xml -s /usr/share/maven/ref/settings-docker.xml dependency:resolve
The entry-point will take care of setting local repository for you. It helped me hope it helps you as well.
Also, for reference visit.
When I run a docker build command i see the following
[root#hadoop01 myjavadir]# docker build -t runhelloworld .
Sending build context to Docker daemon 4.096 kB
Sending build context to Docker daemon
Step 0 : FROM java
---> 3323938eb5a2
Step 1 : MAINTAINER priyanka priyanka.patil#subex.com
---> Running in 89fa73dbc2b8
---> 827afdfa3d71
Removing intermediate container 89fa73dbc2b8
Step 2 : COPY ./HelloWorld.java .
---> 9e547d78d08c
Removing intermediate container ff5b7c7a8122
Step 3 : RUN javac HelloWorld.java
---> Running in d52f3093d6a3
---> 86121aadfc67
Removing intermediate container d52f3093d6a3
Step 4 : CMD java HelloWorld
---> Running in 7b4fa1b8ed37
---> 6eadaac27986
Removing intermediate container 7b4fa1b8ed37
Successfully built 6eadaac27986
Want to understand the meaning of these container ids like 7b4fa1b8ed37.
What does it mean when the daemon says "Removing intermediate container d52f3093d6a3"?
The docker build process automates what is happening in the Creating your own images section of the docker docs.
In your case above:
The image ID we're going to start with is 3323938eb5a2 (the ID of the java image)
from that image we run a container (after it's created it has a container ID of 89fa73dbc2b8) to set the MAINTAINER meta data, docker commits the changes and the resulting layer ID is 827afdfa3d71
because we're finished with the container 89fa73dbc2b8, we can remove it
from the layer we created from the MAINTAINER line, we create a new container to run the command COPY ./HelloWorld.java . which gets a container ID of ff5b7c7a8122, docker commits the changes and the resulting layer ID is 9e547d78d08c
because we're finished with the container ff5b7c7a8122, we can remove it
Repeat for steps 3 and 4.
docker build --rm=true
This is the default option, which makes it to delete all intermediate images after a successful build.
Does it affect the caching adversely? Since cache relies on the intermediate images I think?
Why not try it and find out?
$ cat Dockerfile
FROM debian
RUN touch /x
RUN touch /y
$ docker build --rm .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM debian
---> df2a0347c9d0
Step 1 : RUN touch /x
---> Running in 2e5ff13506e5
---> fd4dd6845e31
Removing intermediate container 2e5ff13506e5
Step 2 : RUN touch /y
---> Running in b2a585989fa5
---> 0093f530941b
Removing intermediate container b2a585989fa5
Successfully built 0093f530941b
$ docker build --rm .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM debian
---> df2a0347c9d0
Step 1 : RUN touch /x
---> Using cache
---> fd4dd6845e31
Step 2 : RUN touch /y
---> Using cache
---> 0093f530941b
Successfully built 0093f530941b
So no, the cache still works. As you pointed out, --rm is actually on by default (you would have to run --rm=false to turn it off), but it refers to the intermediate containers not the intermediate images. These are the containers that Docker ran your build commands in to create the images. In some cases you might want to keep those containers around for debugging, but normally the images are enough. In the above output, we can see the containers 2e5ff13506e5 and b2a585989fa5, which are deleted, but also the images fd4dd6845e31 and 0093f530941b which are kept.
You can't delete the intermediate images as they are needed by the final image (an image is the last layer plus all ancestor layers).