62

I've nignx container and one asset container which have all my assets build from grunt or some other tools.

Now in docker compose file, i want to mount asset container's 's folder path into nginx container so nginx can serve that files.

  • How can we do that? i don't remember but i think there is a option where we can share path of one container with another.

  • Suppose if i scale up nginx to 2 container then will that mount works for all instance of nginx?

  • if i scale up asset container then what will happen?

  • i also want to mount that with my host so development can be done be easily.

dev.meghraj
  • 8,542
  • 5
  • 38
  • 76

1 Answers1

106

What you want to do is use a volume, and then mount that volume into whatever containers you want it to appear in.

Completely within Docker

You can do this completely inside of Docker.

Here is an example (stripped-down - your real file would have much more than this in it, of course).

version: '3'
services:
  nginx:
    volumes:
      - asset-volume:/var/lib/assets
  asset:
    volumes:
      - asset-volume:/var/lib/assets

volumes:
  asset-volume:

At the bottom is a single volume defined, named "asset-volume".

Then in each of your services, you tell Docker to mount that volume at a certain path. I show example paths inside the container, just adjust these to be whatever path you wish them to be in the container.

The volume is an independent entity not owned by any particular container. It is just mounted into each of them, and is shared. If one container modifies the contents, then they all see the changes.

Note that if you prefer only one can make changes, you can always mount the volume as read-only in some services, by adding :ro to the end of the volume string.

services:
  servicename:
    volumes:
      - asset-volume:/var/lib/assets:ro

Using a host directory

Alternately you can use a directory on the host and mount that into the containers. This has the advantage of you being able to work directly on the files using your tools outside of Docker (such as your GUI text editor and other tools).

It's the same, except you don't define a volume in Docker, instead mounting the external directory.

version: '3'
services:
  nginx:
    volumes:
      - ./assets:/var/lib/assets
  asset:
    volumes:
      - ./assets:/var/lib/assets

In this example, the local directory "assets" is mounted into both containers using the relative path ./assets.

Using both depending on environment

You can also set it up for a different dev and production environment. Put everything in docker-compose.yml except the volume mounts. Then make two more files.

  • docker-compose.dev.yml
  • docker-compose.prod.yml

In these files put only the minimum config to define the volume mount. We'll mix this with the docker-compose.yml to get a final config.

Then use this. It will use the config from docker-compose.yml, and use anything in the second file as an override or supplemental config.

docker-compose -f docker-compose.yml \
    -f docker-compose.dev.yml \
    up -d

And for production, just use the prod file instead of the dev file.

The idea here is to keep most of the config in docker-compose.yml, and only the minimum set of differences in the alternative files.

Example:

docker-compose.prod.yml

version: '3'
services:
  nginx:
    volumes:
      - asset-volume:/var/lib/assets

docker-compose.dev.yml

version: '3'
services:
  nginx:
    volumes:
      - ./assets:/var/lib/assets
Dan Lowe
  • 51,713
  • 20
  • 123
  • 112
  • can you please also let me know how can i mount that to host as well for development...means how to mount asset-volume with host so both can be synced. – dev.meghraj Apr 22 '17 at 14:03
  • @dev.mraj See updated answer. I added an example of using an external directory instead of a Docker volume. – Dan Lowe Apr 22 '17 at 14:16
  • Can't I use both at same time – dev.meghraj Apr 22 '17 at 14:21
  • Means volume sync with host (for dev env) – dev.meghraj Apr 22 '17 at 14:22
  • @dev.mraj I'm not sure what you mean. Yes you can, but only one thing can be mounted at a specific path at a time. So if you use both they would be at different paths. – Dan Lowe Apr 22 '17 at 14:23
  • @dev.mraj if you use the second approach that's basically what you have. A volume on the external host that is also available in the containers. – Dan Lowe Apr 22 '17 at 16:00
  • first approach looks more better solution and on server i want to use, so on dev server can't i mount asset-volume to my host directory? – dev.meghraj Apr 23 '17 at 06:02
  • 1
    @dev.mraj I updated my answer. Now it shows how to use overlay compose files to adapt your config to multiple environments (like dev and prod). – Dan Lowe Apr 23 '17 at 23:26
  • i have got the problem again.. i've have two containers nginx and asset (grunt build system that build bundle files from grunt) so if use volumes then volumes won'be pushed to docker hub afaik. and i want to push my bundled js files up there so i can pull it and publish wherever i want. – dev.meghraj Apr 24 '17 at 05:28
  • @dev.mraj Then a volume is probably the wrong approach. Build them into the image and push that to the hub. You can still use an overlay volume to modify them on the fly during development. A mounted volume will override the contents built into an image and allow you to work quickly. But for publication they will be built into your images. – Dan Lowe Apr 24 '17 at 13:38
  • I finally got it! Thanks for super explanation – Billizzard Mar 16 '20 at 16:41
  • I used this approach, but the volume needs to be deleted every time a newer image of `asset` service is generated, otherwise it will retain the previous files. Is there any way to avoid manually deleting the volume? – Maxxer Dec 03 '22 at 20:38