Creating an empty directory to docker container - docker

How do I create an empty folder inside a docker container using a Dockerfile?
I guess I could just copy an empty folder from source as an empty "backup" directory to the container like:
COPY empty_dir backup
... but what I would like to do, is just to create the folder without referring to anything existing.
A script running in the container would need to access this folder later on to copy some backup-files into it.
Is there a command like MKDIR to be used in the Dockerfile?
Simple question, but couldn't find answer to it (easily at least).

You could create it with :
RUN mkdir -p /path/to/my/myemptydir
-p allows to make intermediate directories.

Related

Moving files onto docker container and running them

I'm pretty new to docker, so I apologize if this is a simple question. I need to create a script of some sort that will start a docker image in ubuntu:16.04, copy files from a directory onto the container, and run some of the code that was just copied in.
From what I understand, the first step would be to start up the container with something like this:
docker run --name test_container my_image
Then, I need to copy over the files. From what I have found, this is conventionally done on the host with a command like so:
docker cp src/. test_container:/code/src
Lastly, lets say I want to run some code from my container, that I just put on it. If I started my container with the -it tag, I could probably just do something like the following (assuming there was a makefile and hello_world.c in the src folder that was copied):
cd code/src/
make
./hello_world
But is there some way I can have this automated. For example, I want to put the following lines in my docker file:
WORKDIR code/src/
RUN make
RUN ./hello_world
But the main problem is that if I run my dockerfile right at the beginning, I will not have my copied files on the container by the time I get to these commands at the bottom.
I was looking to see if there is a way to copy files onto the container by running commands inside the container. For example:
RUN docker cp src/. test_container:/code/src
But that doesn't seem to work, which kind of makes sense. So I was wondering if there is another good way to automate a process like this.
If you want to bake your files into the image the command is
COPY src /code/src/
WORKDIR /code/src
RUN make
CMD ["./hello_world"]
If you want to use files at runtime, you'd do it with something like
docker run -v $CWD/src:/code/src myimage make

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 (.)

How to write files in Docker Images?

I've copied a file into a docker image with:
COPY dbconfig.xml /var/app/dbconfig.xml
After that I tried to replace some values in the file with:
RUN sed -i "s/PASSWD/$dbpasswd/" /var/app/dbconfig.xml
Note that $dbpassword is an ENV Variable.
When I check the contents of config.xml, by starting a container of that image and running a bash inside it, nothing has changed in the dbconfig.xml.
Now I think I misunderstand some fundamentals of docker images..
I even tested to create a simple file:
RUN echo "test" > newfile.txt
which seems to be deleted after the call..
I know that each RUN statement creates an new layer and after the statement it gets removed(?).
I'm confused. Why does something like installing software with
RUN apt-get install -y some-package
doesn't get removed and creating a simple file does get removed?
So.. how can I change files inside docker images at image-build-time?
Dockerfile:
FROM dchevell/jira-software:8.0
COPY dbconfig.xml /var/atlassian/application-data/jira/dbconfig.xml
WORKDIR /var/atlassian/application-data/jira
# set default password to admin
ENV dbpasswd=admin
RUN sed -i "s/PASSWD/$dbpasswd/" dbconfig.xml \
&& cat dbconfig.xml
RUN echo "test" > newfile.txt
dbconfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<jira-database-config>
<name>defaultDS</name>
<delegator-name>default</delegator-name>
<database-type>postgres72</database-type>
<schema-name>public</schema-name>
<jdbc-datasource>
<url>jdbc:postgresql://docker-postgres:5432/jiradb</url>
<driver-class>org.postgresql.Driver</driver-class>
<username>atlasdb</username>
<password>PASSWD</password>
<pool-test-while-idle>true</pool-test-while-idle>
</jdbc-datasource>
</jira-database-config>
Update 1
Confusingly, when I COPY something in the WORKDIR folder, it persists, but when I try to modify it afterwards with SED, these changes do not persist! I think there is some really dark magic happening in the background..
Maybe I try to bind mount my preconfigured dbconfig.xml within docker-compose and see if that helps..
Update 2
From the Docker Documentation:
Changing the volume from within the Dockerfile: If any build steps
change the data within the volume after it has been declared, those
changes will be discarded.
I totally missed that! Thanks David for pointing me there:) So creating and writing Files DOES work as expected, but be careful with VOLUME directories. RUN statements do not work here.
So to address this issue, the best practice would be to bind mount the file into that volume.
If you look at the Dockerfile for that base image, it says in part
ENV JIRA_HOME /var/atlassian/application-data/jira
VOLUME ["${JIRA_HOME}"]
Once you execute a VOLUME statement in a Dockerfile, later Dockerfile statements can't make any more changes in that specific directory.
Given that the sorts of things you're trying to change are very installation-specific settings (admin password, database settings) I wouldn't try to build an image out of these. Instead I'd use the docker run -v option to inject the configuration file at runtime.
Each RUN statement does not create an intermediate container but creates a new layer on union file system, which is read only. When you run an image, a special writable layer is created for this container and all the changes you make on this container are written to this layer. (except the volumes. which is a different concept). That is why docker is able to share the same image (or even layers) between containers safely, without affecting each other. You can check docker documentation for more information.
For your question, you should see every change you make on build time in the running instance of this image, unless you somehow delete or overwrite them.
See this question.
The commands you are running are correct and they should create the files. What I suspect is that when you run your container, the jira application is overwriting the WORKDIR you have specified.
Try this Dockerfile:
WORKDIR /var/atlassian/application-data/jira
# set default password to admin
ENV dbpasswd=admin
RUN sed -i "s/PASSWD/$dbpasswd/" dbconfig.xml \
&& cat dbconfig.xml
WORKDIR /testtest
RUN touch test.txt
RUN echo "test" > newfile.txt
WORKDIR /var/atlassian/application-data/jira
Now if you start the container, you can see that the files are being created inside the /testtest folder.
If you want your changes to the dbconfig.xml file to persist you should try using volumes to bind the local dbconfig.xml with the jira folder.
Thanks for this interesting question :)

Is it possible to persist a file in a docker image?

I want to prepare a base docker image that executes a command and produces a report. I want this to be persisted within the image for the next docker file. Is this possible?
What you can do is to set a WORKDIR within your dockerfile e.g.
WORKDIR /data
and use a volume with the run command for the built image.
docker run -v /users/home/your_user/use_case_folder:/data -it your_image_tag /bin/bash
When you run your reports/predictions you have to write them to /data, then your files will be placed on your local system. You now can use the next
Dockerfile and use the same volume mount, which is defined as WORKDIR within the new Dockerfile. Sharing the results within the image itself for another image is not possible as far as I know. You will always have to use an outside mounted File System or Database or sth. similar.
Maybe here you can find some infos too:
https://docs.docker.com/storage/volumes/#restore-container-from-backup

Resources