Skip to content

Image Layered Architecture


What if you could build an application image once, change only your source code, and avoid rebuilding everything from scratch?

That’s the idea behind Image Layered Architecture. Instead of treating an image as one giant block, we can think of it as a stack of reusable layers—base OS, runtime, dependencies, requirements, and finally our application code.

Once you understand how these layers work, image builds, caching, rebuild times, and image optimization start making a lot more sense.

Image Layers

Don’t get overwhelmed listening image layers. It’s just an indication of something has changed in your filesystem which can be anything like:

  • You install new package
  • You add new file
  • You modify or delete existing file

One thing to understand about image layers is that they are immutable (can’t be changed) once committed. This means any change in the filesystem will create a new layer.

Benefits of Layers

We will try to understand the benefit of this layerd architecture with an example of theoretical image.

Let’s say you are developing a python app (you dont’ need to learn python to understand this) where each layer can look like the following:

Your theroretical image:

  • Layer1: First you choose a base image that has command and package managar
  • Layer2: You install your app runtime and dependency manager on top of it Layer 1
  • Layer3: You put on your requirements file on top of Layer 2
  • Layer4: You install your app’s requirements/dependencies Layer 3
  • Layer5: You put all your app’s source code Layer 4

As you see each layer from 1 to 5 has some change in file system. You can visualize your theoretical image as:

    flowchart 
    subgraph "The Diagram Showing Layered Architecture for an App (python in our example)"
        direction TD
        Layer1["Ubuntu Base Image"]
        Layer2["Runtime and Dependency Manager"]
        Layer3["Requirements File"]
        Layer4["Dependencies"]
        Layer5["Source Code"]

        Layer5 --> Layer4
        Layer4 --> Layer3
        Layer3 --> Layer2
        Layer2 --> Layer1
    end
  

Now suppose you need to build another python application which will have different requirements. This time you don’t need to create all the layers because any layer (from 1 to 5) can be reused.

Which one will you reuse though?

This is the question you need to ask yourself. In the above scenario, it is most likely you will have same Runtime and Dependency Manager i.e. Layer2. And Layer2 also already has package manager because it’s built on top of Layer1. This means you can take Layer2 as base instead of Layer1. The figure makes everything clear.

    flowchart
    subgraph "Benefits of Layered Architecture"
        direction TB

        A1["App1 Source Code"]
        A2["App2 Source Code"]

        D1["App1 Dependencies"]
        D2["App2 Dependencies"]

        R1["App1 Requirements File"]
        R2["App2 Requirements File"]

        P["Runtime and Dependency Manager (Shared Base)"]
        B["Ubuntu Base Image"]

        A1 --> D1 --> R1
        A2 --> D2 --> R2

        R1 --> P
        R2 --> P

        P --> B
    end
  

As seen both apps share the same base image where there is already runtime and dependency manager installed. You don’t need that installation twice for App2. You just put your requirements file on top of that and move the layer up till you put your source code.

Note

You can choose any layer as your base. Suppose you just need to change source code than you can choose Layer4 as base instead of Layer2.

If you want to see layered architecture practically, follow the next class for practical.

Last updated on