Table of contents
1.
Introduction🤔
2.
Production Configuration👷🏽‍♂️
3.
General Configuration📋
3.1.
Other Ways for General Configuration🗂️
3.2.
Specifying an Alternate Configuration File💻
3.2.1.
Using -Dconfig.resource👨🏻‍💻
3.2.2.
Using -Dconfig.file👨🏻‍💻
3.3.
Overriding Configuration with System Properties🎯
3.3.1.
Using System Attributes to Provide the HTTP Server Address and Port👨🏻‍💻
3.3.2.
Using Environment Variables to Provide the HTTP Server Address and Port👨🏻‍💻
3.3.3.
Changing the Path of RUNNING_PID💻
3.4.
Using Environment Variables👨🏻‍💻
3.5.
Server Configuration Options💻
4.
Logging Configuration
4.1.
Including a Custom Logback Configuration File💻
4.2.
Using -Dlogger.resource👨🏻‍💻
4.3.
Using -Dlogger.file💻
4.4.
Using -Dlogger.url👨🏻‍💻
5.
JVM Configuration
6.
Frequently Asked Questions
6.1.
Define the play framework.
6.2.
In which format are most of the play’s configurations defined?
6.3.
Describe the akka cluster.
6.4.
Play uses which code in level messages?
6.5.
What is a JVM application?
7.
Conclusion
Last Updated: Mar 27, 2024
Medium

Production Configuration

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction🤔

Play's architecture is stateless, lightweight, and web-friendly. Play is based on Akka and consumes very few resources. It is a developer-friendly and flexible framework. The majority of java libraries are also supported by play.

play coding ninjas

This article will discuss different configurations that may be configured in production.

Production Configuration👷🏽‍♂️

In production, you can specify a variety of various sorts of configurations. The three major kinds are as follows:

  • General configuration
  • Logging configuration
  • JVM configuration

Each of the kinds above can be configured differently.

General Configuration📋

production configuration play

The play features a lot of options that may be changed. Database connection URLs, application secrets, the HTTP port, SSL settings, and other options are available.

The majority of play's configuration is defined in .conf files that employ the HOCON format. The application.conf file will be your primary configuration file. This file may be found in your project at conf/application.conf. At runtime, the application.conf file is loaded from the classpath (or you can override where it is loaded from). Each project may only have one application.conf.

Other .conf files are also loaded. The default parameters for libraries are defined in reference.conf files. These files are kept in the JARs of the libraries (one reference.conf per JAR) and aggregated during runtime. The reference.conf files offer defaults; any parameters supplied in the application.conf file overrides these.

Other Ways for General Configuration🗂️

System attributes and environment variables can also determine play settings. This is useful when settings vary between situations; you may use application.conf for standard settings but alter settings when running the application in other circumstances by using system properties and environment variables.

System properties override app.conf settings during the app.conf overrides the default settings in the multiple reference.conf files.

There are numerous techniques to override runtime settings. This is useful when the configuration varies between environments; you may change the setup dynamically for each domain. Here are your runtime configuration options:

  • Using a different application .config file
  • Using system properties to override specific settings.
  • Using environment variables to inject configuration settings.

Specifying an Alternate Configuration File💻

By default, the application.conf file is loaded from the classpath. If necessary, you can supply an alternate configuration file in the following ways:

Using -Dconfig.resource👨🏻‍💻

This will look for an alternate configuration file in the application classpath (you should generally put them in your application conf/ directory before packaging). Play will look into conf/, so you won't have to.

$ /path/to/bin/<project-name> -Dconfig.resource=prod.conf

Using -Dconfig.file👨🏻‍💻

You may also supply a local configuration file that is not included in the application artefacts:

$ /path/to/bin/<project-name> -Dconfig.file=/opt/conf/prod.conf


Note: You can always use the include directive to include the original configuration file in a new prod.conf file, for example:

include "application.conf"
key.to.override=blah

Overriding Configuration with System Properties🎯

Sometimes you don't want to override a whole configuration file but only a few particular keys. You may accomplish this by defining them as java system properties:

$ /path/to/bin/<project-name> -Dplay.http.secret.key=ad31779d4ee49d5ad5162bf1429c32e2e9933f3b -Ddb.default.password=toto

Using System Attributes to Provide the HTTP Server Address and Port👨🏻‍💻

Using system attributes, you can specify both the HTTP port and address. The default setting is to listen on port 9000 at 0.0.0.0. (all addresses).

$ /path/to/bin/<project-name> -Dhttp.port=1234 -Dhttp.address=127.0.0.1

Using Environment Variables to Provide the HTTP Server Address and Port👨🏻‍💻

You may simply specify both the HTTP port and address using environment variables, for example, when using Bash under Linux:

export PLAY_HTTP_PORT=1234
export PLAY_HTTPS_PORT=1235
export PLAY_HTTP_ADDRESS=127.0.0.1


The above variables are selected last, which means any previously declared port or address in the application.conf or through system properties will override these environment variables.

Changing the Path of RUNNING_PID💻

It is possible to alter the file's path containing the process id of the currently running application. This file is usually placed in the root directory of your play project, but it is recommended that you store it elsewhere where it will be cleared automatically on the restart, such as /var/run:

$ /path/to/bin/<project-name> -Dpidfile.path=/var/run/play.pid


Note: Check that the directory exists and that the user running the play application has to write access to it.

You may use this file to terminate your application by using the kill command, for example:

$ kill $(cat /var/run/play.pid)


To prevent play from establishing its own PID, change the path in your application.conf file to /dev/null:

pidfile.path = "/dev/null"

Using Environment Variables👨🏻‍💻

You may also use environment variables in your application.conf file:

my.key = defaultvalue
my.key = ${?MY_KEY_ENV}

 

In this case, the override field my.key = $? If there is no value for MY_KEY_ENV, it just disappears, but if you create an environment variable MY_KEY_ENV, it will be utilised.

Server Configuration Options💻

The default HTTP server implementation in play is Akka HTTP, which gives many options for tuning and configuring the server, such as the size of parser buffers, whether keep alive is utilised, and so on.

A complete list of server setup options, including defaults, is available here:

# Copyright (C) Lightbend Inc. 

# Configuration for Play's AkkaHttpServer
play {

  server {
    # The server provider class name
    provider = "play.core.server.AkkaHttpServerProvider"

    akka {
      @* How much time to wait when binding to the listening socket *@

      bindTimeout = 5 seconds

      @* How long does a request takes until it times out? Set to null or "infinite" to 
      disable the timeout. *@

      requestTimeout = infinite

      @* Timeout after which every request and connection shall be forcefully terminated
       when shutting down the server.
       It will default to Coordinated Shutdown service-unbind
       phase timeout. The value must be a duration, for example:
       play.server.akka.terminationTimeout = 10 seconds *@

      terminationTimeout = null

      @* Enables/disables automatic handling of HEAD requests.
      When this option is enabled, the server sends HEAD requests to the #application   
      as GET requests, and automatically 
      removes all message bodies from outgoing replies.
      Even if this option is disabled, the server will never transmit 
      message bodies in response to HEAD requests.*@

      transparent-head-requests = off

      @* If you leave this parameter blank, the server will only accept requests with a non-empty 'Host' header. 
      Otherwise, it returns a '400 Bad Request' response.
      To force the server to accept such requests, set a non-empty value #instead of #a missing or empty 'Host.' header.
      It should be noted that the server will never accept HTTP/1.1
      requests without a 'Host.' header. Therefore
      this option only applies to HTTP/1.1 requests with an empty #host header. *@

      default-host-header = ""

      @* If no explicit 'Server'-header was supplied in a response, 
      this is the default value of the 'Server' header to output.
      No 'Server' header will be presented 
      if this value is null or zero and no header was supplied in the request. *@

      server-header = null
      server-header = ${?play.server.server-header}

      @* Sets the processing mode when unlawful characters 
      are encountered in the response's header value.
       Supported mode:
       `error`: default mode, throw a ParsingException and terminate the processing
       `warn`: ignore the illegal characters in the response header value and log a 3warning message
       `ignore`: just ignore the illegal characters in a response header value *@

      illegal-response-header-value-processing-mode = warn

      @* Enables/disables the inclusion of a Tls-Session-Info header in parsed
       messages upon Tls transports (i.e., HttpRequest on the server side and
       HttpResponse on client side). *@

      tls-session-info-header = on

    }
  }
}


You may also use netty as an HTTP server, with its options. The following is a complete list of netty server configuration options, including the defaults:

# Copyright (C) Lightbend Inc. 

play.server {

  # The server provider class name
  provider = "play.core.server.NettyServerProvider"

  netty {

    @* If no explicit 'Server'-header was supplied in a response, this is the default value of the 'Server' header to output.
     No 'Server' header will be presented if this value is null and no header was supplied in the request. *@
    
    server-header = null
    server-header = ${?play.server.server-header}

    @* The number of threads in the event loop. 0 indicates let Netty decide, 
    which will choose double the number of available processors by default. *@
    
    eventLoopThreads = 0

    @* The beginning line's maximum length. The opening line consists of the 
    method (3-7 characters), the URL, and the HTTP version (8 characters),    
    including usual whitespace, and the maximum URL length is this number - 18. *@
   
     maxInitialLineLength = 4096

     @* The maximum number of body bytes Netty will read into memory at once.
     This is used in a variety of contexts. This setting does not affect HTTP chunked  
     transfer encoding; Netty will read "chunks," or byte buffers worth of content, and 
     give it to Play regardless of whether the body uses HTTP chunked transfer 
     encoding. If this value is exceeded, a single HTTP chunk may span numerous 
     Netty chunks.
     A non-HTTP chunked body will span multiple Netty chunks if it exceeds this  
     limit or if no content length is supplied. This solely affects the maximum size of 
     Netty chunk byte buffers. *@

    maxChunkSize = 8192

    # Should the Netty wire be logged?

    log.wire = false
    transport = "jdk"

    @* Netty options. Possible keys here are defined using:
       https://netty.io/4.1/api/io/netty/channel/ChannelOption.html
       To transfer native sockets:
       http://netty.io/4.1/api/io/netty/channel/unix/UnixChannelOption.html
       http://netty.io/4.1/api/io/netty/channel/epoll/EpollChannelOption.html
       Options related to the listening server socket are specified at the top level,    
       whereas options related to incoming client connections are prefixed with child. *@

    option {

       @* Set the size of the TCP connection backlog. 
       This parameter's default and precise meaning are JDK-specific.
       SO_BACKLOG = 100 *@

      child {

         @* Set whether connections should use TCP to keep-alive
         SO_KEEPALIVE = false *@

        @*  Determine if the TCP no-delay flag is enabled.
          TCP_NODELAY = false *@

        @* Example of how to set native socket transport options
         (Full qualified class name + "#" + option)
         "io.netty.channel.unix.UnixChannelOption#SO_REUSEPORT" = true
         "io.netty.channel.epoll.EpollChannelOption#TCP_FASTOPEN" = 1 *@

      }
    }
  }
}


Note: The Netty server backend is not enabled by default in 2.6.x and must be explicitly activated.

The options shown above are particular to the Akka HTTP and netty server backends; however, there are also more general setups available:

# Copyright (C) Lightbend Inc. 

play {

  server {

    @* The play server instance's root directory. This value may be set by passing a path 
    to the play server launcher script as the first input. 
    'ServerConfig.loadConfiguration' is an example. *@
    
    dir = ${?user.dir}

    # HTTP configuration

    http {

      @* The HTTP port of the server. Use a value of "disabled" if the server
       shouldn't bind an HTTP port. *@

      port = 9000
      port = ${?PLAY_HTTP_PORT}
      port = ${?http.port}

      # The interface address to bind to.

      address = "0.0.0.0"
      address = ${?PLAY_HTTP_ADDRESS}
      address = ${?http.address}

      @* The idle duration for an open connection before it is closed
      To disable the timeout, set it to null or "infinite," but keep in mind that this is not 
      recommended because timeouts are critical techniques for protecting your 
      servers from malicious assaults or programming errors. *@

      idleTimeout = 75 seconds
    }
    
    # HTTPS configuration

    https {

      # The HTTPS port of the server.

      port = ${?PLAY_HTTPS_PORT}
      port = ${?https.port}

      # The interface address to bind to

      address = "0.0.0.0"
      address = ${?PLAY_HTTPS_ADDRESS}
      address = ${?https.address}

       @* The idle duration for an open connection after which it will be closed
       Set to null or "infinite" to deactivate the timeout. However, keep in mind that this
       is not recommended because timeouts are critical techniques for protecting 
       your servers from malicious attacks or programming errors. *@

      idleTimeout = ${play.server.http.idleTimeout}

      # The SSL engine provider

      engineProvider = "play.core.server.ssl.DefaultSSLEngineProvider"
      engineProvider = ${?play.http.sslengineprovider}

      @* HTTPS keystore configuration, utilised by the default SSL engine provider *@

      keyStore {

        # The path to the keystore

        path = ${?https.keyStore}

        # The type of the keystore

        type = "JKS"
        type = ${?https.keyStoreType}

        # The password for the keystore

        password = ""
        password = ${?https.keyStorePassword}
        algorithm = ${?https.keyStoreAlgorithm}

      }
      trustStore {

        @* If true, does not perform CA verification on client-side certificates *@

        noCaVerification = false
      }

      @* Whether JSSE wants client auth mode should be used. This implies that the 
      server will ask for a client certificate but will not fail if one is not supplied. *@

      wantClientAuth = false

      @* Whether or not JSSE requires client authentication mode. This indicates that the
      server will request a client certificate, fail, and end the session.
      if one isn't provided. *@

      needClientAuth = false
    }

    @* The path to the process id file is defined by the server when it executes.
     If set to "/dev/null, " no pid file will be created. *@

    pidfile.path = ${play.server.dir}/RUNNING_PID
    pidfile.path = ${?pidfile.path}

    websocket {

      @* Maximum frame payload length permitted. Setting this number to the 
      requirements of your application may decrease denial of service attacks 
      employing large data frames. *@

      frame.maxLength = 64k
      frame.maxLength = ${?websocket.frame.maxLength}
      
    }
    debug {

      @* If set to true, this will add a debug information property to each request. If the 
      programme fails to load (for example, owing to a build error in dev mode), this 
      setting value is disregarded, and the debug information is attached permanently.
      Note: This configuration item is not part of Play's public API and is susceptible 
      to change without going through the standard deprecation cycle. *@

      addDebugInfoToRequests = false
    }

    @* The HTTP headers' maximum length. The most prevalent consequence is a 
    limitation in cookie length, which includes the number of cookies and the amount 
    of cookie values. *@

    max-header-size = 8k

    @* If a request includes a Content-Length header, it will be compared to this 
    maximum value.
    If the value of a specific Content-Length header exceeds the set value, the request 
    is aborted, and the error handler is triggered with Http status code 413 "Entity too 
    big."
     If set to infinite/if no Content-Length header is present, no check is performed and 
    the request is handled as usual.
     Play enforces this restriction using the idea of a 'BodyParser,' so we set it to 
    infinity. *@

    max-content-length = infinite
  }

  editor = ${?PLAY_EDITOR}

}

Logging Configuration

logging configuration play

A logback configuration file can be used to customise logging. Your application may access this in the following ways:

Including a Custom Logback Configuration File💻

Create an additional logback configuration file named logback.xml and copy it to app>/conf.

A System property can also be used to provide another logback configuration file. Please remember that if no configuration file is given, play will utilise the default logback.xml file that comes with play in production mode. Any log level settings in the application.conf file will be overwritten as a result. Always specify your logback.xml as a best practice.

Using -Dlogger.resource👨🏻‍💻

Select another logback configuration file from the classpath:

$ /path/to/bin/<project-name> -Dlogger.resource=prod-logger.xml

Using -Dlogger.file💻

Select another logback configuration file from the file system:

$ /path/to/bin/<project-name> -Dlogger.file=/opt/prod/prod-logger.xml

Using -Dlogger.url👨🏻‍💻

Another logback configuration file may be specified to be loaded from a URL:

$ /path/to/bin/<project-name> -Dlogger.url=http://conf.mycompany.com/logger.xml


Note: To observe which file is being utilised, set the system parameter -Dlogback.debug=true.

JVM Configuration

Any JVM parameters can be sent to the application launch script. Otherwise, the JVM's default parameters will be used:

$ /path/to/bin/<project-name> -J-Xms128M -J-Xmx512m -J-server


We hope you understood everything about deploying your application in the production configuration.🤗

Frequently Asked Questions

Define the play framework.

Play is based on a stateless, lightweight, web-friendly architecture. Play is built on akka. It has minimal resource consumption. It is a developer-friendly framework and very versatile. Most of the java libraries are also supported in play. 

In which format are most of the play’s configurations defined?

The majority of play's configuration is defined in .conf files that employ the HOCON format.

Describe the akka cluster.

A fault-tolerant decentralised peer-to-peer cluster membership service without a single point of failure or bottleneck is offered by Akka Cluster.

Play uses which code in level messages?

In level messages, play employs ANSI colour codes by default.

What is a JVM application?

The JVM provides a portable execution environment for java-based applications while managing system memory.

Conclusion

In this article, we have extensively discussed several configuration types that may be configured in production. 

Do you not feel eager to read/explore additional information on the subject of the Play framework after reading about several configuration types that may be configured in production? See the Coordinated ShutdownConfiguring Netty Server BackendGuidelines for Writing Play Documentation, and 15 Best Java frameworks to use in 2022-Coding Ninjas.

Refer to our guided paths on Coding Ninjas Studio to learn more about DSA, Competitive Programming, JavaScript, System Design, etc. Enrol in our courses and refer to the mock test and problems available. Take a look at the interview experiences and interview bundle for placement preparations.

Happy Learning Ninja! 🥷

Live masterclass