The guys at Heroku released by the end of 2011, a now open-source manifesto that enumerates 12 factors (or best practices, or rules) to develop SaaS (software-as-a-service) products.

The main goals of those 12 factors are to create robust applications that maximize portability, encourage continuous deployment and scale effortless

It is not directly coupled to any specific language or development environment.

Although these factors where build from the perspective and observation of applications deployed to Heroku, hence a devops oriented perspective, they conform a robust set of principles on how to get a modern web app deployed properly https://12factor.net/

1. Codebase

One codebase tracked in revision control, many deploys

That’s it, you should use any reliable source control system (git, mercurial, subversion, …), and master it. Yes, believe me, I already saw software being developed without versioning, or with homemade solutions…

“There is always a one-to-one correlation between the codebase and the app”
Do not use a single source control repository to all company projects. One repository to each application.

2. Dependencies

Explicitly declare and isolate dependencies

“A twelve-factor app never relies on implicit existence of system-wide packages” All libraries, components, packages, all dependencies, must be explicit declared in an configurantion file. A good example is Bundler/Gem tool in Ruby.

“Twelve-factor apps also do not rely on the implicit existence of any system tools” This philosophy extends to your devs or devops team managing entire machine configurations using management tools like Chef and Puppet

3. Config

Store config in the environment

strict separation of config from code Application configuration settings should not be stored inside the code. Normally they change more often then code, and also are dependent of an outside tool, like a database, an operating system, are credentials, etc. “The twelve-factor app stores config in environment variables” Somehow self explanable.

4. Backing services

“Treat backing services as attached resources”

“The code for a twelve-factor app makes no distinction between local and third party services” The application should be able to swap the backing service (resource), within a configuration file. A good example is the Ruby on Rails database.yml, where you can change from a database that is installed locally in the same server as the application, to a database in the cloud, just by change its configuration file.

5. Build, release, run

Strictly separate build and run stages

A deploy should be executed in three steps:

  1. A build stage, where the application is extracted from the source code repository,
  2. A release stage, where the outcome from the build stage is combined with configuration variables
  3. A run stage, where all the services are running A good example for that is Capistrano deploy tool, used in the ruby world.

6. Processes

Execute the app as one or more stateless processes

“Twelve-factor processes are stateless and share-nothing”
Having stateless processes makes your application scalable, or at least easier to scale. If the application keep changes in an object in the session, without persisting it in a database, it is is going to be quite difficult to apply load balance to the app.

7. Port binding

Export services via port binding

“The twelve-factor app is completely self-contained” The idea is that the application interfaces to the world using a simple URL.

8. Concurrency

Scale out via the process model

When an application is running lots of little processes are handling specific needs, like processing web-requests, api calls, e-mail handling, background jobs, etc.

keeping all those processes working independently, and running them as separate processes, the application will scale better.

9. Disposability

Maximize robustness with fast startup and graceful shutdown

“The twelve-factor app’s processes are disposable, meaning they can be started or stopped a moment’s notice” A slim and fast startup and shutdown, makes resources available fast.
Further, the application should be robust, in a way that if crashes, it should always be able to start back cleanly.

10. Dev/prod parity

Keep development, staging, and production as similar as possible

“The twelve-factor app is designed for continuous deployment by keeping the gap between development and production small.”

“The twelve-factor developer resists the urge to use different backing services between development and production”

Well, you should keep the different environments of your application as close as possible to production, that means, using the same OS, same DB, same caching, load balance, etc. It is quite easier to troubleshoot it, errors are easier to replicate…

11. Logs

Treat logs as event streams

“A twelve-factor app never concerns itself with routing or storage of its output stream.” The application should not have its own logging system, or manage logfiles, but send logging messages directly to STDOUT. Log storage, collating, and analysis be done in the environment or with other tools.
Logs should provide visibility to how the application works over time.

12. Admin processes

Run admin/management tasks as one-off processes

Developers will need from time to time to do administration or maintenance tasks in the production environment. These tasks should be run in an identical environment as the production, in the same release as the production release, using the same configuration. These tasks should not be done directly, but t through an script.
For example, if it is needed to do a change in the database, it should not be done by executing sql command directly in the db, but by using a script that was previously executed in a clone environment.