Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Preview

Twelve factors, part one

This is the first page of the lesson. Read it and have a go at the activities. The rest is in the full lesson.

45 minutes

It works on my laptop

Aisha builds an app. It works on her laptop. She puts it on the server. It breaks.

A package is missing. The password is wrong. The folder is not there.

Twelve habits, called the twelve factors, stop most of these problems. Today you learn the first six.

Key words

WordWhat it meansExample
Twelve-factor appAn app built with twelve good habits so it is easy to deploy and grow.
DatabaseAn organised store of data that programs can search and change.
Version controlA tool that keeps every version of your files.
NetworkComputers joined together so they can send data to each other.
CodebaseAll the code of one app, kept in one repository.
RepositoryA store for code and its full history.
DeployAs a verb: put the app on a computer and start it. In the twelve factors it is also a noun: one running copy of the app, such as test or live.
DependencyA package your code needs to run.flask
ConfigurationSettings that change between deploys, such as passwords and web addresses.
Environment variableA setting stored outside the code, in the place where the app runs.PORT=9000
Backing serviceA service your app uses over the network, such as a database or email.
StatelessA process that keeps nothing on itself between requests.

The cells students fill in are left blank in this preview.

Six habits

Each factor is a short rule. It has a reason. Learn the reason and you can find the rule again.

Run the code below to see factor 3 at work: the configuration comes from outside the code.

Try it: a setting from outside

Code: python
import os

# Read a setting. If there is none, use "Hello".
greeting = os.environ.get("GREETING", "Hello")
print(greeting, "world")

# The code does not change. Only the setting changes.
# A setting that is missing should give a clear error, not a guess.

Factors 1 to 6

FactorRule in plain wordsWhy
1 CodebaseOne codebase in version control. Many deploys come from itTest and live run the same code
2 DependenciesWrite down every package you need. Keep them apart from other projectsA new machine installs the same things
3 ConfigKeep settings in the environment, not in the codeThe same code runs anywhere. No passwords in the repository
4 Backing servicesTreat a database or email service as a plug you can swap by changing a settingYou can change database without changing code
5 Build, release, runKeep three stages apart: make the program, add the settings, then run itYou can go back to an old release if the new one is bad
6 ProcessesRun as stateless processes. Keep data in a database, not in the processAny process can answer any request. One can die and nothing is lost

The cells students fill in are left blank in this preview.

Never put a password in code

data-callouts.warning.label

Code goes into a repository, and many people can read it. A password in code is shared with everyone. Keep passwords in the environment, and never in version control.

Try it: swap a backing service

Code: python
import os


class MemoryStore:
    def __init__(self):
        self.items = []

    def save(self, item):
        self.items.append(item)

    def load(self):
        return self.items


class LoudStore(MemoryStore):
    def save(self, item):
        print("Saving", item)
        super().save(item)


# The setting picks the store. The rest of the code does not change.
name = os.environ.get("STORE", "memory")
store = LoudStore() if name == "loud" else MemoryStore()

store.save("tea")
print(store.load())

# Change "memory" to "loud" in the line that reads STORE and run again.
# A real app swaps a small database for a big one in the same way.

Try it: why processes must be stateless

Code: python
class Process:
    def __init__(self, name):
        self.name = name
        self.basket = []      # kept inside this process

    def add(self, item):
        self.basket.append(item)

    def show(self):
        print(self.name, "sees", self.basket)


one = Process("process 1")
two = Process("process 2")
one.add("tea")
one.show()
two.show()      # the second process knows nothing

# Fix it: make one shared basket outside both processes.
# In a real app, that shared place is a database.

Which factor is broken?

Have a go

Which factor is broken?

6 questions
Have a go: your answers are marked here and then forgotten. Sign in if you would like your score kept, and to pick up where you left off.Sign in to keep your score

Your answers are marked here and are not kept. A college account keeps every student’s marks.

The lesson goes on

3 more parts of this lesson are in the full curriculum, with the tasks, the final check and the labs. A college account gives your students all of it.