Reputation: 26624
I'm using docker-compose and v3. I'm trying to mount a volume in docker:
./appdata:/appdata
I'd like to have this as a volume and then reference that volume from multiple containers. The volume configuration reference only shows data-volume:
as a named volume, with no value, so it doesn't look like the above.
services:
nginx:
build: ./nginx/
ports:
- 80:80
links:
- php
volumes:
- app-volume
php:
build: ./php/
expose:
- 9000
volumes:
- app-volume
volumes:
app-volume: ./appdata:/appdata
This gives me:
ERROR: In file './docker-compose.yml', volume 'app-volume' must be a mapping not a string.
Obviously I know I need to change the volumes
key/value pair, but I'm not sure how to change this so I can share a volume between services.
I've also checked out volumes_from
but this effectively just allows inheritance from other containers. I've seen someone use volumes_from
on another container that contains the mapping they want, but with command: true
set so that the container is never actually run, which to me just seems like a hack.
How can I do this?
Note, I do have the following working:
nginx:
volumes:
- ./appdata:/appdata
php:
volumes:
- ./appdata:/appdata
But that's just duplication and is something I'm hoping a named volume could help me avoid :-)
Upvotes: 190
Views: 207547
Reputation: 22071
You can use one of the two options:
Named volumes: https://docs.docker.com/compose/compose-file/07-volumes/
extension-fields to avoid duplicating volumes source and prevent yourself from future typos:
version: '3.5'
x-services-volume:
&services-volume
type: bind
source: ./appdata
target: /appdata
services:
nginx:
build: ./nginx/
ports:
- 80:80
links:
- php
volumes: *services-volume
php:
build: ./php/
expose:
- 9000
# Use same way as for nginx if target override not needed.
volumes:
- <<: *services-volume
target: /opt/target-override
NOTE: This feature is available starting from version 3.4 file format.
Upvotes: 44
Reputation: 4435
Previous answers helped me a lot (thanks!) but it took some more time to figure out how to set options to create a shared tmpfs
volume (memory file system). I'm sharing it in the hope to make life easier for developers in the same situation.
An example showing only the relevant parts of docker-compose.yml
:
version: '3'
volumes:
shared-tmpfs:
driver: local
driver_opts:
type: "tmpfs"
device: "tmpfs"
o: "size=256m,uid=1000"
services:
nginx:
volumes:
- shared-tmpfs:/tmp/mytmpfs
php-fpm:
volumes:
- shared-tmpfs:/tmp/mytmpfs
I use it to spare my SSD from heavy writes (building lot's of static html files) in development/watch mode.
You can read more about driver_opts
in the official Docker docs here.
Upvotes: 15
Reputation: 36883
This solves it without using named volumes:
volumes:
- ./appdata:/appdata
So, it looks like:
services:
nginx:
build: ./nginx/
ports:
- 80:80
links:
- php
volumes:
- ./appdata:/appdata
php:
build: ./php/
expose:
- 9000
volumes:
- ./appdata:/appdata
Upvotes: 48
Reputation: 6606
The named volumes can be shared across containers in the following way:
services:
nginx:
build: ./nginx/
ports:
- 80:80
links:
- php
volumes:
- app-volume:location_in_the_container
php:
build: ./php/
expose:
- 9000
volumes:
- app-volume:location_in_the_container
volumes:
app-volume:
Here's an example config that I use for better understanding. I'm exposing the static files generated from my web
container to a named volume called static-content
which is then read and served by the nginx
container:
services:
nginx:
container_name: nginx
build: ./nginx/
volumes:
- static-content:/usr/src/app
web:
container_name: web
env_file: .env
volumes:
- static-content:/usr/src/app/public
environment:
- NODE_ENV=production
command: npm run package
volumes:
static-content:
Upvotes: 223