I want to copy files from host to Docker container when I run the container on any host.
here is my Dockerfile
FROM tomcat:9
EXPOSE 8080
ADD ./target/app.war /tmp/myapp.war
RUN unzip /tmp/myapp.war -d /usr/local/tomcat/webapps/myapp
ENTRYPOINT ["cp", "-r", "/data/*", "/usr/local/tomcat/webapps/myapp/data"]
After building the docker image
docker build -t myappimage .
I am running it with:
docker run --mount type=bind,source=d:/data,destination=/data --rm -it -p 8081:8080 myappimage
but this throws error cp: cannot stat '/data/*': No such file or directory
I am not sure why mounting is not working, it should copy all files from my host directory d:/data to Docker container directory /data when a container starts.
This command in ENTRYPOINT is run in Docker container.
You can try:
FROM tomcat:9
EXPOSE 8080
ADD ./target/app.war /tmp/myapp.war
RUN unzip /tmp/myapp.war -d /usr/local/tomcat/webapps/myapp
COPY /data /usr/local/tomcat/webapps/myapp/data/
I hope /usr/local/tomcat/webapps/myapp/data directory exist in image prior to copying. The command seems to working fine on my machine (Mac). Not sure if it's the d:/ that is causing the issue.
Also you can try using the -v option with a z flag (It solved the same issue for me), assuming you are inside d: directory
docker run -v "$(pwd)"/data:/data:z --rm -it -p 8081:8080 myappimage
With -v it will create an endpoint for you. You can read here
Related
I've just started dabbling with Docker. I notice that when directly pulling the PHP-Apache image and mounting a volume, this works fine:
docker run -d -p 80:80 --name php-try -v C:\Users\me\Desktop\php-try:/var/www/html php:7.2-apache
But when I build an image with a Dockerfile, copying the contents of the working directory to the usual /var/www/html folder, and then try to run a container with a volume or bind mount docker run -d -p 80:80 php-try -v C:\Users\me\Desktop\php-try:/var/www/html the container simply exits/doesn't run. Without the attempt to mount a volume, it runs fine.
The Dockerfile is simply:
FROM php:7.2-apache
COPY . /var/www/html/
Grateful for any help with this.
I am trying to bindmount a directory form docker container to my host directory called /home, the docker container directory which I am trying to sync is named as /test and it contains a file called new.txt.
My Dockerfile is in /home/sampledocker1 directory. Its contents are as follows:
FROM ubuntu:18.04
RUN ["/bin/bash", "-c", "mkdir test"]
COPY new.txt test
Here, local file new.txt available in current path.
I executed the below commands first I built the docker image and started the container as follows:
docker build -t sample1:latest . # image is created properly
docker run -t -d -v /home:/test sample1:latest /bin/bash
After creating container with mount option, I am expecting that the file new.txt in test folder of container would appear in my /home directory but it did not.
Here bindmount is not happening properly.
By running -v option you actually override directory that already exists in the docker file.
If you run:
docker run -ti sample1:latest /bin/bash
You will find /test/new.txt file because it is added to the image layer with COPY command on the Dockerfile.
If you run:
docker run -ti -v /home:/test sample1:latest /bin/bash
You will find the contents of your computers /home directory in the /test of the docker container, because -v (mouted volume) overrides original image layer created with the COPY command on the Dockerfile.
THE SUGGESTION: Remove both COPY and mkdir commands from your Dockerfile:
FROM ubuntu:18.04
# Nothing at all
And mount your current directory with your docker run command:
docker run -ti -v $(pwd):/test sample1:latest /bin/bash
Since your Dockerfile is empty, equivalent command is just running ubuntu:18:04 image:
docker run -ti -v $(pwd):/test ubuntu:18.04 /bin/bash
p.s. I changed -d (detached) to -i(interactive) on the example to make sure that you enter docker image as soon as you run docker run command.
Here is my docker file I was wondering how can I copy the local html code which is in the same directory as my dockerfile. This command somehow did not work as when I ran a curl on my docker IP
it was not my html code it was the default code.
FROM httpd
EXPOSE 80
COPY public-html.html /usr/local/apache2/htdocs/
The problem is that you built the image, but did not run it.
Example to run it by mounting the file as a volume into the container:
docker run -it --rm -d -p 8080:80 --name web -v ./public-html.html:/usr/share/nginx/html nginx
Now you can do a curl http://localhost:8080.
Example for building it:
FROM nginx:latest
COPY ./public-html.html /usr/share/nginx/html/index.html
More information here
I am facing an issue where after runnig the container and using bind mount to mount the directory on host to container I am not able to see new files created in host machine inside container.Below is my project structure.
The python code creates a file inside the container which should be available inside the host machine too however this does happen when I start the container with below command. However updates to python code and html is available inside the container.
sudo docker container run -p 5000:5000 --name flaskapp --volume feedback1:/app/feedback/ --volume /home/deepak/PycharmProjects/NewDockerProject/sampleapp:/app flask_image
However after starting the container using below command, everything seems to work fine. I can see all the files from container to host and vice versa(new created , edited).I git this command from docker in the month of lunches book.
sudo docker container run --mount type=bind,source=/home/deepak/PycharmProjects/NewDockerProject/sampleapp,target=/app -p 5000:5000 --name flaskapp
Below is the content of my dockerfile
FROM python:3.8-alpine
WORKDIR /app
COPY ./requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python","main.py"]
Could someone please help me in figuring out the difference between the two commands ? I am using ubuntu. Thank you
In my case i got working volumes using following docker run args (but i am running without --mount type=bind):
docker run -it ... -v mysql_data:/var/lib/mysql -v storage:/usr/shared/app_storage
where:
mysql_data is a volume name
/var/lib/mysql path inside container machine
you could list volumes as:
docker volume ls
and inspect them to see where it points on your system (usually /var/lib/docker/volumes/{volume_nanme}/_data):
docker volume inspect mysql_data
to create volume use following command:
docker volume create {volume_name}
I created a Flask Application. This application receives a XML from a url and saves it:
response = requests.get(base_url)
with open('currencies.xml', 'wb') as file:
file.write(response.content)
When I run the application without Docker, the file currencies.xml is correctly created inside my app folder.
However, this behaviour does not occur when I use docker.
In docker I run the following commands:
docker build -t my-api-docker:latest .
docker run -p 5000:5000 my-api-docker ~/Desktop/myApiDocker # This is where I want the file to be saved: inside the main Flask folder
When I run the second command, I get:
docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"/Users/name/Desktop/myApiDocker\": stat /Users/name/Desktop/myApiDocker: no such file or directory": unknown.
ERRO[0001] error waiting for container: context canceled
But If I run:
docker build -t my-api-docker:latest .
docker run -p 5000:5000 my-api-docker # Without specifying the PATH
I can access the website (but it is pretty useless without the file currencies.xml
Dockerfile
FROM python:3.7
RUN pip install --upgrade pip
COPY ./requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip install -r requirements.txt
COPY . /app
EXPOSE 5000
CMD [ "flask", "run", "--host=0.0.0.0" ]
When you
docker run -p 5000:5000 my-api-docker ~/Desktop/myApiDocker
Docker interprets everything after the image name (my-api-docker) as the command to run. It runs /Users/name/Desktop/myApiDocker as a command, instead of what you have as the CMD in the Dockerfile, and when that path doesn't exist in the container, you get the error you see.
It's a little unlikely you'll be able to pass this path to your flask run command as a command-line argument. A typical way of dealing with this is by using an environment variable instead. In your code,
download_dir = os.environ.get('DOWNLOAD_DIR', '.')
currencies_xml = os.path.join(download_dir, 'currencies.xml')
with open(currencies_xml, 'wb') as file:
...
Then when you start your container, you can pass that as an environment variable with the docker run -e option. Note that this names a path inside the container; there's no particular need for this to match the path on the host.
docker run \
-p 5000:5000 \
-e DOWNLOAD_DIR=/data \
-v $HOME/Desktop/myApiDocker:/data \
my-api-docker
It's also fairly common to put an ENV statement in your Dockerfile or otherwise pick a fixed path for this, and just specify that your image's interface is that it will download the file into whatever is mounted on /data.
When you docker run the image, the process' context is the container's file system not your host's file system. So my-api-docker ~/Desktop/myApiDocker (attempts to) place the file in the container's (!) ~/Desktop.
Instead you need to mount one of your host's directories into the container's file system and store the file in the mounted directory.
Something like:
docker run ... \
--volume=[HOST-PATH]:[CONTAINER-PATH] \
... \
my-api-docker [CONTAINER-PATH]/thefile
The container then writes the file to [CONTAINER-PATH]/thefile but this is mapped to the host's [HOST-PATH]/thefile.
NB The values for [HOST-PATH] and [CONTAINER-PATH] must be absolute not relative paths.
You may prove this behavior to yourself using e.g. either python:3.7 or busybox:
# List my host's root
ls -l /
# List the container's root
docker run --rm busybox ls -l /
# Mount the host's /tmp into the container's /tmp
ls -l /tmp
docker run --rm --volume=/tmp:/tmp busybox ls -l /tmp
HTH!