C4 Model for Architecture Documentation One-Pager
- Introduction
- Basics
- The C4 model
- Level 1: System Context Diagram
- Level 2: Container Diagram
- Level 3: Component Diagram
- Level 4 Code-level Diagrams
- Examples
- Container C4 Elements Example
- A basic C4 container example
- Example with sprites and a legend
- Example with links
- Example with custom tags and a calculated legend
- Example showing how to layout elements with relationships
- Example showing how to layout elements without relationships
- System Context Diagram for Internal Banking System
- Container diagram for Internet Banking System
- Component diagram for Internet Banking System - API Application
- System Landscape Diagram
- Dynamic Diagram
- Sequence Diagram
- Deployment Diagram for Internet Banking System - Live
- Deployment Diagram for Internet Banking System - Live
- Container Diagram with Icons
- Container Diagram Sample - Message Bus
- References
Introduction
Diagrams are the maps that help software developers navigate a complex codebase.
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.
-
System Context: A System Context diagram provides a starting point, showing how the software system in scope fits into the world around it.
-
Containers: A Container diagram zooms into the software system in scope, showing the high-level technical building blocks (containers) and how they interact.
-
Components: A Component diagram zooms into an individual container, showing the components inside it.
-
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:
-
What is the software system that we are building (or have built)?
-
Who is using it?
-
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:
-
What is the overall shape of the software system?
-
What are the high-level technology decisions?
-
How are responsibilities distributed across the system?
-
How do containers communicate with one another?
-
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.
-
What components is each container made up of?
-
Do all components have a home (i.e. reside in a container)?
-
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
@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
@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
@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
Example with links
@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
@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
@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
@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
@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
@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
@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
@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
@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
@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
@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
@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
@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
@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