Docker Community Forums

Share and learn in the Docker community.

Continuous Delivery (CD) using Tomcat and webapp image


(Malvarez) #1

While trying to Dockerize a webapp I’m working on, I have found some errors of concept that I’m unable to solve.
The software I try to build with Docker is a web service running on a Apache Tomcat and a PostgreSQL database to store its relational data.
The web service is composed of a webapp folder which contains all static files that are served by Tomcat (they are immutable and placed inside Tomcat webapp folder). The web service has also associated a dynamic data folder that will change its content as user interacts with the application (user stored/uploaded data).
So I have created four services inside a docker-compose.yml file:

  1. PostgreSQL data volumes container (to store PostgreSQL data)
  2. PostgreSQL container (runs database service)
  3. The webapp service with two volumes
  4. Apache Tomcat container (linked to database, runs the web services)

This is the resulting docker-compose.yml file:

version: '2'

services:
  data:
    image: "alpine:latest"
    read_only: true
    volumes:
      - $PWD/postgresql/data:/var/lib/postgresql/data
      - $PWD/postgresql/sql:/docker-entrypoint-initdb.d
    command: echo "PostgreSQL Data volumes container"
  database:
    image: "postgres:latest"
    read_only: true
    environment:
      POSTGRES_PASSWORD: foouser
      POSTGRES_USER: foopwd
    expose:
       - 5432
    volumes_from:
      - data
    tmpfs:
      - /run/postgresql
      - /tmp
      - /var/log/postgresql

  browsewebapp:
    image: "fooapp/browse:1.1.0"
    command: echo "Browse web module and data"

  tomcat:
    image: "tomcat:7.0.70-jre8"
    links:
      - database:db
    volumes_from:
      - browsewebapp
    ports:
      - "8888:8080"

With this configuration I have a web server with database connection running on host port 8888.

The fooapp/browse image is build from an alpine image where there are two volumes defined as:
-v /usr/local/tomcat/webapps/browse <- Immutable web files
-v /usr/local/fooapp/browse <- Dynamic, user generated files, accessed by the web files code
Then I enter a console inside this running container and checkout my files inside both folders/volumes, exit console and commit the container into the fooapp/browse image.
Everything defined previously is working ‘fine’ and my intention is to distribute the previously mentioned docker-compose.yml to deploy the application on multiple servers.
My concerns are about maintaining the browsewebapp service in order to release new versions of the application as I code more functionalities. I would like to follow a release workflow like Continuous Delivery approach does: Code -> Version Control -> Unit Testing -> Package Image -> Deploy. So the web service should be upgraded with every new version of the image.
Using volumes on fooapp/browse image works fine on the second volume because it is created once and then it is later modified by the user interaction (not Docker). But the first volume (the one with the code) needs to be updated on every new version, but it won’t because newer image versions ignore file changes on volumes (as Docker documentation states).
So the question is, how can I build an image to be used inside a tomcat webserver that can update its contents with new files but without using volumes as they don’t reflect new image file changes? May I use sshfs / nfs to mount such folders inside tomcat container?
Thank you all in advance.