Mount a volume in docker-compose conditionally

I have a docker-compose.yml configuration. One of the containers there is a Tomcat server and it has some default .war file deployed in webapps directory.

I want to have the ability to pass (override) the war archive to be deployed by some which resides on the host machine. I think the best would be to have ability somehow switch / override starting docker-compose: as a default, I want to run the webapp (war file) which is inside the container, but I want to have a possibility to mount a directory from my host (for example during development / debugging) if need be.

  • How to setup a docker swarm cluster with AWS ubuntu machine [closed]
  • RHEL7: How to solve “ import read failed(2)”?
  • Docker: setctty operation not permitted
  • Pushing files into private registry in Docker
  • AWS ECS windows containers network mode issue
  • Docker-based Ambari 1.7 cluster install wizard repo URL dead (404) while 'Running setup agent script'
  • Currently, I have the following line in my docker-compose.yml, which is commented out if I need the default.

    volumes:
    # By default, there is the latest version of the application already present in the container
    # If you want to provider the container with your own .war file, uncomment the following line
    # - ./application/webapps:/usr/local/tomcat/webapps
    

    Is there a better way how to achieve that?

  • Can't connect Celery server to RabbitMQ on localhost
  • “I have no name!” as user logging into Jenkins in a docker container that uses Tini
  • How I can running GUI application on Docker for Mac?
  • Referencing services with Docker Compose
  • Restrict memory across all containers
  • docker ps -a not showing my container
  • 3 Solutions collect form web for “Mount a volume in docker-compose conditionally”

    Let’s say that the .war filename is “app.war”… you could overwrite it using a env variable like this:

    volumes:
     - ./application/webapps/${APPLICATION_ENV}.war:/usr/local/tomcat/webapps/app.war
    

    Then when you need to run a different war file just change the APPPLICATION_ENV value to the one you need to run and restart the container.

    I don’t think docker-compose does have “conditional volumes”, but that way you could change the app.war according with your environment.

    Other way would be running a script after the docker-compose up/start to overwrite it, and do it only when needed, like:

    docker-compose exec your-container-name cp /a/volume/path/app.war /usr/local/tomcat/webapps/app.war
    

    What I’m doing is mounting the volume not directly into the tomcat webapps directory, but in an auxiliary folder, let’s call it /tempWarDir/app.war.

    Then, you could use the command in your docker-compose to run something like this:

    command: start.sh

    And inside that start.sh script, check for an environment variable to decide whether to replace the war with the one in /tempWarDir or not. Something like:

       if [ "$EXTERNAL_WAR" = "true" ]
         then
           cp /tempWarDir/app.war /usr/lib/tomcat/webapps/ 
       fi
    

    As a final note, you have to make that env variable to reach the container. There are several ways to do that, from using the environment commnd in your docker-compose file, to using build args and other. I suggest you check the docker documentation for this, and start hardcoding the value for debugging purposes.

    It’s not the cleanest way, but get’s the trick done IMHO.

    Instead of (not) mounting a volume commenting out that line, I would use https://docs.docker.com/compose/extends/#example-use-case to run a service extension that specifies a volume.

    I do this to tackle two different problems:

    • I don’t specify a volume when the docker image is meant to run in production and has all the necessary files bundled in it.
    • I specify a volume during development, to check live changes.
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.