Docker named volume not updating [closed]
Asked Answered
F

3

24

I am confused on how the named data-volume (not data container) should be used.

I have a named data volume app_src that is mounted to /usr/src/app using docker compose file. However, after making changes to my source code (locally), building the image doesn't update the volume.

I am building the image like so,

docker-compose -f development.yml build and running it docker-compose -f development.yml up -d.

To confirm that the volume doesn't change, I attached into the running container and true enough, the source code isn't updated.

Here is my docker compose file development.yml and Dockerfile for my web service. version: '2'

services:
  web:
    restart: always
    build: ./web
    expose:
      - "8000"
    volumes:
      - app_src:/usr/src/app
    links:
      - postgres:postgres
    env_file: development.env
    command: ./start_web.sh

volumes:
   app_src: {}


FROM python:3.4.4

WORKDIR /usr/src/app
RUN rm -rf /usr/src/app/*
COPY . /usr/src/app/
RUN pip install --no-cache-dir -r requirements.txt

I could make it work by mounting the host like so,

volumes:
    - ./web/src:/usr/src/app

I'm on Ubuntu 16.04 running docker 1.11.2. Is my understanding wrong? I did take a look at the documentation but I could find anything that explained the volume really well.

Fastness answered 18/7, 2016 at 15:54 Comment(0)
K
18

It looks like you're trying to use docker-compose with a named volume mount and a Dockerfile to modify the contents of that location. This won't work because the Dockerfile is creating an image. The docker-compose is defining the running container that runs on top of that image. You won't be able to modify the volume within the image creation since that volume is only mounted after the image is created an you run the container.

If you want to update your named volume, consider a side container:

docker run -v app_src:/target -v `pwd`/web/src:/source --rm \
  busybox /bin/sh -c "tar -cC /source . | tar -xC /target"

You can run that container on demand to update your named volume. You can also replace the tar with something like a git clone to pull from a source repository, or even an rsync (which you'd need installed on your image) if you are making small changes to a large repository.

You can also workaround this by emptying your named volume (either rm -rf /vol/dir or removing the volume and creating a new one) and then restarting the container. On the startup of the container, if an empty named volume is included, the default is to copy the image contents at that location into the volume.

Kinsey answered 18/7, 2016 at 19:43 Comment(4)
Ok, that makes sense. I was a little confused on how it gets build with compose. Is there a way to empty the named volume from docker-compose when bringing the service up? docker-compose up -> I want to clear the vol dir and copy the latest file from host?Fastness
It wouldn't work to delete the directory on the start of the container since that would happen after Docker does it's check for an empty folder. If you're looking to always have this initialized with the contents of the container, and don't mind deleting the previous volume, I have to ask if you really need it as a volume at all?Kinsey
you're right. My solution now is to remove the volume all together, and mount from host file during development. I have the volume at the first place because I thought of sharing the code to multiple containers, but now it doesn't really make sense doing that.Fastness
Thanks for that clear explanationUnit
A
4

A workaround is to recreate the volume, of course, if you can afford longer downtime period:

docker-compose down && docker volume rm <VOLUME_NAME> && docker-compose up -d
Adulthood answered 24/9, 2020 at 9:14 Comment(1)
docker compose down -v && docker-compose up -d does the same, but it's shorterBroth
S
1

you mount the volume many times into the same place. First time container stores data into Host file system, second time it override data INTO container FROM your host file system. remove volume mount from you docker-compose file

volumes: - ./web/src:/usr/src/app #remove this!

you can get additional info here

$ docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

This command mounts the host directory, /src/webapp, into the container at /opt/webapp. If the path /opt/webapp already exists inside the container’s image, the /src/webapp mount overlays but does not remove the pre-existing content. Once the mount is removed, the content is accessible again. This is consistent with the expected behavior of the mount command.

Syringe answered 18/7, 2016 at 18:10 Comment(1)
I didn't mount the volume many times. I can make it to work by mounting the host file system into the volume. I think I understand what's happening, on build, content from host is copied to the image. But then, I am mounting the volume which has existing data, so that will shadow the file that has been copied to the image. It works like normal mount. I think what confused me was that I thought the mount is done before image is build, which is wrong.Fastness

© 2022 - 2024 — McMap. All rights reserved.