One codebase per app, multiple deployments
DO
- One codebase to rule all deployment environments: production, staging, local and so on and differentiate them from config files (see #3).
DON’T
- Multiple apps sharing the same code. INSTEAD the common code should be extracted from a library and included through a dependency manager.
Declare and isolate dependencies
DO
- Have a dependency declaration manifest (e.g. packages.json, Gemfile)
- Execute dependencies in isolation per app (e.g. bundle exec).
DON’T
- Rely on implicit existence of system-wide packages (e.g. curl, ImageMagik). INSTEAD vendor them into the app.
Store the config in the environment
DO
- Separate app’s config (AWS S3, passwords, Google/Fb/Tw/APIs credentials, deployment hostname) from the code.
- Keep the code ready in a way that if were open source, it wouldn’t compromise any credentials.
- Use/commit ‘config’ files with sensitive information into repository. INSTEAD use environmental variables (env, env vars) which are easily changed between deployments and without changing code.
DON’T
- Group config variables by environment (e.g. AWS_S3_PRODUCTION, AWS_S3_TEST, AWS_S3_QA, AWS_S3_STAGING, AWS_S3_JOE…). INSTEAD use clean environment variables (e.g. AWS_S3) that are managed individually per deploy.
Swappable local and third party services
DO
- Services like databases (e.g. MongoDB, PostgreSQL), message queues (e.g. RabbitMQ, Beanstalkd) should be accessed via URL or locator/credential stored in config.
- Swapping local to production services should be done without any code changes.
Build and runtime
DO
- Code changes flows in one direction only development -> build -> run time environments.
Execute the app as share-nothing stateless processes
DO
- Store any persistent data in external services (such as databases)
DON’T
- Use the filesystem/memory to save states. INSTEAD any instance of the app should be able to handle requests.
Export services via port binding
DO
- App is completely self-contained and communicates with other processes through port binding.
Scale out the app horizontally
DO
- Scale app horizontally since the app is a stateless and share-nothing model.
DON’T
- Daemonize. INSTEAD use operating system manager such as Upstart or init and Foreman in development.
Fast startup and shutdown
DO
- app start in few seconds to serve requests or jobs.
- shut down gracefully after receiving SIGTERM signal (stop receiving new request/jobs, finish processing current request/job before stopping).
Keep development, staging, and production as similar as possible
DO
- design app for continuous deployment keeping the tools gaps and deployment times as minimum as possible.
- code from development to production should take few hours or just few minutes.
- developers who wrote the code should be able to deploy it to production.
- keep production and development tool the same as possible
DON’T
- use different services on production and development (e.g. development using SQLite and production ProtgreSQL).
#[object object] #mobileapp