Deployment

Distribution

Fathom does not supply a distribution solution. It does, however, recommend two available solutions.

  • Stork, for more traditional distribution and foolproof Linux/Windows/OSX service integration
  • Capsule, for more modern distribution

Stork

Stork will generate a universal .tar.gz bundle of your application with shell scripts & batch files that will correctly launch your application and optionally install/remove an operating system service for your application.

Layout
YourApp
├── pom.xml
└── src
    └── main
        └── launchers
            └── fathom.yml
Configuration

pom.xml

<build>
  <plugins>
    <plugin>
      <groupId>com.fizzed</groupId>
      <artifactId>fizzed-stork-maven-plugin</artifactId>
      <version>1.2.2</version>
      <executions>
        <execution>
          <id>generate-stork-launchers</id>
          <goals>
            <goal>generate</goal>
          </goals>
        </execution>
        <execution>
          <id>generate-stork-assembly</id>
          <goals>
            <goal>assembly</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

src/main/launchers/fathom.yml

#
# Stork Packaging
# https://github.com/fizzed/java-stork
#
name: "fathom-fit" # $SERVICE
domain: "com.gitblit.fathom"
display_name: "fathom-fit"
short_description: "Fathom Integration Test"
type: DAEMON
main_class: "fathom.Boot"
platforms: [ WINDOWS, LINUX, MAC_OSX ]
min_java_version: "1.8"
min_java_memory: 1024
symlink_java: true
Quick Service Installation (Linux)

These instructions assume you have root permissions.

  1. Unpack the Stork tarball to /opt/$SERVICE where $SERVICE is the name of your service as defined in your launcher definition.
  2. cp /opt/$SERVICE/share/init.d/$SERVICE.init /etc/init.d/$SERVICE
  3. update-rc.d $SERVICE defaults

Note

Your microservice will run as root by default.

Declaring Environment Variables (Linux)

The Stork service scripts will set environment variables defined in /etc/default/$SERVICE

echo "export MYAPP_DATA=/opt/myapp-data" > /etc/default/$SERVICE
Running your Microservice as a different user
  1. Modify /etc/init.d/$SERVICE and specify a different $APP_USER and $APP_GROUP.
  2. Make sure any filesystem data you are accessing can be read or written to by your $APP_USER.

Note

Linux requires root permissions to open ports <= 1024 so you will not be able to serve http directly on 80 nor https directly on 443.

Basic Service Administration (Linux)
service $SERVICE start
service $SERVICE stop
Service Uninstallation (Linux)

These instructions assume you have root permissions.

  1. service $SERVICE stop
  2. update-rc.d -f $SERVICE remove

Capsule

Capsule describes itself as dead-simple packaging and deployment for JVM applications.

Capsule generates either a fat-jar, similar to Maven’s Shade plugin or Gradle’s Shadow plugin, or a thin-jar that automatically downloads dependencies on first execution.

In a typical Fathom application it’s very easy to generate a 25MB+ distribution. This makes The thin-jar build particularly appealing since it is likely to be under a few MB.

Configuration

pom.xml

<build>
  <plugins>
    <plugin>
      <groupId>com.github.chrischristo</groupId>
      <artifactId>capsule-maven-plugin</artifactId>
      <version>1.0.0</version>
      <executions>
        <execution>
          <goals>
            <goal>build</goal>
          </goals>
          <configuration>
            <appClass>fathom.Boot</appClass>
            <chmod>true</chmod>
            <trampoline>true</trampoline>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Using Environment Variables in your Microservice

Environment variables may be used by your microservice in your default.conf configuration file to make it easier to keep your data separate from your installation.

In this example we are defining a home directory of data/ which is located within the working directory (user.dir) of your microservice. We are also conditionally redefining that location to the value specified in the MYAPP_DATA environment variable, if that environment variable exists.

myapp.data = "data/"
myapp.data = ${?MYAPP_DATA}

Reverse Proxies & SSL Termination

Nginx

Nginx is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server.

We’re going to use it as a reverse proxy for our Fathom app and let it handle SSL and http-to-https redirects.

The information presented here is a streamlined version of Digital Ocean’s tutorial. You may also find Linode’s Nginx tutorial valuable for understanding nginx’s other practical features.

Install nginx
sudo apt-get install nginx
Create a self-signed SSL certificate
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/cert.key -out /etc/nginx/cert.crt
Modify the default nginx configuraiton
sudo nano /etc/nginx/sites-enabled/default
# Define an http listener which redirects to https
server {
    listen 80;
    return 301 https://$host$request_uri;
}

# Define an https listener
server {

    listen 443;
    server_name app.domain.com;

    ssl_certificate           /etc/nginx/cert.crt;
    ssl_certificate_key       /etc/nginx/cert.key;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    access_log            /var/log/nginx/app.access.log;

    location / {

      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;

      # Fix the “It appears that your reverse proxy set up is broken" error.
      proxy_pass          http://localhost:8080;
      proxy_read_timeout  90;

      proxy_redirect      http://localhost:8080 https://app.domain.com;
    }
  }
Configure Your Fathom Application

For Fathom to work with Nginx, we need to instruct your Fathom application to listen only on the localhost interface instead of all (0.0.0.0), to ensure traffic gets handled properly. This is an important step because if Fathom is still listening on all interfaces, then it will still potentially be accessible via its default port (8080).

Stork
echo "export APP_ARGS='--mode PROD --httpPort 8080 --httpListenAddress localhost --applicationUrl https://app.domain.com'" >> /etc/default/$SERVICE

Restart Your Fathom Application
sudo service $SERVICE restart
Restart nginx
sudo service nginx restart