5.3.7. Deployment with Docker

This section covers deployment of CUBA applications in Docker containers.

We will take Sales Application, migrate it to PostgreSQL database and build UberJAR to run in a container. In fact, an application built as a WAR file would also work with a containerized Tomcat, but it would require a bit more configuration, so for the demo purposes we will stick with UberJAR.

Configure and build UberJAR

Clone the sample project from https://github.com/cuba-platform/sample-sales-cuba7 and open it in CUBA Studio.

First, change your database type to PostgreSQL:

  1. Click CUBA > Main Data Store Settings… in the main menu.

  2. Select PostgreSQL in the Database type field and click OK.

  3. Click CUBA > Generate Database Scripts in the main menu. Studio opens the Database Scripts dialog with generated scripts. Click Save and close in the dialog.

  4. Click CUBA > Create Database in the main menu. Studio creates the sales database on the local PostgreSQL server.

Next, configure a Gradle task for building UberJAR.

  1. Click CUBA > Deployment > Edit UberJAR Settings main menu item.

  2. Select Build Uber JAR and Single Uber JAR checkboxes.

  3. Click Generate button next to the Logback configuration file field.

  4. Click Configure button next to the Custom data store configuration checkbox.

  5. Make sure that URL in the Database Properties group starts with the jdbc:postgresql:// prefix. Enter postgres host name instead of the localhost in the first URL text field. It is necessary for connecting to the containerized database described below.

  6. Click OK. Studio adds the buildUberJar task to the build.gradle file.

  7. Open the generated etc/uber-jar-logback.xml file or another file used as Logback configuration and ensure that the logDir property has the following value:

    <property name="logDir" value="${app.home}/logs"/>

    Also, make sure the Logback configuration file limits the level of the org.eclipse.jetty logger at least to INFO. If there is no such logger in the file, add it:

    <logger name="org.eclipse.jetty" level="INFO"/>

Run the task to create the JAR file by using main menu: CUBADeploymentBuild UberJAR or by running the following command in the terminal:

./gradlew buildUberJar
Create Docker image

Now let’s create Dockerfile and build a docker image with our application.

  1. Create the docker-image folder in the project.

  2. Copy the JAR file from build/distributions/uberJar into this folder.

  3. Create a Dockerfile with the following instructions:

    FROM openjdk:8
    
    COPY . /opt/sales
    
    CMD java -Dapp.home=/opt/sales-home -jar /opt/sales/app.jar

The app.home Java system property defines a directory for the application home where all logs and other files created by the application will be stored. When running the container, we will be able to map this directory to a host computer directory for easy access to logs and other data including files uploaded to FileStorage.

Now build the image:

  1. Open the terminal in the project root folder.

  2. Run the build command passing the image name in the -t option and the directory where Dockerfile is located:

    docker build -t sales docker-image

Check that the sales image is shown when you execute the docker images command.

Run application and database containers

The application is now ready to run in the container, but we also need a containerized PostgreSQL database. In order to manage two containers - one with the application and another with the database, we will use Docker Compose.

Create docker-compose.yml file in the project root with the following content:

version: '2'

services:
  postgres:
    image: postgres:12
    environment:
      - POSTGRES_DB=sales
      - POSTGRES_USER=cuba
      - POSTGRES_PASSWORD=cuba
    ports:
      - "5433:5432"
  web:
    depends_on:
      - postgres
    image: sales
    volumes:
      - /Users/me/sales-home:/opt/sales-home
    ports:
      - "8080:8080"

Pay attention to the following parts of the file:

  • The volumes section maps the container’s /opt/sales-home path which is the application home directory to the host’s /Users/me/sales-home path. It means that the application logs will be available in the /Users/me/sales-home/logs directory of the host computer.

  • The PostgreSQL internal port 5432 is mapped to the host’s port 5433 to avoid possible conflicts with a PostgreSQL instance running on the host computer. Using this port, you can access the database from outside of the container, for example to backup it:

    pg_dump -Fc -h localhost -p 5433 -d sales -U cuba > /Users/me/sales.backup
  • The application container exposes port 8080, so the application UI will be available at http://localhost:8080/app on the host computer.

To start the application and the database, open the terminal in the directory of the docker-compose.yml file and run:

docker-compose up