From a9c9fccadf97256130b3c1d075d36490267e9e66 Mon Sep 17 00:00:00 2001 From: Nigini Oliveira Date: Sat, 26 Nov 2022 17:28:59 -0800 Subject: [PATCH 1/2] Improving information about Mastodon's architecture as suggested in issue #1008. --- content/en/dev/overview.md | 27 +++++++++++++++++++++------ static/assets/architecture.png | Bin 0 -> 40958 bytes 2 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 static/assets/architecture.png diff --git a/content/en/dev/overview.md b/content/en/dev/overview.md index a6248643..49831ca4 100644 --- a/content/en/dev/overview.md +++ b/content/en/dev/overview.md @@ -7,15 +7,30 @@ menu: parent: dev --- -{{< hint style="warning" >}} -This page is under construction. -{{< /hint >}} - Mastodon is a Ruby on Rails application with a React.js front-end. It follows standard practices of those frameworks, so if you are already familiar with Rails or React.js, you will not find any surprises here. -The best way of working with Mastodon in a development environment is installing all the dependencies on your system, rather than using Docker or Vagrant. You need Ruby, Node.js, PostgreSQL and Redis, which is a pretty standard set of dependencies for Rails applications. +## Architecture -Tutorials for installing these dependencies can be found on the “Installing from source” page in the Running Mastodon section of the documentation. Please keep in mind that root access to a machine running Ubuntu 18.04 is required. After following the installation guide in the Running Mastodon section, see the “Setting up a dev environment” page for further instruction on how to configure your environment for development. +Mastodon's architecture can be divided in the five sub-systems depicted in the image bellow: + +{{< figure src="/assets/architecture.png" caption="Architectural layout of a Mastodon deployment." >}} + + 1. The web-server, who deals with the incoming HTTP calls from clients; + 2. Mastodon's logic which implements the Tooting functionalities you love; + 3. A job processing system (a.k.a. queuing framework) used by Mastodon's logic to process as needed tasks; + 4. An "operations data system" which keeps needed information handy for quick access; + 5. A persistent data storage system where all those toots and cat photos will be written and read from. + +Because the Mastodon's logic is implemented in Ruby, as of now, all these systems are implemented on or easily integratable in a Ruby project stack. For instance, although one could imagine using any HTTP server or Queue framework, as of now, the default architecture uses [Puma](https://puma.io) and [Sidekiq](https://sidekiq.org), both Ruby libraries that made adding Web call-handling and Job processing conveniently easy to create. + +In terms of data management, Mastodon uses the popular in-memory datastructure storage system [Redis](https://redis.io) which affords super-fast access to vital information like cached toot streams and Sidekiq's queues and its jobs. The final bit, the persistent storage, is accomplished by the [PosgreSQL][https://posgresql.org] for general data, and for media storage, Mastodon can use either a conventional filesystem or an Elastic Storage solution (a.k.a. storage bucket - initially created as the S3 API by Amazon Cloud, but now implemented by most cloud service providers like Google, Azure, or Digital Ocean.). + + +## Development + +The best way of working with Mastodon in a development environment is installing all the dependencies directly on an Ubuntu Server, rather than using Docker or Vagrant. You will need to install all the software describe above -- e.g., Ruby, Node.js, PostgreSQL and Redis -- which is a pretty standard set of dependencies for Rails applications. You may also prefer to install your storage-components in dedicated servers, but there is a conversation for another time. + +Tutorials for installing these dependencies can be found on the “Installing from source” page in the Running Mastodon section of the documentation. Please keep in mind that root access to a machine running Ubuntu (currently on 22.10) is required. After following the installation guide in the Running Mastodon section, see the “Setting up a dev environment” page for further instruction on how to configure your environment for development. ### Environments {#environments} diff --git a/static/assets/architecture.png b/static/assets/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..9699567ae6f721693d6fe70e41d718034cd5d708 GIT binary patch literal 40958 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 Date: Mon, 12 Dec 2022 20:46:58 -0800 Subject: [PATCH 2/2] Small fixes and improvements to the Architecture Overview. --- content/en/dev/overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/dev/overview.md b/content/en/dev/overview.md index 49831ca4..7be040ae 100644 --- a/content/en/dev/overview.md +++ b/content/en/dev/overview.md @@ -13,7 +13,7 @@ Mastodon is a Ruby on Rails application with a React.js front-end. It follows s Mastodon's architecture can be divided in the five sub-systems depicted in the image bellow: -{{< figure src="/assets/architecture.png" caption="Architectural layout of a Mastodon deployment." >}} +{{< figure src="/assets/architecture.png" caption="Architectural layout of Mastodon." >}} 1. The web-server, who deals with the incoming HTTP calls from clients; 2. Mastodon's logic which implements the Tooting functionalities you love; @@ -23,7 +23,7 @@ Mastodon's architecture can be divided in the five sub-systems depicted in the i Because the Mastodon's logic is implemented in Ruby, as of now, all these systems are implemented on or easily integratable in a Ruby project stack. For instance, although one could imagine using any HTTP server or Queue framework, as of now, the default architecture uses [Puma](https://puma.io) and [Sidekiq](https://sidekiq.org), both Ruby libraries that made adding Web call-handling and Job processing conveniently easy to create. -In terms of data management, Mastodon uses the popular in-memory datastructure storage system [Redis](https://redis.io) which affords super-fast access to vital information like cached toot streams and Sidekiq's queues and its jobs. The final bit, the persistent storage, is accomplished by the [PosgreSQL][https://posgresql.org] for general data, and for media storage, Mastodon can use either a conventional filesystem or an Elastic Storage solution (a.k.a. storage bucket - initially created as the S3 API by Amazon Cloud, but now implemented by most cloud service providers like Google, Azure, or Digital Ocean.). +In terms of data management, Mastodon uses the popular in-memory datastructure storage system [Redis](https://redis.io) which affords super-fast access to vital information like cached toot streams and Sidekiq's queues and its jobs. The final bit, the persistent storage, is accomplished by the [PosgreSQL](https://posgresql.org) for general data, and for media storage, Mastodon can use either a conventional filesystem or an Elastic Storage solution (a.k.a. storage bucket - initially created as the [S3 API](https://docs.aws.amazon.com/AmazonS3/latest/API/Type_API_Reference.html) by Amazon Web Services (AWS) and now implemented by most cloud service providers like Google, Azure, or Digital Ocean). ## Development