How to run shell command in Dockerfile after docker container starts up? - docker

Based on bitnami-docker-jasperreports I'm trying to copy some files and folders to jasperserver folder deployed in tomcat, first i added a COPY and ADD instructions within my Dockerfile and both of them can not work with the deployed folder because it's not already present or it gets overridden after copying them to it, then I tried to add and ENTRYPOINT, RUN and CMD instructions and all of them have failed.
here is my Dockerfile with Entrypoint instruction
FROM bitnami/jasperreports:7.8.0
ADD . /bitnami/
ENTRYPOINT [ "cp", "/bitnami/jrs/.", "/bitnami/tomcat/data/jasperserver/WEB-INF/" ]
NB: jrs folder is in the same folder as my Dockerfile
Edit: I've added a volume to the container to see jasperserver folder in my machine but i found that the link is broken, however when I acces it trough docker bash it seems fine.
docker bash:

Related

Mis-understand of copy file in docker images

Hello could someone pleas help me on copying docker(I'm starter) host file into my jupyter/pyspark-notebook images. I've pulled this notebook from docker as public available.
I've created a Dockerfile which contains this.
FROM jupyter/pyspark-notebook:latest
ADD /home/abdoulaye/Documents/M2BIGDATA/Jaziri /bin/bash
I've changed /bin/bash to . but nothing is visible.
when I execute docker built it's like it copy files as shown in output below.
when I go to my my notebook I did note found folders. I check my snapshot if I can found these copied folder but I'm very confused.
In clear, I've an running notebook in my docker I use it in y navigator but I can not load data. I like to copy data in place where I can access it in notebook.
You can not copy using absoult path, the path should be relative to Dockerfile, so /home/abdoulaye/Documents/M2BIGDATA/Jaziri this path inside Dockerfile is not correct. Copy file to Dockerfile context and then copy like
ADD M2BIGDATA/Jaziri /work
Now First thing, you should not copy files from host to executable files directory.
For instance,
FROM alpine
copy hello.txt /bin/sh
If you copy like this, it will create a problem to run command inside container as sh or bash will be replaced or corrupt.
2nd, while you are building the docker image with invalid context, it should be the same where your Dockerfile is, so better to run the directory where you place the Dockerfile.
docker build -t my-jupyter .
3rd, you should not run cp command inside container to copy files from host to container.
docker cp /home/abdoulaye/Documents/M2BIGDATA/Jaziri container_id:/work
it will copy your files to /work path of the container.

Troubleshoot directory path error in COPY command in docker file

I am using COPY command in my docker file on top of ubuntu 16.04. I am getting error as no such file or directory eventhough the directory is present. In the below docker file I want to copy the directory "auth" present inside workspace directory to the docker image (at path /home/ubuntu) and then build the image.
FROM ubuntu:16.04
RUN apt-get update
COPY /home/ubuntu/authentication/workspace /home/ubuntu
WORKDIR /home/ubuntu/auth
a Dockerfile COPY command can only refer to files under the context - the current location of the Dockerfile, aka .
so you have a few options now:
if it is possible to copy the /home/ubuntu/authentication/workspace/ directory content to somewhere inside your project before the build (so now it will be included in your Dockerfile context and you can access it via COPY ./path/to/content /home/ubuntu) it can be great. but sometimes you dont want it.
instead of copying the directory, bind it to your container via a volume:
when you run the container, add a -v option:
docker run [....] -v /home/ubuntu/authentication/workspace:/home/ubuntu [...]
mind that a volume is designed so any change you made inside the container dir(/home/ubuntu) will affect the bound directory on your host side (/home/ubuntu/authentication/workspace) and vice versa.
i found a something over here: this guy is forcing the Dockerfile to accept his context- he is sitting inside the /home/ubuntu/authentication/workspace/ directory, and running there
docker build . -f /path/to/Dockerfile
so now inside his Dockerfile he can refer to /home/ubuntu/authentication/workspace as his context (.)

Docker: How to copy a file from one folder in a container to another?

I want to copy my compiled war file to tomcat deployment folder in a Docker container. As COPY and ADD deals with moving files from host to container, I tried
RUN mv /tmp/projects/myproject/target/myproject.war /usr/local/tomcat/webapps/
as a modification to the answer for this question. But I am getting the error
mv: cannot stat ΓÇÿ/tmp/projects/myproject/target/myproject.warΓÇÖ: No such file or directory
How can I copy from one folder to another in the same container?
You can create a multi-stage build:
https://docs.docker.com/develop/develop-images/multistage-build/
Build the .war file in the first stage and name the stage e.g. build, like that:
FROM my-fancy-sdk as build
RUN my-fancy-build #result is your myproject.war
Then in the second stage:
FROM my-fancy-sdk as build2
COPY --from=build /tmp/projects/myproject/target/myproject.war /usr/local/tomcat/webapps/
A better solution would be to use volumes to bind individual war files inside docker container as done here.
Why your command fails
The command you are running tries to access files which are out of context to for the dockerfile. When you build the image using docker build . the daemon sends context to the builder and only those files are accessible during the build. In docker build . the context is ., the current directory. Therefore, it will not be able to access /tmp/projects/myproject/target/myproject.war.
Copying from inside the container
Another option would be to copy while you are inside the container. First use volumes to mount the local folder inside the container and then go inside the container using docker exec -it <container_name> bash and then copy the required files.
Recommendation
But still, I highly recommend to use
docker run -v "/tmp/projects/myproject/target/myproject.war:/usr/local/tomcat/webapps/myproject.war" <image_name>

Docker mount happens before or after entrypoint execution

I'm building a Docker image to run my Spring Boot based application. I want to have user to be able to feed a run time properties file by mounting the folder containing application.properties into container. Here is my Dockerfile,
FROM java:8
RUN mkdir /app
RUN mkdir /app/config
ADD myapp.jar /app/
ENTRYPOINT ["java","-jar","/app/myapp.jar"]
When kicking off container, I run this,
docker run -d -v /home/user/config:/app/config myapp:latest
where /home/user/config contains the application.properties I want the jar file to pick up during run time.
However this doesn't work, the app run doesn't pick up this mounted properties file, it's using the default one packed inside the jar. But when I exec into the started container and manually run the entrypoint cmd again, it works as expected by picking up the file I mounted in. So I'm wondering is this something related to how mount works with entrypoint? Or I just didn't write the Dockerfile correctly for this case?
Spring Boot searches for application.properties inside a /config subdirectory of the current directory (among other locations). In your case, current directory is / (docker default), so you need to change it to /app. To do that, add
WORKDIR /app
before the ENTRYPOINT line.
And to answer your original question: mounts are done before anything inside the container is run.

How to conditionally mount host-container volume in dev environment and ADD at build time?

Suppose my I checkout my code from github onto ~/repos/shinycode .
$> cd ~/repos/shinycode
$> ls
Dockerfile
www/index.html
$> cat Dockerfile
FROM nginx
ADD www /usr/share/nginx/html
For deployment, everything works fine: checkout from github and run docker build.
In dev environment, however, I want to run the container using the same Dockerfile but also live-edit files in the www directory, such as would have if I supplied a -v www:/usr/share/nginx/html option to docker run.
What is the best practice in this case? Should I have a separate Dockerfile for dev without the final ADD command? Am I going about this in the entirely wrong way?
Thanks
You can use the same Dockerfile and mount over the image's /usr/share/nginx/html folder with any external volume. The mount of the volume takes precedence in the filesystem and you won't see anything from the image at that location.

Resources