C4 Model for Architecture Documentation One-Pager

one-pagers documentation

Introduction

Diagrams are the maps that help software developers navigate a complex codebase.
— Simon Brown
Creator of C4 software architecture model

The C4 model captures the static structure of a software system.

A software system is made up of one or more containers (web applications, mobile apps, desktop applications, databases, file systems, etc), each of which contains one or more components, which in turn are implemented by one or more code elements (e.g. classes, interfaces, objects, functions, etc). And people use the software systems that we build.

Basics

Level 1: Software Systems

  • A software system is the highest level of abstraction.

  • Delivers value to its users.

Level 2: Containers

  • A container is something that needs to be running in order for the overall software system to work.

  • A container is essentially a context or boundary inside which some code is executed or some data is stored.

  • Feel free to call it runtime context”, “execution environment” or “deployable unit”.

  • Containers are separately deployable.

  • Every container can be deployed onto or run on a separate piece of infrastructure.

  • Communication between containers is likely to require an out-of-process or remote procedure call across the process and/or network boundary.

  • Two separate database schemas are two separate containers.

Level 3: Components

  • Grouping of related functionality encapsulated behind a well-defined interface.

  • Components are not separately deployable units.

  • Components inside a container typically execute in the same process space.

Level 4: Code

  • Components are made up of one or more code elements constructed with the basic building blocks of the programming language that you’re using; classes, interfaces, enums, functions, objects, etc.

Examples

  • Software System: Any system that is outside your or your team’s control.

  • Containers:- Server-side web apps on tomcat, iis, client side webapps. mobile apps, console apps, microservices, serverless functions, databases, blob, content store, file system, shell script. Should be within yours or your teams control.

  • Components:- JAR files, DLL files, .NET assemblies,etc

The C4 model

The “C4 model”: (System) Context, Containers, Components and Code.

  1. System Context: A System Context diagram provides a starting point, showing how the software system in scope fits into the world around it.

  2. Containers: A Container diagram zooms into the software system in scope, showing the high-level technical building blocks (containers) and how they interact.

  3. Components: A Component diagram zooms into an individual container, showing the components inside it.

  4. Code: A code (e.g. UML class) diagram can be used to zoom into an individual component, showing how that component is implemented.

Level 1: System Context Diagram

System Context diagram allows you to step back and look at the big picture.

A System Context diagram helps answer the following:

  1. What is the software system that we are building (or have built)?

  2. Who is using it?

  3. How does it fit in with the existing environment?

A System Context diagram usually includes two types of elements; people and software systems.

Capture the following information about the people using the system:

  • Name: The name of the person, user, role, actor or persona.

  • Description: A short description of the person, their role, responsibilities, etc.

Capture the other software systems that your software system interacts with.

Software systems sit outside the scope or boundary of your own software system, and you don’t have responsibility or ownership of them.

Capture the following about other software systems:

  • Name: The name of the software system.

  • Description: A short description of the software system, its responsibilities, etc

Annotate every interaction between elements on the diagram with some information about the purpose of that interaction. Keep it high-level.

Avoid Technical Details.

A System Context diagram is a good starting point for other diagrams. Very useful when gathering requirements.

Non-technical folks must be able to read this diagram to get an overview of the system.

Level 2: Container Diagram

It is a high-level technology focussed diagram that is useful for software developers and support/operations staff alike.

A container diagram helps you answer the following questions:

  1. What is the overall shape of the software system?

  2. What are the high-level technology decisions?

  3. How are responsibilities distributed across the system?

  4. How do containers communicate with one another?

  5. As a developer, where do I need to write code in order to implement features?

A container typically represents an application or data store.

Capture the following information for a conatiner:

  • Name: The name of the container (e.g. “Internet-facing web server”, “Database”, etc).

  • Technology: The implementation technology (e.g. Java/Spring MVC application, ASP.NET web application, C# Windows Service, Relational Database Schema, etc).

  • Description: A short descriptive statement, or perhaps a list of the container’s key responsibilities or entities/tables/files/etc that are being stored.

Annotate all interactions.

Useful information to annotate the interactions with includes:

  • The purpose of the interaction (e.g. “reads/writes data from”, “sends reports to”, etc).

  • The communication mechanism (e.g. Web Services, REST, Web API, Java Remote Method Invocation, Windows Communication Foundation, Java Message Service).

  • The communication style (e.g. synchronous, asynchronous, batched, two-phase commit, etc).

  • Protocols and port numbers (e.g. HTTP, HTTPS, SOAP/HTTP, SMTP, FTP, RMI/IIOP,etc).

Software developers, operational and support staff should find this useful because:

  • It makes the high-level technology choices explicit.

  • It shows the relationships between containers, and how those containers communicate.

Level 3: Component Diagram

A Component diagram helps you answer the following questions.

  1. What components is each container made up of?

  2. Do all components have a home (i.e. reside in a container)?

  3. It is clear how the software works at a high-level?

Components are the coarse-grained building blocks of your software system that live inside of a container.

Capture the following information for each component:

  • Name: The name of the component.

  • Technology: The implementation technology for the component (e.g. Plain Old [Java|C#|Ruby|etc] Object, Enterprise JavaBean, Windows Communication Foundation service, etc).

  • Description: A short description of the component, usually a brief sentence describing the component’s responsibilities.

Annotate the interactions between components.

Useful information to add the diagram includes:

  • The purpose of the interaction (e.g. “uses”, “persists data using”, “delegates to”, etc).

  • Communication style (e.g. synchronous, asynchronous, etc).

A Component diagram shows the components that reside inside an individual container.

This is useful because:

  • It shows the high-level decomposition of a container into components, each with distinct responsibilities.

  • It shows where there are relationships and dependencies between components.

  • It provides a high-level summary of the implementation details, including any frameworks or libraries being used.

  • If the components shown on the diagram can be explicitly mapped to the code, you have a good way to really understand the structure of a codebase.

Level 4 Code-level Diagrams

The intent of a code-level diagram is to illustrate the structure of the code and, in this case, how a component is implemented.

If you are using an object-oriented programming language, probably the best way to do this is to use a UML class diagram, either by generating it automatically from the code or by drawing it freehand.

Only include as much information as you need to tell the story that you want to tell.
Typically, only include the attributes and methods that are relevant to the narrative.

Having this final level of abstraction provides a way to map the high-level, coarse-grained components into real-world code elements. It helps to bridge what are sometimes seen as two very different worlds; the software architecture and the code.

Examples

Container C4 Elements Example

dot example2
@startuml C4_Elements
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

Person(personAlias, "Label", "Optional Description")
Container(containerAlias, "Label", "Optional Description")
System(systemAlias, "Label", "Optional Description")

Rel(personAlias, containerAlias, "Label", "Optional Technology")
@enduml

A basic C4 container example

basicexample
@startuml Basic Sample
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

Person(admin, "Administrator")
System_Boundary(c1, "Sample System") {
    Container(web_app, "Web Application", "C#, ASP.NET Core 2.1 MVC", "Allows users to compare multiple Twitter timelines")
}
System(twitter, "Twitter")

Rel(admin, web_app, "Uses", "HTTPS")
Rel(web_app, twitter, "Gets tweets from", "HTTPS")
@enduml

Example with sprites and a legend

spritesample
@startuml Sprite Sample
!define DEVICONS https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons
!define FONTAWESOME https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/font-awesome-5

!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
!include https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/common.puml
!includeurl DEVICONS/angular.puml
!includeurl DEVICONS/java.puml
!includeurl DEVICONS/msql_server.puml
!includeurl FONTAWESOME/users.puml

LAYOUT_WITH_LEGEND()

Person(user, "Customer", "People that need products", $sprite="users")
Container(spa, "SPA", "angular", "The main interface that the customer interacts with", $sprite="angular")
Container(api, "API", "C#", "Handles all business logic", $sprite="csharp")
ContainerDb(db, "Database", "Microsoft SQL", "Holds product, order and invoice information", $sprite="microsoftsqlserver")

Rel(user, spa, "Uses", "https")
Rel(spa, api, "Uses", "https")
Rel_R(api, db, "Reads/Writes")
@enduml
links sample
@startuml Link Sample
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

Person(admin, "Administrator", $sprite="person2", $link="https://tremorscript.com")
System_Boundary(c1, "Sample System", $link="https://tremorscript.com") {
    Container(web_app, "Web Application", "C#, ASP.NET Core 2.1 MVC", $descr="Allows users to compare multiple Twitter timelines")
}
System(twitter, "Twitter", $link="https://tremorscript.com")

Rel(admin, web_app, "Uses", "HTTPS", $link="https://tremorscript.com")
Rel(web_app, twitter, "Gets tweets from", "HTTPS", $link="https://tremorscript.com")
@enduml

Example with custom tags and a calculated legend

tagslegend
@startuml custom tags and calculated legend
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

AddElementTag("v1.0", $borderColor="#d73027")
AddElementTag("v1.1", $fontColor="#d73027")
AddElementTag("backup", $fontColor="orange")

AddRelTag("backup", $textColor="orange", $lineColor="orange", $lineStyle = DashedLine())

Person(user, "Customer", "People that need products")
Person(admin, "Administrator", "People that administrates the product via the new v1.1 components.", $tags="v1.1")
Container(spa, "SPA", "angular", "The main interface that the customer interacts with via v1.0", $tags="v1.0")
Container(spaAdmin, "Admin SPA", "angular", "The administrator interface that the customer interacts with via v1.1", $tags="v1.1")
Container(api, "API", "C#", "Handles all business logic (incl. new v1.1 extensions)", $tags="v1.0+v1.1")
ContainerDb(db, "Database", "Microsoft SQL", "Holds product, order and invoice information")
Container(archive, "Archive", "Audit Logging", "Stores 5 years", $tags="backup")

Rel(user, spa, "Uses", "https")
Rel(spa, api, "Uses", "https")
Rel_R(api, db, "Reads/writes")
Rel(admin, spaAdmin, "Uses", "https")
Rel(spaAdmin, api, "Uses", "https")
Rel_L(api, archive, "Writes", "messages", $tags="backup")

SHOW_LEGEND()
@enduml

Example showing how to layout elements with relationships

example rel
@startuml layout with relationships
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

HIDE_STEREOTYPE()

Person(a, "A")
Person(b, "B")
Person(c, "C")
Person(d, "D")
Person(e, "E")


BiRel_U(a,b, "talk with")
BiRel_R(a,c, "talk with")
BiRel_D(a,d, "talk with")
BiRel_L(a,e, "talk with")

Person(x, "X")
System(s1, "S1")
System(s2, "S2")
System(s3, "S3")
System(s4, "S4")

Rel_U(x, s1, "uses")
Rel_R(x, s2, "uses")
Rel_D(x, s3, "uses")
Rel_L(x, s4, "uses")

@enduml

Example showing how to layout elements without relationships

layout rel1
@startuml layout without relationships
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

HIDE_STEREOTYPE()

Person(a, "A")
Person(b, "B")
Person(c, "C")
Person(d, "D")
Person(e, "E")

Lay_U(a,b)
Lay_R(a,c)
Lay_D(a, d)
Lay_L(a, a)

Person(x, "X")
System(s1, "S1")
System(s2, "S2")
System(s3, "S3")
System(s4, "S4")

Rel_U(x, s1, "uses")
Rel_R(x, s2, "uses")
Rel_D(x, s3, "uses")
Rel_L(x, s4, "uses")

@enduml

System Context Diagram for Internal Banking System

context diagram banking
@startuml

!theme C4_sandstone from https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/themes
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml

title System Context Diagram for Internet Banking System

Person(customer, "Personal Banking Customer", "A customer of the bank, with personal bank accounts.")
System(banking_system, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")

System_Ext(mail_system, "E-mail system", "The internal Microsoft Exchange e-mail system.")
System_Ext(mainframe, "Mainframe Banking System", "Stores all of the core banking infrastructure about customers, accounts, transactions, etc.")

Rel(customer, banking_system, "Uses")
Rel_Back(customer, mail_system, "Sends e-mails to")
Rel_Neighbor(banking_system, mail_system, "Sends e-mails", "SMTP")
Rel(banking_system, mainframe, "Uses")

SHOW_LEGEND()
@enduml

Container diagram for Internet Banking System

container diagram internet
@startuml

!theme C4_sandstone from https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/themes
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

title Container diagram for Internet Banking System

Person(customer, Customer, "A customer of the bank, with personal bank accounts")

System_Boundary(c1, "Internet Banking") {
    Container(web_app, "Web Application", "Java, Spring MVC", "Delivers the static content and the Internet Banking SPA")
    Container(spa, "Single Page App", "JavaScript, Angular", "Provides all the internet banking functionality to customers via their web browser")
    Container(mobile_app, "Mobile App", "C#, Xamarin", "Provides a limited subset of the Internet banking functionality to customers via their mobile device")
    ContainerDb(database, "Database", "SQL Database", "Stores user registration information, hashed auth credentials, access logs etc")
    Container(backend_api, "API Application", "Java, Docker Container", "Provides Internet banking functionality via API")
}

System_Ext(email_system, "E-Mail System", "The internal Microsoft Exchange system")
System_Ext(banking_system, "Mainframe Banking System", "Stores all the core banking information about customers, accounts, transactions, etc.")

Rel(customer, web_app, "Uses", "HTTPS")
Rel(customer, spa, "Uses", "HTTPS")
Rel(customer, mobile_app, "Uses")

Rel_Neighbor(web_app, spa, "Delivers")
Rel(spa, backend_api, "Uses", "async, JSON/HTTPS")
Rel(mobile_app, backend_api, "Uses", "async, JSON/HTTPS")
Rel_Back_Neighbor(database, backend_api, "Reads from and writes to", "sync, JDBC")

Rel_Back(customer, email_system, "Sends e-mails to")
Rel_Back(email_system, backend_api, "Sends e-mails using", "sync, SMTP")
Rel_Neighbor(backend_api, banking_system, "Uses", "sync/async, XML/HTTPS")

SHOW_LEGEND()
@enduml

Component diagram for Internet Banking System - API Application

api internet
@startuml

!theme C4_sandstone from https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/themes
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

title Component diagram for Internet Banking System - API Application

Container(spa, "Single Page Application", "JavaScript, Angular", "Provides all the internet banking functionality to customers via their web browser")
Container(ma, "Mobile App", "C#, Xamarin", "Provides a limited subset of the Internet banking functionality to customers via their mobile device")
ContainerDb(db, "Database", "SQL Database", "Stores user registration information, hashed auth credentials, access logs etc")
System_Ext(mbs, "Mainframe Banking System", "Stores all the core banking information about customers, accounts, transactions, etc.")

Container_Boundary(api, "API Application") {
    Component(sign, "Sign In Controller", "MVC Rest Controller", "Allows user to sign in to the internet banking system.")
    Component(accounts, "Accounts Summary Controller", "MVC Rest Controller", "Provides customers with a summary of their bank accounts.")
    Component(security, "Security Component", "Spring Bean", "Provides functionality related to signing in, changing passwords etc.")
    Component(mbsfacade, "Mainframe Banking System Facade", "Spring Bean", "A facade onto the mainframe banking system.")

    Rel(sign, security, "Uses")
    Rel(accounts, mbsfacade, "Uses")
    Rel(security, db, "Read & write to", "JDBC")
    Rel(mbsfacade, mbs, "Uses", "XML/HTTPS")
}

Rel(spa, sign, "Uses", "JSON/HTTPS")
Rel(spa, accounts, "Uses", "JSON/HTTPS")

Rel(ma, sign, "Uses", "JSON/HTTPS")
Rel(ma, accounts, "Uses", "JSON/HTTPS")

SHOW_LEGEND()
@enduml

System Landscape Diagram

system landscape
@startuml

!theme C4_sandstone from https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/themes
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml


title System Landscape diagram for Big Bank plc

Person(customer, "Personal Banking Customer", "A customer of the bank, with personal bank accounts.")

Enterprise_Boundary(c0, "Big Bank plc") {
    System(banking_system, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")

    System_Ext(atm, "ATM", "Allows customer to withdraw cash.")
    System_Ext(mail_system, "E-mail system", "The internal Microsoft Exchange e-mail system")

    System_Ext(mainframe, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

    Person_Ext(customer_service, "Customer Service Staff", "Customer service staff within the bank.")
    Person_Ext(back_office, "Back Office Staff", "Administration and support staff within the bank.")
}

Rel_Neighbor(customer, banking_system, "Uses")
Rel_R(customer, atm, "withdraws cash using")
Rel_Back(customer, mail_system, "Sends e-mail to")


Rel_R(customer, customer_service, "Asks questions to", "Telephone")

Rel_D(banking_system, mail_system, "Sends e-mail using")
Rel_R(atm, mainframe, "Uses")
Rel_R(banking_system, mainframe, "Uses")
Rel_D(customer_service, mainframe, "Uses")
Rel_U(back_office, mainframe, "Uses")

Lay_D(atm, banking_system)

Lay_D(atm, customer)
Lay_U(mail_system, customer)

SHOW_LEGEND()
@enduml

Dynamic Diagram

dynamic diag
@startuml

!theme C4_sandstone from https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/themes
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml

ContainerDb(c4, "Database", "Relational Database Schema", "Stores user registration information, hashed authentication credentials, access logs, etc.")
Container(c1, "Single-Page Application", "Javascript and Angular", "Provides all of the Internet Banking functionality to customers via their web browser.")
Container_Boundary(b, "API Application") {
    Component(c3, "Security Component", "Spring Bean", "Provides functionality Related to signing in, changing passwords etc.")
    Component(c2, "Sign In Controller", "Spring MVC Rest Controller", "Allows users to sign in to the Internet Banking System.")
}

Rel_R(c1, c2, "Submits credentials to", "JSON/HTTPS")
Rel(c2, c3, "Calls isAuthenticated() on")
Rel_R(c3, c4, "select * from users where username= ?", "JDBC")

SHOW_LEGEND()
@enduml

Sequence Diagram

@startuml

!theme C4_sandstone from https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/themes
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Sequence.puml

Container(c1, "Single Page Application", "Javascript and Angular", "Provides all of the Internet Banking functionality to customers via their web browser.")

Container_Boundary(b, "API Application")
    Component(c2, "Sign In Controller", "Spring MVC Rest Controller", "Allows users to sign in to the Internet Banking System")
    Component(c3, "Security Component", "Spring Bean", "Provides functionality Related to signing in, changing passwords, etc.")
Boundary_End()

ContainerDb(c4, "Database", "Relational Database Schema", "Stores user registration information, hashed authentication credentials, access logs, etc.")

Rel(c1, c2,"Submits credentials to", "JSON/HTTPS")
Rel(c2, c3, "Calls isAuthenticated on")
Rel(c3, c4, "select * from users where username=?", "JDBC")

SHOW_LEGEND()
@enduml

Deployment Diagram for Internet Banking System - Live

dep diag
@startuml

!theme cb_div_PRGn_11 from https://raw.githubusercontent.com/mweagle/C4-PlantUML-Themes/main/palettes
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Deployment.puml


AddElementTag("fallback", $bgColor="#D3BC8D")
AddRelTag("fallback", $textColor="#D3BC8D", $lineColor="#2F4F2F")

' calculated legend is used (activated in last line)
' LAYOUT_WITH_LEGEND()

title Deployment Diagram for Internet Banking System - Live

Deployment_Node(plc, "Big Bank plc", "Big Bank plc data center") {

    Deployment_Node(dn, "bigbank-api***\tx8", "Ubuntu 16.04 LTS") {
        Deployment_Node(apache, "Apache Tomcat", "Apache Tomcat 8.x") {
            Container(api, "API Application", "Java and Spring MVC", "Provides Internet Banking functionality via JSON/HTTPS API.")
        }
    }

    Deployment_Node(bigbankdb01,"bigbank-db01", "Ubuntu 16.04 LTS") {
        Deployment_Node(oracle, "Oracle - Primary", "Oracle 12c"){
            ContainerDb(db, "Database", "Relational Database Schema", "Stores user registration, hashed authentication credentials, access logs, etc..")
        }
    }

    Deployment_Node(bigbankdb02,"bigbank-db02", "Ubuntu 16.04 LTS", $tags="fallback") {
        Deployment_Node(oracle2, "Oracle - Secondary", "Oracle 12c", $tags="fallback"){
            ContainerDb(db2, "Database", "Relational Database Schema", "Stores user registration, hashed authentication credentials, access logs, etc..")
        }
    }

    Deployment_Node(bb2, "bigbank-web***\tx4", "Ubuntu 16.04 LTS") {
        Deployment_Node(apache2, "Apache Tomcat", "Apache Tomcat 8.x") {
            Container(web, "Web Application", "Java and Spring MVC", "Delivers the static content and the Internet Banking single page application.")
        }
    }
}

Deployment_Node(mob, "Customer's mobile device", "Apple iOS or Android") {
    Container(mobile, "Mobile App", "Xamarin", "Provides a limited subset of the Internet Banking functionality to customers via their mobile app.")
}

Deployment_Node(comp, "Customer's computer", "Microsoft Windows or Apple macOS") {
    Deployment_Node(browser, "Web Browser", "Google Chrome, Mozilla Firefox, Apple Safari or Microsoft Edge") {
        Container(spa, "Single Page Application", "Javascript and Angular", "Provides all of the Internet Banking functionality to customers via their web browser.")
    }
}

Rel(mobile, api, "Makes API calls to", "json/HTTPS")
Rel(spa, api, "Makes API calls to", "json/HTTPS")
Rel_U(web, spa, "Delivers to the customer's web browser")
Rel(api, db, "Reads from and writes to", "JDBC")
Rel(api, db2, "Reads from and written to", "JDBC", $tags="fallback")
Rel_R(db, db2, "Replicates data to")

SHOW_LEGEND()
@enduml

Deployment Diagram for Internet Banking System - Live

dep diag details
@startuml

!theme cb_div_PRGn_11 from https://raw.githubusercontent.com/mweagle/C4-PlantUML-Themes/main/palettes
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Deployment.puml

AddElementTag("fallback", $bgColor="#D3BC8D")
AddRelTag("fallback", $textColor="#D3BC8D", $lineColor="#2F4F2F")

WithoutPropertyHeader()

' calculated legend is used (activated in last line)
' LAYOUT_WITH_LEGEND()

title Deployment Diagram for Internet Banking System - Live

Deployment_Node(plc, "Live", "Big Bank plc", "Big Bank plc data center") {
    AddProperty("Location", "London and Reading")
    Deployment_Node(dn, "bigbank-api***\tx8", "Ubuntu 16.04 LTS", "A web server residing in the web server farm, accessed via F5 BIG-IP LTMs.") {
        AddProperty("Java Version", "8")
        AddProperty("Xmx", "512M")
        AddProperty("Xms", "1024M")
        Deployment_Node(apache, "Apache Tomcat", "Apache Tomcat 8.x", "An open source Java EE web server.") {
            Container(api, "API Application", "Java and Spring MVC", "Provides Internet Banking functionality via JSON/HTTPS API.")
        }
    }
    AddProperty("Location", "London")
    Deployment_Node(bigbankdb01,"bigbank-db01", "Ubuntu 16.04 LTS", "The primary database server.") {
        Deployment_Node(oracle, "Oracle - Primary", "Oracle 12c", "The primary, live database server."){
            ContainerDb(db, "Database", "Relational Database Schema", "Stores user registration, hashed authentication credentials, access logs, etc..")
        }
    }

    AddProperty("Location", "Reading")
    Deployment_Node(bigbankdb02,"bigbank-db02", "Ubuntu 16.04 LTS", "The secondary database server.", $tags="fallback") {
        Deployment_Node(oracle2, "Oracle - Secondary", "Oracle 12c", "A secondary, standby database server, used for failover purposes only.", $tags="fallback"){
            ContainerDb(db2, "Database", "Relational Database Schema", "Stores user registration, hashed authentication credentials, access logs, etc..")
        }
    }

    AddProperty("Location", "London and Reading")
    Deployment_Node(bb2, "bigbank-web***\tx4", "Ubuntu 16.04 LTS", "A web server residing in the web server farm, accessed via F5 BIG-IP LTMs.") {
        AddProperty("Java Version", "8")
        AddProperty("Xmx", "512M")
        AddProperty("Xms", "1024M")
        Deployment_Node(apache2, "Apache Tomcat", "Apache Tomcat 8.x", "An open source Java EE web server.") {
            Container(web, "Web Application", "Java and Spring MVC", "Delivers the static content and the Internet Banking single page application.")
        }
    }
}

Deployment_Node(mob, "Customer's mobile device", "Apple iOS or Android") {
    Container(mobile, "Mobile App", "Xamarin", "Provides a limited subset of the Internet Banking functionality to customers via their mobile app.")
}

Deployment_Node(comp, "Customer's computer", "Microsoft Windows or Apple macOS") {
    Deployment_Node(browser, "Web Browser", "Google Chrome, Mozilla Firefox, Apple Safari or Microsoft Edge") {
        Container(spa, "Single Page Application", "Javascript and Angular", "Provides all of the Internet Banking functionality to customers via their web browser.")
    }
}

Rel(mobile, api, "Makes API calls to", "json/HTTPS")
Rel(spa, api, "Makes API calls to", "json/HTTPS")
Rel_U(web, spa, "Delivers to the customer's web browser")
Rel_L(web, api, "calls")
Rel(api, db, "Reads from and writes to", "JDBC")
Rel(api, db2, "Reads from and written to", "JDBC", $tags="fallback")
Rel_R(db, db2, "Replicates data to")

SHOW_LEGEND()
@enduml

Container Diagram with Styles

container diag styles
@startuml
!theme cb_div_PRGn_11 from https://raw.githubusercontent.com/mweagle/C4-PlantUML-Themes/main/palettes
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

SHOW_PERSON_OUTLINE()
AddElementTag("backendContainer",$bgColor="#8b008b", $fontColor="white", $shape=EightSidedShape(), $legendText="backend container\height sided")
AddRelTag("async", $lineStyle=DashedLine(), $legendText="dashed line for async")
AddRelTag("sync/async", $lineStyle=DottedLine(), $legendText="dotted line for sync/async")
AddPersonTag("persontag", $fontColor="white", $legendText="Person")

title Container diagram for Internet Banking System

Person(customer, Customer, "A customer of the bank, with personal bank accounts", $tags="persontag")

System_Boundary(c1, "Internet Banking") {
    Container(web_app, "Web Application", "Java, Spring MVC", "Delivers the static content and the Internet Banking SPA")
    Container(spa, "Single-Page App", "Javascript, Angular", "Provides all the Internet banking functionality to customers via their web browser")
    Container(mobile_app, "Mobile App", "C#, Xamarin", "Provides a limited subset of the Internet banking functionality to customers va their mobile device")
    ContainerDb(database, "Database", "SQL database", "Stores user registration information, hashed auth credentials, access logs, etc.")
    Container(backend_api, "API application", "Java, Docker Container", "Provides Internet banking functionality via API", $tags="backendContainer")
}

System_Ext(email_system, "E-Mail System", "The internal Microsoft Exchange system")
System_Ext(banking_system, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

Rel(customer, web_app, "Uses", "HTTPS")
Rel(customer, spa, "Uses", "HTTPS")
Rel(customer, mobile_app, "Uses")

Rel_Neighbor(web_app, spa, "Delivers")
Rel(spa, backend_api, "Uses", "async, JSON/HTTPS", $tags="async")
Rel(mobile_app, backend_api, "Uses", "async, JSON/HTTPS", $tags="async")
Rel_Back_Neighbor(database, backend_api, "Reads from and writes to", "sync, JDBC")

Rel_Back(customer, email_system, "Sends e-mails to")
Rel_Back(email_system, backend_api, "Sends e-mails using", "sync, SMTP")
Rel_Neighbor(backend_api, banking_system, "Uses", "sync/async, XML/HTTPS", $tags="sync/async")

SHOW_LEGEND()

Container Diagram with Icons

container diag icons
@startuml
!theme cb_div_PRGn_11 from https://raw.githubusercontent.com/mweagle/C4-PlantUML-Themes/main/palettes
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
!define DEVICONS https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons
!define FONTAWESOME https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/font-awesome-5
' uncomment the following line and comment the first to use locally
' !include C4_Container.puml
!include DEVICONS/angular.puml
!include DEVICONS/dotnet.puml
!include DEVICONS/java.puml
!include DEVICONS/msql_server.puml
!include FONTAWESOME/server.puml
!include FONTAWESOME/envelope.puml


title Container diagram for Internet Banking System

Person(customer, Customer, "A customer of the bank, with personal bank accounts")

System_Boundary(c1, "Internet Banking") {
    Container(web_app, "Web Application", "Java, Spring MVC", "Delivers the static content and the Internet banking SPA", "java")
    Container(spa, "Single-Page App", "JavaScript, Angular", "Provides all the Internet banking functionality to customers via their web browser", "angular")
    Container(mobile_app, "Mobile App", "C#, Xamarin", "Provides a limited subset of the Internet banking functionality to customers via their mobile device", "dotnet")
    ContainerDb(database, "Database", "SQL Database", "Stores user registration information, hashed auth credentials, access logs, etc.", "mysql_server")
    Container(backend_api, "API Application", "Java, Docker Container", "Provides Internet banking functionality via API", "server")
}

System_Ext(email_system, "E-Mail System", "The internal Microsoft Exchange system", "envelope")
System_Ext(banking_system, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

Rel(customer, web_app, "Uses", "HTTPS")
Rel(customer, spa, "Uses", "HTTPS")
Rel(customer, mobile_app, "Uses")

Rel_Neighbor(web_app, spa, "Delivers")
Rel(spa, backend_api, "Uses", "async, JSON/HTTPS")
Rel(mobile_app, backend_api, "Uses", "async, JSON/HTTPS")
Rel_Back_Neighbor(database, backend_api, "Reads from and writes to", "sync, JDBC")

Rel_Back(customer, email_system, "Sends e-mails to")
Rel_Back(email_system, backend_api, "Sends e-mails using", "sync, SMTP")
Rel_Neighbor(backend_api, banking_system, "Uses", "sync/async, XML/HTTPS")

SHOW_LEGEND()
@enduml

Container Diagram Sample - Message Bus

container msg bus
@startuml
!theme cb_div_PRGn_11 from https://raw.githubusercontent.com/mweagle/C4-PlantUML-Themes/main/palettes
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
!define DEVICONS https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons
!define DEVICONS2 https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons2
!define FONTAWESOME https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/font-awesome-5
!include DEVICONS/angular.puml
!include DEVICONS/dotnet.puml
!include DEVICONS/java.puml
!include DEVICONS/msql_server.puml
!include DEVICONS/ruby.puml
!include DEVICONS2/oracle_original.puml
!include DEVICONS/mysql.puml
!include FONTAWESOME/server.puml
!include FONTAWESOME/bus.puml

AddElementTag("microService", $bgColor="#8b008b", $fontColor="white", $shape=EightSidedShape(),  $legendText="microservice")
AddElementTag("storage", $bgColor="#ffffed", $shape=EightSidedShape(), $legendText="Storage")


SHOW_PERSON_OUTLINE()

Person(customer, Customer, "A customer")

System_Boundary(c1, "Customer Information") {
    Container($alias=app, $label="Customer Application", $techn="Javascript, Angular", $descr="Allows customers to manage their profile", $sprite="angular")
    Container(customer_service, "Customer Service", "Java, Spring Boot", "The point of access for customer information.", $tags="microService", $sprite="java")
    ContainerQueue(message_bus, "Message Bus", "RabbitMQ", "Transport for business events", $sprite="bus")
    Container(reporting_service, "Reporting Service", "Ruby", "Creates normalized data for reporting purposes", $tags='microService', $sprite="ruby")
    Container(audit_service, "Audit Service", "C#/.NET", "Provides organization-wide auditing facilities", $tags="microService", $sprite="ruby")
    ContainerDb(customer_db, "Customer Database", "Oracle 12c", "Stores customer information", $tags="storage",$sprite="oracle_original")
    ContainerDb(reporting_db, "Reporting Database", "MySQL", "Stores a normalized version of all business data for ad hoc reporting purposes", $tags="storage", $sprite="mysql")
    Container(audit_store, "Audit Store", "Event Store", "Stores information about events that have happened.", $tags="storage")
}

Rel_D(customer, app, "Uses", "HTTPS")

Rel_D(app, customer_service, "Updates customer information using", "async, JSON/HTTPS")

Rel_U(customer_service, app, "Sends events to", "WebSocket")
Rel_U(customer_service, message_bus, "Sends customer update events to")
Rel(customer_service, customer_db, "Stores data in", "JDBC")

Rel(message_bus, reporting_service, "Sends customer update events to")
Rel(message_bus, audit_service, "Sends customer update events to")

Rel(reporting_service, reporting_db, "Stores data in")
Rel(audit_service, audit_store, "Stores events in")

Lay_R(reporting_service, audit_service)

SHOW_LEGEND()
@enduml

References