Around 2011-2012 when the cloud computing was not that popular, developers from Heroku presented methodology known as Twelve-Factor App. It describes recipes for building cloud-native, scalable, deployable applications. In my opinion it is a baseline for any team building cloud-native apps.
When you design applications for containers you should keep in mind that container image moves from environment to environment, so the image can’t hold things like production database credentials or any other sensitive information. It all should be supplied to the container by injecting configuration on container start up.
Another thing is to not bake-in any networking inside your image. Container images should not contain hostnames or port numbers. That’s because the setting needs to change dynamically while the container image stays the same. Links between containers are all established by the control plane when starting them up.
Containers are meant to start and stop rapidly. Avoid long startup or initialization sequences. Some production servers take many minutes to load reference data or to warm up caches. These are not suited for containers. Aim for a total startup time of one second.
It’s hard to debug an containerized applications. Just getting access to log files can be a challenge. Such applications need to send their telemetry out to a data collector.
Let’s take a closer look to these 12 factors which you should keep in mind each time developing application which meant to be running in container. The “factors” identify different potential impediments to deployment, with recommended solutions for each:
|1||Codebase||Track one codebase in revision control. Deploy the same build to every environment|
|2||Dependencies||Explicitly declare and isolate dependencies|
|3||Config||Store config in the environment|
|4||Backing services||Treat backing services as attached resources|
|5||Build, release, run||Strictly separate build and run stages|
|6||Processes||Execute the app as one or more stateless processes|
|7||Port binding||Export services via port binding|
|8||Concurrency||Scale out via the process model|
|9||Disposability||Maximize robustness with fast startup and graceful shutdown|
|10||Dev/prod parity||Keep development, staging, and production as similar as possible|
|11||Logs||Treat logs as event streams|
|12||Admin processes||Run admin/management tasks as one-off processes|