Search code examples
dockertomcatdocker-composetomcat8

tomcat docker mounted volume becomes empty


I have a docker-compose.yml which looks like this:

version: '3'

services:
  tomcat:
    container_name: tomcat8
    restart: always
    image: tomcat:8-jdk8
    ports:
    - 80:8080
    volumes:
    - /var/docker/myservice/tomcat/data/webapps:/usr/local/tomcat/webapps:Z

I want to mount the tomcat/webapps folder inside the container to the host so that I don't have to enter the docker container to modify the applications.

However, when this container starts up, the /usr/local/tomcat/webapps folder becomes empty. The ROOT/, docs/, examples/, host-manager/, manager/ folders that should have been created when tomcat starts up are all gone.

I originally thought this is because that the container does not have permission to write to the volume on the host machine. But I've followed this post's instruction to add an Z at the end of the volume.

What's wrong with my configuration? Why does /usr/local/tomcat/webapps folder inside the container become empty?

Is there any way to let the data in /usr/local/tomcat/webapps in the container to overwrite the data in /var/docker/myservice/tomcat/data/webapps in the host machine?


Solution

  • For tomcat:8-jdk8, we could see next:

    $ docker inspect tomcat:8-jdk8 | grep Entrypoint
            "Entrypoint": null,
            "Entrypoint": null,
    

    Also, see tomcat:8-jdk8 Dockerfile:

    CMD ["catalina.sh", "run"]
    

    To sum all, the only start script for a container is catalina.sh, so if we override it like next:

    $ docker run -it --rm tomcat:8-jdk8 ls /usr/local/tomcat/webapps
    ROOT  docs  examples  host-manager  manager
    

    We can see even we did not start any start script like catalina.sh, we still can see ROOT, docks, etc in /usr/local/tomcat/webapps.

    This means, above folders just in the image tomcat:8-jdk8 not dynamically generated by catalina.sh. So, when you use - /var/docker/myservice/tomcat/data/webapps:/usr/local/tomcat/webapps as a bind mount volume, the empty folder on host will just override all things in the container folder /usr/local/tomcat/webapps, so you will see empty folder in container.

    UPDATE:

    Is there any way to let the data in /usr/local/tomcat/webapps in the container to overwrite the data in /var/docker/myservice/tomcat/data/webapps in the host machine?

    The nearest solution is to use named volume:

    docker-compose.yaml:

    version: '3'
    
    services:
      tomcat:
        container_name: tomcat8
        restart: always
        image: tomcat:8-jdk8
        ports:
        - 80:8080
        volumes:
        - my-data:/usr/local/tomcat/webapps:Z
    
    volumes:
      my-data:
    

    Then see next command list: (NOTE: 99_my-data, here 99 is the folder where you store your docker-compose.yaml)

    shubuntu1@shubuntu1:~/99$ docker-compose up -d
    Creating tomcat8 ... done
    shubuntu1@shubuntu1:~/99$ docker volume inspect 99_my-data
    [
        {
            "CreatedAt": "2019-07-15T15:09:32+08:00",
            "Driver": "local",
            "Labels": {
                "com.docker.compose.project": "99",
                "com.docker.compose.version": "1.24.0",
                "com.docker.compose.volume": "my-data"
            },
            "Mountpoint": "/var/lib/docker/volumes/99_my-data/_data",
            "Name": "99_my-data",
            "Options": null,
            "Scope": "local"
        }
    ]
    shubuntu1@shubuntu1:~/99$ sudo -s -H
    root@shubuntu1:/home/shubuntu1/99# cd /var/lib/docker/volumes/99_my-data/_data
    root@shubuntu1:/var/lib/docker/volumes/99_my-data/_data# ls -alh
    total 28K
    drwxr-xr-x  7 root root 4.0K 7月  15 15:09 .
    drwxr-xr-x  3 root root 4.0K 7月  15 15:09 ..
    drwxr-xr-x 14 root root 4.0K 7月  15 15:09 docs
    drwxr-xr-x  6 root root 4.0K 7月  15 15:09 examples
    drwxr-xr-x  5 root root 4.0K 7月  15 15:09 host-manager
    drwxr-xr-x  5 root root 4.0K 7月  15 15:09 manager
    drwxr-xr-x  3 root root 4.0K 7月  15 15:09 ROOT
    

    This is the nearest way can pop contents to host.

    Another solution: mount /var/docker/myservice/tomcat/data/webapps to the container folder but not /usr/local/tomcat/webapps, e.g. /tmp/abc, then customize your CMD to copy the things in /usr/local/tomcat/webapps to /tmp/abc, then in your host's /var/docker/myservice/tomcat/data/webapps could also see them...