CloudCaptain supports Play 2.3.x and newer apps packaged as a Play dist zip using OpenJDK 7, 8, 11, 17 or 21.
If you haven’t already, start by following Play & CloudCaptain tutorial that will get you up and running in 5-10 minutes.
By default CloudCaptain uses the latest OpenJDK 17 version (headless JRE).
If you want to switch to OpenJDK 7.x or simply an older version, you can do so using the -components.openjdk
configuration setting:
> boxfuse run my-app-1.0.jar -components.openjdk=7.80.32
To find out which OpenJDK versions are available from the CloudCaptain Inventory you can simply issue:
> boxfuse inventory openjdk
If you prefer to use a different JRE, such as the Oracle JRE, rather than the default OpenJDK one,
you can do so by including the Linux x64 JRE distribution of your choice in a /jre
folder inside the Play dist zip file.
This /jre
folder should be put into the conf
directory of your project:
my-play-app
conf
jre
bin
java
...
lib
amd64
...
rt.jar
...
COPYRIGHT
LICENSE
...
Tip for Git users
To avoid file corruption due to Git line-ending normalization, add the following line to `.gitattributes`
conf/jre/* binary
By default CloudCaptain looks for an application.conf
file inside the Play dist zip file.
You can find this file in the /conf
directory of your project:
my-play-app
conf
application.conf
CloudCaptain parses application.conf
and automatically configures the http & https ports, the payload path and the healthcheck path based on the
following config parameters: play.server.http.port
, play.server.https.port
and play.http.context
.
When both play.server.http.port
and play.server.https.port
are set, the https port takes precedence for the healthcheck.
You can override this by explicitly passing the CloudCaptain parameter -healthcheck.port=http
when fusing the image.
As CloudCaptain runs your application in production mode you must set your application secret either in application.conf
or pass it from the command-line. For example:
Play Version | Play Setting |
---|---|
2.6 | play.http.secret.key="QCY?tAnfk?aZ?iwrNwnxIlR6CTf:G3gf:90Latabg@5241ABR5W:1uDFN];Ik@n" |
2.5 | play.crypto.secret="QCY?tAnfk?aZ?iwrNwnxIlR6CTf:G3gf:90Latabg@5241ABR5W:1uDFN];Ik@n" |
2.4 | play.crypto.secret="QCY?tAnfk?aZ?iwrNwnxIlR6CTf:G3gf:90Latabg@5241ABR5W:1uDFN];Ik@n" |
2.3 | application.secret="QCY?tAnfk?aZ?iwrNwnxIlR6CTf:G3gf:90Latabg@5241ABR5W:1uDFN];Ik@n" |
More info in the official Play documentation.
If your application uses the allowed hosts filter you must ensure play.filters.hosts.allowed
in
application.conf
allows connections from anywhere as this filter otherwise causes ELB healthchecks to fail. For example:
play.filters.hosts { allowed = ["."] }
More info in the official Play documentation.
By default, Play loads the application.conf
file in the conf
directory of your app.
You can however tell play to use alternative config files by passing in a JVM system property. So for:
my-play-app
conf
application.conf
other.conf
You could then launch your CloudCaptain instance with -jvm.args=-Dconfig.file=other.conf
to load the
alternate Play config file called other.conf
in the conf directory of your application.
Note: these files must be present at the time you build the dist zip using sbt dist
.
Also keep in mind that CloudCaptain auto-configuration only works with the regular application.conf
file.
As an alternative to overriding the entire configure you can also selectively override individual configuration properties on instance launch.
The first option is to use JVM system properties. For example: -jvm.args=-Dplay.http.secret.key=abcdefghijk
More info in the official Play documentation.
Play also gives you the opportunity to override configuration properties using environment variables. Say if you have
defined my.key = ${?MY_KEY_ENV}
in your Play configuration file, you can now override it on instance launch
using -envvars.MY_KEY_ENV=myvalue
.
More info in the official Play documentation.
If your app includes the PostgreSQL or MySQL JDBC driver, CloudCaptain will automatically activate
database auto-provisioning support and provision the necessary PostgreSQL or MySQL database
in each environment as well as auto-configure Play’s DataSource. Alternatively you can also explicitly configure database auto-provisioning by passing in
the correct db.type
value when creating your CloudCaptain app.
When using database auto-provisioning, CloudCaptain automatically configures Play’s DataSource
to use the correct driver class name, jdbc url, user and password. It does so by automatically supplying the
db.default.driver
, db.default.url
, db.default.username
and db.default.password
with the
correct value for the current environment to the JVM.
For Play 2.4 and newer apps that include the PostgreSQL or MySQL JDBC driver and use Slick instead of the regular Play database access, CloudCaptain also automatically configures
Slick’s driver, the jdbc driver class name, jdbc url, user and password. This can be disabled by setting
db.type
to none
when creating your CloudCaptain app.
You can also override these auto-configured values by explicitly passing them as JVM arguments. For example, to override the Slick driver you can do so like this:
> boxfuse fuse my-play-app-1.0.zip -jvm.args=-Dslick.dbs.default.driver=my.custom.SlickDriver
To disable database auto-provisioning and use an existing database set db.type
to none
when creating your CloudCaptain app.
If you choose to use Play Evolutions to migrate your database schema (as opposed to Flyway) you have to ensure evolutions are applied automatically to prevent application startup issues.
For Play 2.3.x, set applyEvolutions.
database=true
in your Play config (reference docs).
For Play 2.4.x and newer, set play.evolutions.autoApply=true
in your Play config (reference docs).
To expose your app via HTTPS make sure you have a custom domain configured
for the environment where you want to run it. Also make sure that you have obtained
a valid TLS (SSL) certificate and that your app has been created
with app.type
set to load-balanced
and tls.type
set to acm
(AWS Certificate Manager).
With that in place your Play app will be automatically configured to run with HTTPS and a green lock will appear in the browser.
You can also manually force the correct configuration by adding these properties to your Play config file:
play.server.https.port=443
CloudCaptain will automatically ensure that all network traffic between the load balancer and your instances will be encrypted as well.
To use HTTPS with your own certificate, you first have to obtain a valid certificate from a Certificate Authority and
add a KeyStore containing your SSL certificate inside the zip file at /conf/boxfuse.jks
.
If you use SBT or Typesafe Activator, this means your boxfuse.jks
keystore file should be put into the conf
directory.
Both the keystore itself as well as the certificate should be secured with the password boxfuse
.
my-play-app
conf
boxfuse.jks
f present, CloudCaptain automatically configures your Play application to use it. All you need to do is set the https
port to the one you want. This can be done either in your CloudCaptain or in your Play config. Example:
> boxfuse run -ports.https=443
To use an alternative keystore called say mykeystore.jks
, simply place it in the conf
directory and refer to it using a relative path like conf/mykeystore.jks
.
You can then also specify its password as usual in your application.conf
file.
By default, CloudCaptain uses the same root certificate bundle as the latest version of Firefox. Additionally CloudCaptain also includes the root certificates for Amazon RDS, so you can connect securely to RDS databases out of the box.
You can, however, ship your own set of root certificates, by placing them in a KeyStore inside the Zip file as /conf/cacerts
.
If you use SBT or Typesafe Activator, this means your cacerts
KeyStore file should be put into the conf
directory.
CloudCaptain will then automatically configure the JRE to use these instead.
my-play-app
conf
cacerts
If you choose to secure your cacerts
TrustStore with a password different than the default changeit
,
you have to add the following to your Play configuration:
play.ws.ssl { trustManager = { stores = [ { path: /cacerts/cacerts, password = "my0th3rPwd" } ] } }
This is already enabled by default (starting with OpenJDK 8.162.12) and no further action is required.
To enable JCE unlimited cryptography (for AES-256, RSA-4096, …), download the policy zip from the Oracle website for either Java 7 or Java 8.
Extract both local_policy.jar
and US_export_policy.jar
and place them inside the Zip file under /conf
.
If you use SBT, this means both policy jar files should be put into the conf
directory.
CloudCaptain will then automatically configure the JRE to use these instead.
my-play-app
conf
local_policy.jar
US_export_policy.jar
If you use a custom JRE it is your responsibility to ensure it is configured for unlimited strength cryptography if you need it.
If you wish to launch the JRE with one or more Java Agents, simply place the Java Agent files inside the Zip file under
/conf/javaagents/
. In a SBT or Typesafe Activator project this means you have to put your agent jar and whatever other files it requires under conf/javaagents
:
my-play-app
conf
javaagents
myjavaagent.jar
myjavaagent.properties
CloudCaptain will then automatically configure the JRE to use these Java Agents.
By default CloudCaptain will dynamically configure your JVM heap to use 85% of the available memory in the instance. All other settings
use the JVM defaults. You can override this by specifying the required JVM arguments like -Xmx
via the
jvm.args
configuration setting.
CloudCaptain configures the JVM to use /tmp
as the directory to store temporary files and provisions 1 GB of space by default.
To increase this (up to a maximum of 16 TB), simply set
the tmp
configuration setting to the number of GB of temp space you need. To prevent CloudCaptain from
provisioning any temp space set tmp
to 0
.
Remote debugging (including hot-code replace) with your favorite IDE is fully supported. Details and setup instructions on our debugging page.
Profiling with tools like JVisualVM and Java Flight Recorder is fully supported. Details and setup instructions on our profiling page.
CloudCaptain supports Live Reloading of exploded Play zip files.
By default all CloudCaptain instance use the UTC
time zone.
We don’t recommend changing this as this greatly simplifies time zone issues in machine to machine communication and cleanly relegates all time zones related aspects to a pure presentation layer concern.
If however you still do want to change this, you can override the default time zone of the instance using the
TZ
environment variable. For example to change the time zone of your instance to America/Los_Angeles
you would do so like this:
> boxfuse fuse -envvars.TZ=America/Los_Angeles
Some JVM applications also depend on native Linux x64 binaries and libs to do their work. CloudCaptain makes it easy to integrate them into your image.
Simply place your binaries under conf/native/bin
and CloudCaptain
will automatically add them to the PATH
at runtime in your instances.
If those binaries also depend on additional shared libraries beyond the C library, place the .so files of your libraries
under conf/native/lib
on the classpath and CloudCaptain
will automatically add them to the LD_LIBRARY_PATH
at runtime in your instances.
Tip
To list all the shared libraries your Linux x64 binary requires, you can use the following command on a Linux system:
$ ldd -v my-native-binary
In a SBT or Typesafe Activator project, the native
directory should be put under the conf
directory. CloudCaptain will then automatically configure the PATH
and LD_LIBRARY_PATH
to use it.
my-play-app
conf
native
bin
my-native-binary
other-linux-x64-binary
lib
my-shared-lib.so
other-shared-lib.so
You can then simply invoke them in your code using
Runtime.getRuntime().exec("my-native-binary arg1 arg2 arg3");
To monitor your app using New Relic simply pass in your New Relic license key when fusing your image and CloudCaptain will automatically install and configure the New Relic Servers Linux x64 and New Relic Java agents for you.
> boxfuse fuse -newrelic.licensekey=0123456789abcdef0123456789abcdef01234567
Alternatively you can also supply a newrelic.yml
configuration file for the Java agent and CloudCaptain will
automatically use that instead. CloudCaptain will then install the agent for you, but won’t override any application name you may have configured.
If you haven’t configured a New Relic license key as described above, CloudCaptain will use
the license key contained in your newrelic.yml
configuration file instead.
In a SBT or Typesafe Activator project, the newrelic.yml
file should be put into the conf
directory.
CloudCaptain will then automatically configure the New Relic Java agent to use it.
my-play-app
conf
newrelic.yml
To ensure New Relic is able to show stack traces for errors, you must include the New Relic API and extend Play’s default error handler so that each error gets properly reported:
import javax.inject._ import play.api.http.DefaultHttpErrorHandler import play.api._ import play.api.mvc._ import play.api.mvc.Results._ import play.api.routing.Router import scala.concurrent._ import com.newrelic.api.agent.NewRelic @Singleton class ErrorHandler @Inject() ( env: Environment, config: Configuration, sourceMapper: OptionalSourceMapper, router: Provider[Router] ) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) { override def onProdServerError(request: RequestHeader, exception: UsefulException) = { NewRelic.noticeError(exception) super.onProdServerError(request, exception) } }
To tune the arguments passed Linux kernel from the bootloader, simply pass them using the
-linux.args
setting when fusing your image.
If you need to tune the Linux kernel running in your instance, simply place a sysctl.conf
file inside the Zip file under
/conf
. In a SBT or Typesafe Activator project this means you have to put it under /conf
:
my-play-app
conf
sysctl.conf
You can then for example tune the maximum number of file descriptors by simply including the following in sysctl.conf
:
fs.file-max = 131072
CloudCaptain will then automatically configure the Linux kernel to use these settings.