Compose: The data volume causes the container directory to be overwritten.

Created on 7 Mar 2017  路  12Comments  路  Source: docker/compose

version: '3'
services:    
  tomcat7jar8:
        container_name: tomcat7-jar8
        image: tomcat:8.5
        ports:
            - 8080
        volumes:
            - ./tomcat/webapps:/usr/local/tomcat/webapps
            - ./tomcat/logs:/usr/local/tomcat/logs

Adding the first line causes the file in the container to be removed.
Log file synchronization is normal.
Commented out webapps tomcat is normal.
This question is very strange, I do not know how to solve.
Or other ways to solve.

kinquestion

Most helpful comment

I think what @nicodmf is saying, is (correct me if I'm wrong, obv.):

  • ./tomcat/webapps:/usr/local/tomcat/webapps
  • ./tomcat/logs:/usr/local/tomcat/logs

If host './tomcat/webapps' is not empty, it will overwrite container files, and be shared.
If host './tomcat/logs' is empty, the containers files will be copied into the host, and be shared.

It's /meant/ to depend on the host folder being empty. I'm specifically having an issue where the folder is empty, but isn't getting the container files copied to it.

(^ I was conflating 'named volumes' with 'mount binds')

--

I've come full circle and have realised I was expecting behaviour from Docker volumes that didn't exist at the time. This is the behaviour I wanted, which was missing:

  • Volumes
  • Bind mounts

    • Sync code between host filesystem and container filesystem

    • Pass

    • The container codebase is copied into the host codebase (with empty host codebase)

    • Fail



      • Using a bash script inside the container to do the copy for me, would prefer to avoid this though.



    • The host codebase is copied into the container codebase (with populated host codebase)

    • Pass

    • The host location can be specified / host has permission to modify

    • Pass

For now I'm using bind mounts, with a script available inside the container that will then sync the code between host and container - ideally I'd be able to deprecate this bash script!

Now using a named volume, that is accessible via the host.
No idea how I'm going to scale this to 'n' containers with 'n' different shared volumes yet, but at least I've gotten it working for where n=1 xD!

I would be interested to see metrics comparing a bash script to copy from container -> host, vs named volumes, I swear it is slightly slower using named volumes...

All 12 comments

If you mount your local directory into /usr/local/tomcat/webapps in the container, it will replace what was there originally. That's the whole point.

What are you trying to do?

I want to synchronize the items in the container webapps to the host.
As logs, logs in the log file, synchronized over, is normal.

Do not know how to use the data volume.
@shin-

Are you saying the contents of ./tomcat/webapps are not available inside the container?

./tomcat/webapps folder is normal, but inside the file. Not synchronized.
@shin-

/ Usr / local / tomcat / webapps inside the file is not synchronized to ./tomcat/webapps.
Container webapps in the original file, also disappeared, leaving an empty directory.
The webapps in the container can not be synchronized.
But logs can be synchronized.

The log directory in the container
image
The webapps directory in the container
image

Comment out webapps data volumes
volumes:
-# - ./tomcat/webapps:/usr/local/tomcat/webapps
- ./tomcat/logs:/usr/local/tomcat/logs
The file in the container webapps appeared again.
image

This is the normal behavior :) If you mount a local directory on a container directory, the container directory is hidden and replaced by your local.

The logs files will written after the start of a container, in your local directory. If you comment the second line withg your logs, the container write always in the same place for it but neither in your local directory.

I think what @nicodmf is saying, is (correct me if I'm wrong, obv.):

  • ./tomcat/webapps:/usr/local/tomcat/webapps
  • ./tomcat/logs:/usr/local/tomcat/logs

If host './tomcat/webapps' is not empty, it will overwrite container files, and be shared.
If host './tomcat/logs' is empty, the containers files will be copied into the host, and be shared.

It's /meant/ to depend on the host folder being empty. I'm specifically having an issue where the folder is empty, but isn't getting the container files copied to it.

(^ I was conflating 'named volumes' with 'mount binds')

--

I've come full circle and have realised I was expecting behaviour from Docker volumes that didn't exist at the time. This is the behaviour I wanted, which was missing:

  • Volumes
  • Bind mounts

    • Sync code between host filesystem and container filesystem

    • Pass

    • The container codebase is copied into the host codebase (with empty host codebase)

    • Fail



      • Using a bash script inside the container to do the copy for me, would prefer to avoid this though.



    • The host codebase is copied into the container codebase (with populated host codebase)

    • Pass

    • The host location can be specified / host has permission to modify

    • Pass

For now I'm using bind mounts, with a script available inside the container that will then sync the code between host and container - ideally I'd be able to deprecate this bash script!

Now using a named volume, that is accessible via the host.
No idea how I'm going to scale this to 'n' containers with 'n' different shared volumes yet, but at least I've gotten it working for where n=1 xD!

I would be interested to see metrics comparing a bash script to copy from container -> host, vs named volumes, I swear it is slightly slower using named volumes...

@mikeyjk hey is there any solution to this or ticket to follow?. I was uploading some images for my work and I realized that all the readmes and tutorials I was doing were wrong because the spec mentioned in the docs from Docker is not accurate. When the host codebase is empty, the container doesn't copy anything.

@dantebarba There are a /few/ tickets that are kind of related to this, but my issue was more of a comprehension problem understanding the behaviour of bind mounts vs named volumes. What I wanted was a named volume, but I thought I wanted a bind volume.

It is possible the Docker docs have gotten this wrong or worded it strangely, can you link me / copy the relevant docs? Docker is still 'relatively' new, so there are still things to be ironed out. So damn useful though.

Seems like this was some confusion over the behaviour of volume vs binds which mikeyjk has explained. I'm going to close, if there is still confusion please do reopen.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DhairyashilBhosale picture DhairyashilBhosale  路  3Comments

leiblix picture leiblix  路  3Comments

Hendrik-H picture Hendrik-H  路  3Comments

davidbarratt picture davidbarratt  路  3Comments

saulshanabrook picture saulshanabrook  路  3Comments