i would like to build my first Docker image, containing Apache Tomcat and a deployed web app. My Dockerfile is really small, based on Tomcat:8.0 image and is supposed to copy a WAR file into Tomcat's appBase.
Build of the image reports success, but the file is nowhere to be found in the container.
Copying from host to the container work w/o issues using "docker cp":
[root#edubox dock]# docker cp jdbcdemo_3.war 15dd44bbf992:/usr/local/tomcat/webapps/
My Dockerfile:
# we are extending everything from tomcat:8.0 image ...
FROM tomcat:8.0
MAINTAINER simo
# COPY path-to-your-application-war path-to-webapps-in-docker-tomcat
COPY ./jdbcdemo_3.war /usr/local/tomcat/webapps/
EXPOSE 8082
Image build:
root#edubox dock]# docker image build -t simo/jdbcdemo_3 --tag=recent ./
Sending build context to Docker daemon 10.24 kB
Step 1/4 : FROM tomcat:8.0
---> ef6a7c98d192
Step 2/4 : MAINTAINER simo
---> Using cache
---> 54d824d7258b
Step 3/4 : COPY ./jdbcdemo_3.war /usr/local/tomcat/webapps/
---> Using cache
---> f94330423a93
Step 4/4 : EXPOSE 8082
---> Running in 74b6dd0364b2
---> 9464f11ac18e
Removing intermediate container 74b6dd0364b2
Successfully built 9464f11ac18e
I would expect COPY to place the file where specified or an error message because of which this does not work.
Please try this way,
Keep the "jdbcdemo_3.war" where your Dockerfile exists. And make this change in the Dockerfile.
(remove ./ from your Dockerfile) like,
COPY jdbcdemo_3.war /usr/local/tomcat/webapps/
please check the permission side of the file.
you can give full permission and test once. (user:group)
try this: COPY jdbcdemo_3.war /tmp
In your Dockerfile. And build the image and check in the /tmp directory. If the file copied successfully, give the permission to /usr/local/tomcat/webapps/ Or copy to /tmp first and then copy from /tmp to /usr/local/tomcat/webapps/. Using COPY command in Dockerfile
Hi and many thanks for offering advice. The issue has been trivial in the end. I have not been examining the correct container.
I did not realize one needs to pick the freshly created image, run the container with this image and only afterwards peek for changes described in the Dockerfile in that container.
I have been looking into parent container which i now understand could not have worked.
Sry for wasting your time ;-)
Related
I'm learning Docker. I have a Console app created with .NET Core. This console app has a Dockerfile in it. That Dockerfile looks like this:
FROM microsoft/dotnet:2.1-runtime AS base
FROM microsoft/dotnet:2.1-sdk
# Copy the compiled files
COPY . ./bin
ENTRYPOINT ["dotnet", "/bin/MyApp.dll"]
I intentionally want to copy the compiled files into the Docker images. I do NOT want to build the code on the Docker image due to issues with the dependencies. Still, when I select the play button in Visual Studio that says "Docker" I can see that the image gets successfully created via the "Output" window. In addition, my console app writes messages to the "Output" window as expected. For these reasons, I'm assuming my Dockerfile is correct.
Now, I try to run the build image from a command line outside of Visual Studio. From the directory where my .csproj file is located, I run docker build .. When I do this, I see the following:
Sending build context to Docker daemon 11.8MB
Step 1/4 : FROM microsoft/dotnet:2.1-runtime AS base
---> 59184f8be664
---> Using cache
---> 3a64d221c7f1
Step 2/4 : FROM microsoft/dotnet:2.1-sdk
---> 6691c7a1e6c7
Step 3/4 : COPY . ./app
---> e3e894ef7997
Step 4/4 : ENTRYPOINT ["dotnet", "/bin/MyApp.dll"]
---> Running in 355713fb3562
Removing intermediate container 355713fb3562
---> 88d4918847b9
Successfully built 78d4918847b8
I then run docker container run 78d4918847b8 from the command line and I see the message:
No executable found matching command "dotnet-/bin/MyApp.dll"
I don't understand why I can run the image from Visual Studio but not from the command line myself. What am I doing wrong?
The error message actually means File not found (see https://github.com/dotnet/core-setup/issues/1126 as suggested by #oneturkmen).
The reason the file is not found is because you are copying the files to ./bin which is a relative path but the ENTRYPOINT is looking in /bin which is an absolute path, related to the root folder.
If you change your DOCKERFILE to:
FROM microsoft/dotnet:2.1-runtime AS base
FROM microsoft/dotnet:2.1-sdk
# Copy the compiled files
COPY . ./bin
ENTRYPOINT ["dotnet", "./bin/MyApp.dll"]
then it should work. Please note the ./bin in the entrypoint
I am using jenkins image to create a docker container. For now I am just trying to create a new directory and copy a couple of files. The image build process runs fine but when I start the container I cannot see the files and the directory.
Here is my dockerfile
FROM jenkins:2.46.1
MAINTAINER MandeepSinghGulati
USER jenkins
RUN mkdir /var/jenkins_home/aws
COPY aws/config /var/jenkins_home/aws/
COPY aws/credentials /var/jenkins_home/aws/
I found a similar question here but it seems different because I am not creating the jenkins user. It already exists with home directory /var/jenkins_home/. Not sure what I am doing wrong
Here is how I am building my image and starting the container:
➜ jenkins_test docker build -t "test" .
Sending build context to Docker daemon 5.632 kB
Step 1/6 : FROM jenkins:2.46.1
---> 04c1dd56a3d8
Step 2/6 : MAINTAINER MandeepSinghGulati
---> Using cache
---> 7f76c0f7fc2d
Step 3/6 : USER jenkins
---> Running in 5dcbf4ef9f82
---> 6a64edc2d2cb
Removing intermediate container 5dcbf4ef9f82
Step 4/6 : RUN mkdir /var/jenkins_home/aws
---> Running in 1eb86a351beb
---> b42587697aec
Removing intermediate container 1eb86a351beb
Step 5/6 : COPY aws/config /var/jenkins_home/aws/
---> a9d9a28fd777
Removing intermediate container ca4a708edc6e
Step 6/6 : COPY aws/credentials /var/jenkins_home/aws/
---> 9f9ee5a603a1
Removing intermediate container 592ad0031f49
Successfully built 9f9ee5a603a1
➜ jenkins_test docker run -it -v $HOME/jenkins:/var/jenkins_home -p 8080:8080 --name=test-container test
If I run the command without the volume mount, I can see the copied files and the directory. However with the volume mount I cannot see the same. Even if I empty the directory on the host machine. Is this the expected behaviour? How can I copy over files to the directory being used as a volume ?
Existing volumes can be mounted with
docker container run -v MY-VOLUME:/var/jenkins_home ...
Furthermore, the documentation of COPY states:
All new files and directories are created with a UID and GID of 0.
So COPY does not reflect your USER directive. This seems to be the second part of your problem.
This is not about transferring files between host and container, it's just inside the container.
app.js exists in the build directory.
Step 7 : RUN ls build
---> Running in 8461a550a5db
app.js
app.js.map
css
html
img
js
---> 22a863b60265
Should be copied to the static folder.
Removing intermediate container 8e195477d342
Step 9 : RUN cp build/app.js static/
---> Running in 0a49669338e0
---> 41cb4d3039d1
But it's not there. Why?
Removing intermediate container 0a49669338e0
Step 10 : RUN ls static/
---> Running in 4cdb5f74a722
css
html
img
js
Tried: RUN cp ./build/app.js ./static/ - doesn't work either.
Could you try to use docker build with no-cache?
docker build -t "your_app" --no-cache=true .
Problem here:
Removing intermediate container 0a49669338e0
From Docker docs: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#build-cache
During the process of building an image Docker will step through the
instructions in your Dockerfile executing each in the order specified.
As each instruction is examined Docker will look for an existing image
in its cache that it can reuse, rather than creating a new (duplicate)
image. If you do not want to use the cache at all you can use the
--no-cache=true option on the docker build command.
All, i'm trying to persistently copy files from my host to an image so those files are available with every container launched based on that image. Running on debian wheezy 64bit as virtualbox guest.
the Dockerfile is fairly simple (installing octave image):
FROM debian:jessie
MAINTAINER GG_Python <[redacted]#gmail.com>
RUN apt-get update
RUN apt-get update
RUN apt-get install -y octave octave-image octave-missing-functions octave-nan octave-statistics
RUN mkdir /octave
RUN mkdir /octave/libs
RUN mkdir /octave/libs/jsonlab
COPY ~/octave/jsonlab/loadjson.m /octave/libs/jsonlab/.
I'm getting the following trace after issuing a build command: docker build -t octave .
Sending build context to Docker daemon 423.9 kB
Sending build context to Docker daemon
Step 0 : FROM debian:jessie
---> 58052b122b60
Step 1 : MAINTAINER GG_Python <[..]#gmail.com>
---> Using cache
---> 90d2dd2f7ee8
Step 2 : RUN apt-get update
---> Using cache
---> 4c72c25cd829
Step 3 : RUN apt-get update
---> Using cache
---> b52f0bcb9f86
Step 4 : RUN apt-get install -y octave octave-image octave-missing-functions octave-nan octave-statistics
---> Using cache
---> f0637ab96d5e
Step 5 : RUN mkdir /octave
---> Using cache
---> a2d278b2819b
Step 6 : RUN mkdir /octave/libs
---> Using cache
---> 65efbbe01c99
Step 7 : RUN mkdir /octave/libs/jsonlab
---> Using cache
---> e41b80901266
Step 8 : COPY ~/octave/jsonlab/loadjson.m /octave/libs/jsonlab/.
INFO[0000] ~/octave/jsonlab/loadjson.m: no such file or directory
Docker absolutely refuses to copy this file from the host into the image. Needless to say a the file loadjson.m is there (cat displays), all my attempts to change the path (relative, absolute, etc.) failed. Any advice why this simple task is problematic?
At the time I originally wrote this, Docker didn’t expand ~ or $HOME. Now it does some expansions inside the build context, but even so they are probably not what you want—they aren’t your home directory outside the context. You need to reference the file explicitly, or package it relative to the Dockerfile itself.
Docker can only copy files from the context, the folder you are minus any file listed in the dockerignore file.
When you run 'docker build' docker tars the context and it sends it to the docker daemon you are connected to. It only lets you copy files inside of the context because the daemon might be a remote machine.
I couldn't get COPY to work until I understood the context (I was trying to copy a file from outside of the context)
The docker build command builds an image from a Dockerfile and a context. The build’s context is the files at a specified location PATH. The PATH is a directory on your local filesystem.
A context is processed recursively. So, a PATH includes any subdirectories.
The build is run by the Docker daemon, not by the CLI. The first thing a build process does is send the entire context (recursively) to the daemon. In most cases, it’s best to start with an empty directory as context and keep your Dockerfile in that directory. Add only the files needed for building the Dockerfile.
Warning: Do not use your root directory, /, as the PATH as it causes the build to transfer the entire contents of your hard drive to the Docker daemon.
Reference:
https://docs.docker.com/engine/reference/builder/#usage
I had similar issue. I solved it by checking two things:
Inside your, docker-compose.yaml check context of the service, docker will not copy any file outside of this directory. For example if the context is app/ then you cannot copy anything from ../app
Check .dockerignore to be sure that you are not ignoring the file you want to copy.
I got it working by first checking what the context was,
setting an absolute path before the source file in
your Dockerfile to get that information:
# grep COPY Dockerfile
COPY /path/to/foo /whatever/path/in/destination/foo
Building with that:
docker build -t bar/foo .
you'll get an error, which states the context-path that Docker
is apparently looking into for its files, e.g.
it turns out to be:
/var/lib/docker/tmp # I don't remember
Copying(!) your set of build-files in that directory (here: /var/lib/docker/tmp),
cd into it, build from there.
See if that works, and don't forget to do some housekeeping cleaning up
the tmp, deleting your files before the next visit(or).
HTH
Michael
Got this error using a Dockerfile for a linux container on a Windows machine:
#24 1.160 Skipping project "/src/Common/MetaData/Metadata.csproj" because it was not found.
Restore worked perfectly on the host machine.
Turned out to be the error mentioned here:
https://stackoverflow.com/a/68592423/3850405
A .csproj file did not match casing in Visual Studio vs the file system.
I'm playing around with Google's Dart docker image. I'm trying to build a Hello World app that listens on port 80. I'm running it on Ubuntu Server 14 on Azure.
If I run the google/dart-hello, it all works fine, and I can connect on port 8080.
The google/dart-hello image is based on the google/dart-runtime image, which is in turn, based on google/dart. The base image adds Dart; google/dart-runtime adds a Dockerfile which expects to execute bin/server.dart and expose port 8080, and google/dart-hello supplies the bin/server.dart (and pubspec.yaml) to make it work. google/dart-runtime isn't useful on its own, because it doesn't contain a bin/server.dart or pubspec.yaml.
So, google/dart-runtime is a good base if your server is at bin/server.dart and you want to listen on port 8080. As I want to listen on port 80, I'm using the google/dart image as a base, hoping to squash what's in google/dart-runtime and google/dart-hello into my container, but changed to port 80.
You can find the sources repos for the three Google images here:
google/dart
google/dart-runtime (Dockerfile)
google/dart-hello (Dockerfile)
So, I've taken the Dockerfile from google/dart-runtime and the files from google/dart-hello, so I have the following:
FROM google/dart
WORKDIR /app
ONBUILD ADD pubspec.yaml /app/
ONBUILD ADD pubspec.lock /app/
ONBUILD RUN pub get
ONBUILD ADD . /app
ONBUILD RUN pub get
CMD []
ENTRYPOINT ["/usr/bin/dart", "/app/bin/server.dart"]
EXPOSE 80
In the same directory as this Dockerfile, I have the following files:
bin/server.dart
pubspec.yaml
pubspec.lock
I'm building the image with:
sudo docker build --no-cache -t dart-test .
And here's the output:
danny#linux:~/dart_test$ sudo docker build --no-cache -t dart-test .
Sending build context to Docker daemon 5.632 kB
Sending build context to Docker daemon
Step 0 : FROM google/dart
---> cd92c7fff717
Step 1 : WORKDIR /app
---> Running in d163d2597eba
---> 2802d6769b76
Removing intermediate container d163d2597eba
Step 2 : ONBUILD ADD pubspec.yaml /app/
---> Running in 7b8be2a481c2
---> 096cbe12a2cd
Removing intermediate container 7b8be2a481c2
Step 3 : ONBUILD ADD pubspec.lock /app/
---> Running in 6ae0243b0dee
---> 80f20ebafa87
Removing intermediate container 6ae0243b0dee
Step 4 : ONBUILD RUN pub get
---> Running in 621d4ce5c7f1
---> 89a509d41b11
Removing intermediate container 621d4ce5c7f1
Step 5 : ONBUILD ADD . /app
---> Running in 4de26a33487f
---> b69c65f12441
Removing intermediate container 4de26a33487f
Step 6 : ONBUILD RUN pub get
---> Running in f7cc689f6f81
---> 2ccc79ea6d04
Removing intermediate container f7cc689f6f81
Step 7 : CMD []
---> Running in 10bd31eb6679
---> f828267f00b5
Removing intermediate container 10bd31eb6679
Step 8 : ENTRYPOINT ["/usr/bin/dart", "/app/bin/server.dart"]
---> Running in 013d3ca0f25d
---> a63b59f9fd05
Removing intermediate container 013d3ca0f25d
Step 9 : EXPOSE 80
---> Running in 4301c572e598
---> 75a4317c135c
Removing intermediate container 4301c572e598
Successfully built 75a4317c135c
However, if I try to run this (using sudo docker run --rm -i -t dart-test), I get the following error:
danny#linux:~/dart_test$ sudo docker run -i -t --rm dart-test
Unhandled exception:
Uncaught Error: FileSystemException: Cannot open file, path = '/app/bin/server.dart' (OS Error: No such file or directory, errno = 2)
If I replace the dart execution in the Dockerfile with /bin/bash instead, then when I build and run, I get put into bash at /app/ but the folder is empty.
I've tried this with both the 0.9(?) version and 1.2 (one that came from apt-get docker.io and the other from the more-involved instructions on the Docker website), since I noticed a mention of an ADD fix in the release notes. Both do the same.
I can find lots of info online that people often pipe Dockerfile into STDIN which means there's no context, but you can see in my output that 5KB of data is being sent; though it's possible this is just the Dockerfile and nothing else I guess? They are in the same directory, here's a listing:
danny#linux:~/dart_test$ dir
bin Dockerfile pubspec.lock pubspec.yaml
The ONBUILD instruction is only useful when you create a base image that will be used later by another Dockerfile (see the documentation).
Here because you write the final Dockerfile, you just need to remove the ONBUILD instructions (but keep the raw instructions ADD, RUN, etc).
In your Dockerfile you need to remove the ONBUILD prefixes from your instructions. The ONBUILD prefix is a way to defer execution of certain instructions until this image is referenced by another Dockerfile. Those instructions are stored as part of the metadata for the image that you created but the instructions themselves are not executed until that image is referenced in the FROM field of another Dockerfile.
What you really want is this:
FROM google/dart
WORKDIR /app
ADD pubspec.yaml /app/
ADD pubspec.lock /app/
RUN pub get
ADD . /app
RUN pub get
CMD []
ENTRYPOINT ["/usr/bin/dart", "/app/bin/server.dart"]
EXPOSE 80
The docker image google/dart-runtime is intended to be a base image for your Dart server application. So in your project the Dockerfile should have just the following content
FROM google/dart-runtime
The when you run docker build the ONBUILD commands in the base image will be executed.
If you look at the Dockerfile for google/dart-hello you will see that it has just that one line.