docker-compose volumes_from equivalent with version 3 - docker

I'm trying to create an Nginx/PHP FPM setup with docker compose and am having issues with the version 3 volumes syntax/changes.
My Dockerfile:
FROM php:7-fpm
VOLUME /var/www/html
My docker-compose.yml:
version: "3"
services:
php:
build: .
volumes:
- ./html:/var/www/html
web:
image: nginx
links:
- php
ports:
- "8888:80"
volumes:
- php:/var/www/html
- ./default.conf:/etc/nginx/conf.d/default.conf
volumes:
php:
When I add an index.php file into ./html, I can view that by going to http://localhost:8888, but any static files (like CSS) return a 404 because Nginx cannot find those in its container (/var/www/html is empty on the nginx container). With version 3 docker compose files do not have volumes_from anymore, which is basically what I'm trying to replicate.
How can I get this to work with version 3?

For using "Named volumes" for sharing files between containers you need to define
1) volumes: section on the top level of yml file and define volume name
volumes:
php:
2) define volume section on first container like you did (Where share will mount)
web:
volumes:
- php:/var/www/html #<container_name>:<mount_point>
3) define volume section on second container (Share will mount from)
php:
volumes:
- php:/var/www/html
4) (optionally) If you need to store volume data on the host machine you can use local-persist docker plugin. You can specify docker volume driver and path where you data will be stored.
volumes:
php:
driver: local-persist
driver_opts:
mountpoint: /path/on/host/machine/
In your case you forgot define volume name for php container. Just replace
php:
build: .
volumes:
- ./html:/var/www/html
to
php:
build: .
volumes:
- php:/var/www/html
and use Local Persist Docker Plugin

Related

Docker volumes_from does not work as expected

Hello Guys I am facing a problem in volumes_from in docker-compose file.
- i have 3 services first one has my app files and the second is php-fpm which take volume from the data service.
my file is like this.
version: '2'
services:
cms_data:
image: ""image from private repository contain application file"
container_name: "cms-data"
php-fpm:
image: "image from private repository contain php configuration"
container_name: "php-fpm"
env_file:
- ../.env.production
volumes_from:
- cms_data
working_dir: /iprice/octobercms
expose:
- 9000
depends_on:
- cms_data
restart: "always"
nginx:
image: "image from private repository contain nginx configuration"
container_name: "nginx"
ports:
- "80:80"
- "443:443"
links:
- php-fpm
volumes_from:
- cms_data
depends_on:
- cms_data
restart: "always"
the cms-data image has the files which is correct.
but the php-fpm container doesn't please help.
volumes_from mounts the volumes present on other containers. It does not create new volumes.
The cms-data container does not have any volumes associated with it. So volumes_from cant do anything. If you want to share a particular folder inside cms-data, first create a volume linking that folder.
NOTE: creating a volume will overwrite the contents of the internal container with the /path/on/host folder. So first copy the contents of the container folder to this host folder.
Run the current docker-compose as is so the containers start.
Copy the contents from the cms-data container to the host folder:
docker cp :/path/to/shared/folder /path/on/host
Make the following changes to the docker-compose file and restart.
services:
cms_data:
image: ""image from private repository contain application file"
container_name: "cms-data"
volumes:
- /path/on/host:/path/to/shared/folder
...

How to share volumes among containers by docker-compose

My docker-compose defines two containers. I want one container shares a volume to the other container.
version: '3'
services:
web-server:
env_file: .env
container_name: web-server
image: web-server
build:
dockerfile: docker/Dockerfile
ports:
- 3000:3000
- 3500:3500
volumes:
- static-content: /workspace/static
command: sh /workspace/start.sh
backend-server:
volumes:
- static-content: /workspace/static
volumes:
static-content:
The above docker composer file declares two services, web-server and backend-server. And I declares the named volume static-content under services. I got below error when I run docker-composer -f docker-composer.yml up:
services.web-server.volumes contains an invalid type, it should be a string
services.backend-server.volumes contains an invalid type, it should be a string
so how can I share volumes throw docker-composer?
You have an extra space in your volume string that causes Yaml to change the parsing from an array of strings to an array of name/value maps. Remove that space in your volume entries (see below) to prevent this error:
version: '3'
services:
web-server:
env_file: .env
container_name: web-server
image: web-server
build:
dockerfile: docker/Dockerfile
ports:
- 3000:3000
- 3500:3500
volumes:
- static-content:/workspace/static
command: sh /workspace/start.sh
backend-server:
volumes:
- static-content:/workspace/static
volumes:
static-content:
For more details, see the compose file section on volumes short syntax.
You need to use the docker volumes syntax, without spaces
<local_path>:<service_path>:<optional_rw_attributes>
For example:
./:/your_path/
will map the present working directory to /your_path
And this example:
./:/your_path/:ro
will map the present working directory to /your_path with read only permissions
Read these docs for more info:
https://docs.docker.com/compose/compose-file/#volume-configuration-reference

Mounting a host directory to a docker container from yaml/compose file

I have part of my current config like this
mymicroservice:
image: service_img
networks: myoverlay
volumes:
- /Users/abcdUser/mountme:/opt/company/
This does the job as my machine's directory gets mounted to /opt/company when I deploy the docker swarm service stack.
However, I want to specify the source directory under a separate volumes: and then specify that name over there. I think this is possible but I am not able to find the syntax.
So I want something along the following lines but not able to do so:
mymicroservice:
image: service_img
networks: myoverlay
volumes:
- myownvolume:/opt/company/
volumes:
- myownvolume: /Users/abcdUser/mountme
I want to clarify that myownvolume here is just pointing to the directory /Users/abcdUser/mountme and I am not intending to create a docker volume. Or there is any other better way to do this?
It is possible to do so but not with the standard setup. The default volume driver doesn't allow the format you are looking for. You need to use docker plugins which requires external installation. Consider the below yaml
version: '2'
services:
one:
image: alpine
working_dir: /one/
command: sleep 600
volumes:
- data:/one/
two:
image: alpine
working_dir: /two/
command: sleep 600
volumes:
- data:/two/
volumes:
data:
driver: local-persist
driver_opts:
mountpoint: /data/local-persist/data
Above would work when you have the local-persist plugin installed. https://github.com/CWSpear/local-persist
You can find about other plugins available on
https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins
Also if repetition of volumes entries is an issues for you then you can use anchors in YAML
version: '3'
services:
alpines:
image: alpine
command: sleep 200
volumes: &common_volumes
- ./data:/data
- ./config:/config
alpine2:
image: alpine
command: sleep 200
volumes: *common_volumes
$ docker-compose config
services:
alpine2:
command: sleep 200
image: alpine
volumes:
- /home/vagrant/so/volumes2/data:/data:rw
- /home/vagrant/so/volumes2/config:/config:rw
alpines:
command: sleep 200
image: alpine
volumes:
- /home/vagrant/so/volumes2/data:/data:rw
- /home/vagrant/so/volumes2/config:/config:rw
version: '3.0'
That's not possible. You either have to use the bind mount syntax or the volume syntax. Volumes at the compose config top level won't allow you to mix both. See how to define a general mount point in docker compose for a similar question.

How to share data from host to containers using named volumes?

I'm trying to share code from host to php and nginx containers. Here is my docker-compose.yml:
version: "3"
services:
php:
image: php:fpm
container_name: php
ports:
- 9000:9000
volumes:
- php_data:/var/www/html/
# configs
- ./php/config:/usr/local/etc/php
nginx:
image: nginx
ports:
- 80:80
volumes:
- php_data:/var/www/html
# logs
- ./nginx/logs:/var/log/nginx
# configs
- ./nginx/config/default.conf:/etc/nginx/conf.d/default.conf:ro
- ./nginx/config/nginx.conf:/etc/nginx/nginx.conf:ro
volumes:
php_data:
./code
The error when running docker-compose up is:
ERROR: In file './docker-compose.yml', volume 'php_data' must be a
mapping not a string.
How do I make make docker-compose know, that I need ./code shared with both nginx and php containers?
Docker saying it needs a mapping, so you need to set something like ./code:{map} in your volume
I think you have 2 options here. Since you share the code map to /var/www/html on both containers.
Option 1
Set the /var/www/html map in your volume:
volumes:
php_data:
./code:/var/www/html
then change /var/www/html to / in your containers.
Option 2
volumes:
php_data:
./code:/

Docker container not writing to volume

I want to setup ownCloud with Docker and Docker-Compose. To achieve this I have a docker-compose.yml with 3 containers and their volumes.
version: '2'
services:
nginx:
build: ./nginx
networks:
- frontend
- backend
volumes:
- owncloud:/var/www/html
owncloud:
build: ./owncloud
networks:
- backend
volumes:
- owncloud:/var/www/html
- data:/data
mysql:
build: ./mariadb
volumes:
- mysql:/var/lib/mysql
networks:
- backend
volumes:
owncloud:
driver: local
data:
driver: local
mysql:
driver: local
networks:
frontend:
driver: bridge
backend:
driver: bridge
I also tried it without the data volume. ownCloud could not write to /data or without this volume to /var/www/html/data. The log only shows timestamps whenever I accessed ownCloud. Changing from data:/data to a hosted volume /var/ownclouddata:/data results in no difference.
The Dockerfiles have only one line each: FROM:image
I´ve tried adding RUN mkdir /data, but it didn´t fix anything.
You need to mount the volumes in the Dockerfile something like this.
VOLUME /data
Later in your docker-compose file, you can either use a named volume like you did earlier or simply use it like this.
/mnt/test:/data
Here /mnt/test is your host volume path and /data is your docker container path.
Hope it helps!

Resources