I came across 12 factor through my colleagues and was intrigued by their opinion on port binding. 12 factor suggests that each web application be packaged as an executable war file and that the war file should have a web server embedded within it that binds the HTTP Service to a port. Other people have gone a bit further and have packaged the application as a Linux service that runs the war file. This is completely different than the traditional way of deploying web applications to an application container. This post draws a comparison between the two approaches.
Installation of an application with an embedded server (hence forth called as the 12 factor app) does not require that you place a war file inside the server’s installation directory. The installation directory could differ from host to host and this makes the installation process more complicated. You could work around this complexity by using provisioning tools like puppet, but the fact remains that the root cause of the problem is coupling the installation of your application with the installation of the application server.
Use system package managers
The 12 factor app can be installed through system packages like RPM or Deb since it does not make any assumptions about installation directories. It is theoretically possible to install the traditional application through system packages, but since they would depend upon specific directory structures, it is not a recommended approach as the packages would not be portable.
Fine grained control over resource usage
Say that you have two web applications. Installing them inside the same container means that they are going to compete for resources like heap and perm space, thread pools etc. Lets say that one of those applications need to have high throughput. For applications that require high throughput, you would want to allocate more resources. Since the resources provided by the container is shared between the two applications, there is no guarantee that increasing the amount of resources allocated to the container would automatically get translated into more resources being allocated to the high throughput application. The solution is to split the applications into two separate processes.
Imagine again that there are two web applications. This time, one web application consumes services provided by the other. If they are 12 factor, you could spin up multiple processes for the service provider and put them behind a load balancer at will. This allows you to scale your applications independently of each other.
Obviosuly, 12 factor apps since they are separate processes, would require more system resources than traditional apps.
Independent start and stop
12 factor apps since they are not inside the same process could be started and stopped independently of each other.
Consider again that there are two web applications, one consuming the service of another. The service provider should be started before the service consumer. This is not possible if they are inside the same container as there is no specification that guarantees the order in which applications are started inside a container like Tomcat. 12 factor apps though, since they use system services, could take advantage of dependency mechanisms provided by service managers like chkconfig on centos boxes to implement ordering.
12 factor apps, since they use OS packages, are specific to the OS. You need to build separate packages for each OS you are going to deploy to.
12 factor apps are not affected by hard to trace bugs that occur because there is a jar in the lib folder of tomcat that interferes with the one used in your application. This makes the runtime of your application same in all the environments to which it is deployed.
Since the 12 factor app is an executable war which is not exploded, the configurable properties of the app should be sourced through environment variables and not property files.