Dockerising Grails applications with an embedded Tomcat

Print Friendly, PDF & Email

The applications built on the Grails framework can be run (often referred to deployment) on either standalone or embedded Tomcat. Grails applications can be deployed in a number of ways, each of which has its pros and cons. In this blog, we have recently published a post to share with you how to deploy a web-based app on a Tomcat Docker container in which Grails based app can be employed this approach without any exception. Therefore, this post will give you another way of running your Grails app on an embedded Tomcat Docker container.

Introduction

As mentioned earlier, Grails based applications can be deployed on an embedded Tomcat like the way of running the applications in development mode. In the production mode, we need to tweak options to tell Grails apps a few configurations from which they are different comparing to the development phase. An embedded Tomcat server is launched that loads the web application from the development sources, thus allowing it to pick up changes to application files. Running a Grails app in this way, you should be very familiar with the grails run-app command.

[box type=”info” ]Notes: Read more about how to deploy applications in Grails 2.5.6 at https://grails.github.io/grails2-doc/2.5.6/guide/deployment.html or in Grails 3.3.11 at https://docs.grails.org/3.3.11/guide/single.html#deployment[/box]

Going with this approach, the Grails framework allows us to specify a mode, i.e. dev or prod, when starting the application.

Deploy Grails apps in an embedded Tomcat Docker
Deploy Grails apps in an embedded Tomcat Docker

How to dockerise Grails app

Start Grails application from the development sources

# Grails 2/3
grails [environment] run-app

whereby the environment can be prod, test, dev. Some options could be found in Grails documentation. I believe --non-interactive is a very important option to be taken into account in Kubernetes deployment. If one of the plugins or dependencies in your Grails app has been upgraded or downgraded, Grails engine will ask us to confirm to install or uninstall this artifact. This option sounds alike unattended installation in automatic update scheduled procedure of Operating System.

You can run the app using the bootRun Gradle task in Grails 3 or above. The next command uses the Gradle Wrapper.

./gradlew bootRun

You can specify an environment supply grails.env system property.

./gradlew -Dgrails.env=prod bootRun

Please read more about the run-app command at Grails2 or Grails3.

Start Grails application from runnable WAR or JAR file

Since Grails 3, we have been supported to generate either war or jar file.

Another way to deploy in Grails 3.0 or above is to use the new support for runnable JAR or WAR files. To create runnable archives, run grails package:

grails package

Alternatively, you could use the assemble Gradle task.

./gradlew assemble

You can then run either the WAR file or the JAR using your Java installation:

java -Dgrails.env=prod -jar build/libs/mywar-0.1.war (or .jar)

Review Dockerfile file

Let’s take a closer insight into the following Dockerfile file to build an image to deploy BioModels on the cloud.

FROM biomodels/jummp-biomodels:1.2-dependencies
LABEL maintainer="biomodels-developers@lists.sf.net"

# install tools and utilities
RUN apt-get update && apt-get install -y mysql-client && rm -rf /var/lib/apt

# set environment options
#ENV MAVEN_OPTS="-Xmx1024m"
ENV JAVA_OPTS="-Xms64m -Xmx1024m -XX:MaxMetaspaceSize=128m"
ENV GRAILS_OPTS="-server -Xmx2g -Xms2g -Dfile.encoding=UTF-8"
#ENV ANT_OPTS="-Xmx2g -XX:MaxPermSize=1024m"
# expected database port
EXPOSE 3306
EXPOSE 4372
EXPOSE 8080

ARG UID
ARG USERNAME
ARG GID
ARG GROUP
RUN echo "$GROUP ($GID) - $USERNAME ($UID)"
ENV HOME=/home/$USERNAME
RUN mkdir -p $HOME
RUN addgroup --gid "$GID" "$USERNAME" \
   && adduser \
   --uid "$UID" \
   --disabled-password \
   --gecos "" \
   --ingroup "$USERNAME" \
   --no-create-home \
   "$USERNAME"

ENV APP_HOME=/home/$USERNAME/biomodels

## SETTING UP THE APP ##
RUN mkdir -p $APP_HOME
RUN chown -R $USERNAME:$USERNAME $HOME

# ***
# Do any custom logic needed prior to adding your code here
# ***

# Copy in the application code.
#ADD . $APP_HOME
# Chown all the files to the app user.
#RUN chown -R "$USERNAME":"$USERNAME" $APP_HOME

# Below is equivalent to the above commands, just speeds up and reduces image size
COPY --chown=$USERNAME:$USERNAME . $APP_HOME

# Change to the app user.
USER $USERNAME
WORKDIR $APP_HOME
RUN ["chmod", "+x", "grailsw"]
ENTRYPOINT ["/bin/bash", "-lc", "./grailsw prod run-app --non-interactive --stacktrace"]

This Dockerfile file includes several concepts but I just explain the segments concerning this post. The rest will be discussed in future posts. The most concerning snippet are extracted below.

# Copy in the application code.
# ADD . $APP_HOME
# Chown all the files to the app user.
# RUN chown -R "$USERNAME":"$USERNAME" $APP_HOME

# Below is equivalent to the above commands, just speeds up and reduces image size
COPY --chown=$USERNAME:$USERNAME . $APP_HOME

# Change to the app user.
USER $USERNAME
WORKDIR $APP_HOME
RUN ["chmod", "+x", "grailsw"]
ENTRYPOINT ["/bin/bash", "-lc", "./grailsw prod run-app --non-interactive --stacktrace"]

Working with Docker, you are probably very familiar with ADD, COPY, WORKDIR or RUN. I don’t waste your valuable time by ignoring their explanation to get clear the key point here. Traditionally, the required environment has Grails framework installed to run a Grails application from source code. From that point, we can use Grails wrapper in place of Grails installation. Therefore, we have to ensure grailsw executable.

Adapter to Grails 3

As revised above, we have to copy WAR or JAR file instead of the development sources. Consequently, ENTRYPOINT instruction should be changed to

ENTRYPOINT ["/bin/bash", "-lc", "java -Dgrails.env=prod -jar myapp-0.1.war"]

Summary

I have represented how to dockerise a Grails app to able to run it in an embedded Tomcat running on a Docker container. All constructive feedback is always welcomed. If you are interested in this post, please consider donating us by following either of the instructions below.

References

  1. Deploy applications in Grails 2.x accessed on 31/05/2020
  2. Deploy applications in Grails 3.x or above accessed on 31/05/2020

Leave a Reply

Your email address will not be published. Required fields are marked *

*

code

This site uses Akismet to reduce spam. Learn how your comment data is processed.