Docker Image move to the src directory - docker

So , I have a project and I want to have a docker image for the project. My directory is:
--Dockerfile
--source
So in my Dockerfile I have commands like :
COPY source /source
RUN cd source
The image is built fine , but when I run the container the last statement cd source is not executed.
PS. I tried using WORKDIR instead of RUN cd , but then the contents of the source was not copied.
Any work-around so that the statement cd source is executed on its own?

use WORKDIR command to set work directory through Dockerfile, you can change workdir as part of docker run with the command switch -w
see full docs for reference: http://docs.docker.com/reference/builder/#workdir
and the docker run switch: http://docs.docker.com/reference/run/#workdir

Related

Command from within Docker image doesn't work in Dockerfile RUN statement

EDIT to provide MRE:
Steps to reproduce (using Docker CLI, now, for reproducibility)
project_directory
Dockerfile
directory_to_cd_into
gradlew
Dockerfile:
From debian:9
RUN cd /directory_to_cd_into
# also tried RUN cd ./directory_to_cd_into
Running docker build yields /bin/sh: 1: cd: can't cd to /directory_to_cd_into
So the problem is cd -- which means I must be missing something really basic about container directory structure.
Also tried WORKDIR
Happy to add more info.
Original:
From within my container, I can successfully build using gralde as follows:
cd directory/with/gradlew && chmod +x gradlew && ./gradlew build
But when I put this in my Dockerfile and try to build the container, it fails with "file or directory gradlew does not exist":
RUN cd directory/with/gradlew && chmod +x gradlew && ./gradlew build.
From this question, Unable to change directories while building docker Image using Dockerfile , I am aware that cd resets with every RUN statement -- but I'm doing this all from within a single RUN.
Everything prior to this RUN statement is held constant, i.e., if I comment out the RUN, and build interactively from the command line in the image, it builds fine.
If it matters, I'm doing all this from within a GitHub codespace; I'm not using the Docker CLI directly.
What am I doing wrong?
--
EDIT: I must be trying to include/cd directories from outside the build context. I'm not sure how to fix that yet -- maybe with COPY?

Check the file contents of a docker image

I am new to docker and I built my image with
docker build -t mycontainer .
The contents of my Dockerfile is
FROM python:3
COPY ./* /my-project/
RUN pip install -r requirements.txt
CMD python /my-project/main.py
Here I get an error:
Could not open requirements file: No such file or directory: 'requirements.txt'
I am not sure if all the files from my local are actually copied to the image.
I want to inspect the contents of the image, is there any way I can do that?
Any help will be appreciated!
When you run docker build, it should print out a line like
Step 2/4 : COPY ./* /my-project/
---> 1254cdda0b83
That number is actually a valid image ID, and so you can get a debugging shell in that image
docker run --rm -it 1254cdda0b83 bash
In particular the place that container starts up will have the exact filesystem, environment variables (from ENV directives), current directory (WORKDIR), user (USER), and so on; directly typing in the next RUN command should get the same result as Docker running it itself.
(In this specific case, try running pwd and ls -l in the debugging shell; does your Dockerfile need a WORKDIR to tell the pip command where to run?)
You just have to get into the project directory and run the pip command.
The best way to do that is to set the WORKDIR /my-project!
This is the updated file
FROM python:3
COPY ./* /my-project/
WORKDIR /my-project
RUN pip install -r requirements.txt
CMD python /my-project/main.py
Kudos!

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

Docker WORKDIR - on my machine or the container?

What context does the WORKDIR keyword in a Dockerfile refer to? Is it in the context I run docker build from or inside the container I am producing?
I find myself often putting RUN cd && ... in my docker files and am hoping there's another way, I feel like I'm missing something.
It is inside the container.
Taken for the Dockerfile reference site https://docs.docker.com/engine/reference/builder/#workdir
The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. If the WORKDIR doesn’t exist, it will be created even if it’s not used in any subsequent Dockerfile instruction.
So rather than adding RUN cd && ... you could do:
WORKDIR /path/to/dir
RUN command
All paths in a Dockerfile, except the first half of COPY and ADD instructions, refer to image filesystem paths. The source paths for COPY and ADD are relative paths (even if they start with /) relative to the build context (the directory at the end of the docker build command, frequently the directory containing the Dockerfile). Nothing in a Dockerfile can ever reference an absolute path on the host or content outside the build context tree.
The only difference between these two Dockerfiles is the directory the second command gets launched in.
RUN cd /dir && command1
RUN command2
WORKDIR /dir
RUN command1
RUN command2
WORKDIR sets the directory inside the image and hence allows you to avoid RUN cd calls.

binary file not found on doing go build -o /bin/go_docker inside a docker file

below is the content of the dockerfile
FROM golang:1.8 as goimage
ENV SRC=/go/src/
RUN mkdir -p /go/src/
RUN mkdir /go/src/go_docker
WORKDIR /go/src/go_docker
RUN cd /go/src/go_docker
COPY StoreImage.go .
RUN go build -o /bin/go_docker
CMD ["/bin/go_docker"]
Docker build is successful for the above content.. But dont see the binary file generated in /bin/go_docker
Can someone please help me with this.
Make sure StoreImage.go can copy into docker
Binary file is created in /bin location and go_docker is the created binary file.
.exe will not be the extension in linux whereas .exe will be seen only in windows

Resources