I have one Dockerfile which more or less does:
VOLUME /files
RUN echo "foo" > /files/x
And then I have a docker-compose.yml which more or less is:
version: '3'
services:
files:
volumes:
- files:/files
other_service:
volumes:
- files:/files
depends_on:
- files
volumes:
files:
The problem is that the /files gets overwritten by the docker-compose (and gets empty).
In the past (with docker-compose v2) I think that I used something like this:
version: '2'
services:
files:
other_service:
volumes_from:
- files
depends_on:
- files
worked
How can I do it in version 3?
(Declaring a volume in the Dockerfile, putting some files inside this volume and then, have these files available in other containers (with docker-compose)
Related
I have python tests that generate the results of the tests as HTML and XML files. When I run docker-compose, I want to find these results and mount them in a local volume.
docker-compose.yml
version "3.9"
services:
tests:
build: .
image: test-image
volumes:
- myLocalVolumes:/my/url/to/tests/results
volumes:
myLocalVolumes
I am using a MacBook. Any tips on how to find the URL of these test results.
I think it has to be taken from inside the container or stored somewhere in the computer.
if your goal is to save test results. first find where the results are saved in the container. if your script/code write results to folder called results in the same working directory
you should first find the working dir
you can find it in the Dockerfile
example:
WORKDIR /project
then mount the results directory to the docker volume
version "3.9"
services:
tests:
build: .
image: test-image
volumes:
- myLocalVolumes:/project/results
volumes:
myLocalVolumes
you will find volume in the path /var/lib/docker/volumes/myLocalVolumes
or in more simple way you can mount to a folder in the host machine
version "3.9"
services:
tests:
build: .
image: test-image
volumes:
- ./results:/project/results
if your script/code generates individual files with different unique names it's better to modify the code to put results into a directory so you can mount them easily.
The solution is there is a folder named results inside the project. That folder contains all the results of the tests as HTML and XML files. To mount that data, we will do: myLocalVolumes:/results.
The complete docker-compose.yml will be
version "3.9"
services:
tests:
build: .
image: test-image
volumes:
- myLocalVolumes:/results
volumes:
myLocalVolumes
I have the following two docker compose files:
docker-compose.yml :
version: '2.3'
services:
# test11 service
test11:
build: test11/.
image: "test11"
and
docker-compose.yml (file inside the folder named test11 that contains Dockerfile and the following docker-compose ):
version: '2.3'
networks:
citrixhoneypot_local:
services:
# CitrixHoneypot service
test11:
build: .
container_name: test11
restart: always
networks:
- citrixhoneypot_local
ports:
- "443:443"
image: "test11:2006"
# read_only: true
volumes:
- test11:/opt/test11/logs
volumes:
test11:
driver:local
when i run docker-compose up --build for the first file, everything seems ok and the container build and i can run exec -it sh on it and get access.
but the problem is that the volume isn't made in the path
/var/lib/docker/volumes and i can't find it there.
also when i write in /opt/test11/logs from inside the docker container no file is made under /var/lib/docker/volumes .
I tried this with bind path too. same problem with that too.
I have a few questions about Docker volumes. I have installed Docker and docker-compose on a fresh host running debian stretch. I managed to get a docker-compose file running for a simple nginx/php-fpm project, both containers mounted on the directory containing the source code. I wanted to try to create a single volume that would be shared across my containers but I have a few issue, and my understanding of the official documentation is not helping.
So this is an idea of what I'm trying to achieve :
Question 1 : Trying to create a volume from a dockerfile on a directory mounted from host
docker-compose.yml :
version: '3'
services:
php:
build:
context: .
dockerfile: php.dockerfile
volumes:
- ./host-project-directory:/project
php.dockerfile :
FROM php:7-fpm
VOLUME project
from my understanding, when running docker-compose we should have a volume created on host containing all files from /project from container. And /project from container should contain all files from ./host-project-directory from host.
If I ls the content of /project on container I can see the files from host, but using docker volume list, there are no volumes created on host, why ?
Question 2 : How to populate and use this volume from another container ?
version: '3'
services:
php:
build:
context: .
dockerfile: php.dockerfile
volumes:
- named-volume:/project
web:
image: nginx
links:
- php
volumes:
- named-volume:/project
volumes:
named-volume:
This should create a volume called 'named-volume' and bind it to /project directories on both containers php and web.
Now, how to populate this volume with content from ./host-project-directory ?
I've tried adding a dockerfile like
ADD ./host-project-directory /project
But nothing changed and the volume remained empty.
I'm sorry if this is due to my lack of experience using Docker but I can't figure out how to make this simple thing work.
Thank you for your time !
For the first question, I try a simple docker file like this:
FROM php:7-fpm
COPY ./project /project
And a docker-compose like this:
version: '3'
services:
php:
build: .
volumes:
- named-volume:/project
web:
image: nginx
links:
- php
volumes:
- named-volume:/project
volumes:
named-volume:
Since you create the volume on docker-compose you don't need to create that in the Dockerfile.
Running docker volume list, I'm able to see the volume created with a local driver. Making ls inside the folder I'm also able to see the file. It's important to note, that the file present in you local directory it's not the same that the file inside the container. So if you edit the files in the host this will not change the files in container. That's because you have your volume created in another path, probably at: /var/lib/docker/volumes/...
This happens because you map the volume to the path, but you not specifies where you want the volume. To do that just make your docker-compose like this:
version: '3'
services:
php:
build: .
volumes:
- ./project:/project
web:
image: nginx
links:
- php
volumes:
- ./project:/project
Making this I'm still able to see the volume with the volume list command but without a name.
So I don't know why you are not able to see the volume in the list.
For question 2:
Doing the example above I have the files inside the container that exists in my local "project" folder.
Please check that the path to the local folder is correct.
A bind mount is not the same thing as a volume. You're defining a named volume here, but wanting the functionality of a bind mount.
Try this
version: '3'
services:
php:
build:
context: .
dockerfile: php.dockerfile
volumes:
- ./host-project-directory:/project
web:
image: nginx
links:
- php
volumes:
- ./host-project-directory:/project
I am trying to allow nginx to proxy between multiple containers while also accessing the static files from those containers.
To share volumes between containers created using docker compose, the following works correctly:
version: '3.6'
services:
web:
build:
context: .
dockerfile: ./Dockerfile
image: webtest
command: ./start.sh
volumes:
- .:/code
- static-files:/static/teststaticfiles
nginx:
image: nginx:1.15.8-alpine
ports:
- "80:80"
volumes:
- ./nginx-config:/etc/nginx/conf.d
- static-files:/static/teststaticfiles
depends_on:
- web
volumes:
static-files:
However what I actually require is for the nginx compose file to be in a separate file and also in a completely different folder. In other words, the docker compose up commands would be run separately. I have tried the following:
First compose file:
version: '3.6'
services:
web:
build:
context: .
dockerfile: ./Dockerfile
image: webtest
command: ./start.sh
volumes:
- .:/code
- static-files:/static/teststaticfiles
networks:
- directorylocation-nginx_mynetwork
volumes:
static-files:
networks:
directorylocation-nginx_mynetwork:
external: true
Second compose file (ie: nginx):
version: '3.6'
services:
nginx:
image: nginx:1.15.8-alpine
ports:
- "80:80"
volumes:
- ./nginx-config:/etc/nginx/conf.d
- static-files:/static/teststaticfiles
networks:
- mynetwork
volumes:
static-files:
networks:
mynetwork:
The above two files work correctly in the sense that the site can be viewed. The problem is that the static files are not available in the nginx container. The site therefore displays without any images etc.
One work around which works correctly found here is to change the nginx container static files volume to instead be as follows:
- /var/lib/docker/volumes/directory_static-files/_data:/static/teststaticfiles
The above works correctly, but it seems 'hacky' and brittle. Is there another way to share volumes between containers which are housed in different compose files without needing to map the /var/lib/docker/volumes directory.
By separating the 2 docker-compose.yml files as you did in your question, 2 different volumes are actually created; that's the reason you don't see data from web service inside volume of nginx service, because there are just 2 different volumes.
Example : let's say you have the following structure :
example/
|- web/
|- docker-compose.yml # your first docker compose file
|- nginx/
|- docker-compose.yml # your second docker compose file
Running docker-compose up from web folder (or docker-compose -f web/docker-compose.yml up from example directory) will actually create a volume named web_static-files (name of the volume defined in docker-compose.yml file, prefixed by the folder where this file is located).
So, running docker-compose up from nginx folder will actually create nginx_static-files instead of re-using web_static-files as you want.
You can use the volume created by web/docker-compose.yml by specifying in the 2nd docker compose file (nginx/docker-compose.yml) that this is an external volume, and its name :
volumes:
static-files:
external:
name: web_static-files
Note that if you don't want the volume (and all resources) to be prefixed by the folder name (default), but by something else, you can add -p option to docker-compose command :
docker-compose \
-f web/docker-compose.yml \
-p abcd \
up
This command will now create a volume named abcd_static-files (that you can use in the 2nd docker compose file).
You can also define the volumes creation on its own docker-compose file (like volumes/docker-compose.yml) :
version: '3.6'
volumes:
static-files:
And reference this volume as external, with name volumes_static-files, in web and nginx docker-compose.yml files :
volumes:
volumes_static-files:
external: true
Unfortunately, you cannot set the volume name in docker compose, it will be automatically prefixed. If this is really a problem, you can also create the volume manually (docker volume create static-files) before running any docker-compose up command (I do not recommand this solution though because it adds a manual step that can be forgotten if you reproduce your deployment on another environment).
I'm using this docker-compose file:
version: '2'
services:
php:
container_name: "php"
build: ./php
volumes:
- ./../php:/var/www
- ./../core:/var/www/core
./../php - does not have core dir. After starting everything is ok. But after 5 seconds /var/www/core is empty and I see empty core directory inside ./../php/core.
I think container reload this empty directory(./../php/core) from host and ignores second volume binding(./../core:/var/www/core)
How use correctly?