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.

  • Running SystemTap inside an unprivileged docker container
  • Merge two docker images
  • How to use Docker to make releases?
  • How can I show only the allocated resources in Docker container?
  • Is there a way to install docker without its git dependency in ubuntu?
  • Run old Linux release in a Docker container?
  • 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?

  • Docker - Does the container OS need to be same as Host OS
  • Does capitrano conflict with docker?
  • Kubernetes on CoreOS: Proxy service max out CPU
  • Dockerfile run entrypoint before shell entrypoint
  • change bluemix docker default subnet to a different value?
  • Jenkins setting up
  • 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.