How to go about building a multisite installation for multiple different clients

A project of mine, is about creating a “basis” solution for new and small companies, with a low monthly cost for a website.
This means, I will be building a multi site installation, as some might be able to reference back to TYPO3.

A editor will have a number of layout parameters (color, logo, “top menu or side menu”, etc), that will be css variables (think about CSS Garden of Zen - http://www.csszengarden.com/) so one layout, and CSS to manipulate the visual output.
The editor will have 8-10 elements (structural, CTA, common text/image) to work with.
The editor will start with having a “normal page” and “news/blog” content type. With the idea of creating a “product” content type, to later (summer 2022) to be used in a shop functionality.

The keywords for a end users is markup (accessiblity and semantic) and speed that will help and improve SEO, while having few element to work with, so they can create content quickly and focus on there business.
Few entry points for creating content and a easy-to-work-with when the amount of content (pages, news, products) grows

The keywords for me/the integrator is the ease of creating templates along with a possibility for the editors properties (in Neos, it could be properties in the inspector). Easy access to help clients, when they have support questions/issue. Great support for multisite and access restriction, so you only access what site you have access to.

I’m familiar with both TYPO3 and Neos - and it’s those two systems I will be deciding about, to get the project rolling to next phase.

My biggest unknown parts about Neos:

  • The multisite installation support and access restriction of a certain part of sites, without having to add and update Policy.yaml when a new site is created?
  • How to provide support, as a editor on a site, with the same permissions as the client?
  • How does other manage long lists of records/nodetypes, with sorting and filtering?

Have anyone done anything similar, and can share and describe the issues and/or “wauw!“-experiences they had and what way they went on solution, that might touch the same subjects as I’m explaining above.

Please, be brutally honest and still respectful

Please reach out for any questions, I’m very open to explain further.

Hi @sorenmalling

I was also thinking about this idea more than once, but never explored it further…

Access Policies
I think you would either have to extend the User to be able to set accessible nodes or add a property to the root node type of the site to define the users that have edit access to the node.
And in both cases you need to add a new Node Privilege Matcher, because the default matchers can’t handle that…
https://docs.neos.io/cms/manual/backend-permissions/node-privileges
or may be someone already published that as a package, I just didn’t stumble upon it by now…

same permissions as the client
this is an easy one, use the package unikka/login-as

long lists of records/nodetypes
I’m not sure what you meant with this question, but you might want to have a look at flowpack/listable

Hi @sorenmalling,

i think the biggest issue in Neos is the access policy. Right now you need to update the Policy.yaml for each new Site you created, because (as @till.kleisli already mentioned) there is no Privilege Matcher that can handle such stuff yet. But this would be a big plus for Neos i think. If we would have such Matcher, i think there should be a backend module to link users to sites or sth. like that.

For long lists i would also recommend flowpack/listable in combination with ElasticSearch.

Hey @sorenmalling,

tl;dr Neos is not multi-tenant capable at all.

I just faced a similar task. The customer company consists of several sub-companies and also a lot of micro sites. And we move more and more of these sites over to Neos and the customers building blocks.

  • Some of the sites use the “default” template - some of them use adjusted colors / fonts / iconsets …
  • They have several hundreds of editors, each should have different access rights on different sites (read here, write there …)
  • They should not be able to use all of the assets of the other sites (for licencing reasons …)

I started to write a site privilege target to restrict site access, and AOPed into the site listing and UI BackendController to hide unaccessible sites, implemented restrictions on Asset Collections, implemented entity restrictions on Redirect records …

That didn’t felt right at all - as you have to target every feature of Neos separately and differently (History, Assets, Sites, Redirects, Users, Form Persistence, Workspaces …)

Neos is not multi-tenant capable at all and even with nearly unlimited customer budget it does not seem to be doable right without fundamentally changing the core.

After some brainstorming with @bwaidelich, I gave up, removed the hacks again. Our solution now looks as follows:

  • We have a single installation for all sites
  • We use separate databases for every tenant
  • Every tenant can still have multiple domains (but with same access schemes)
  • The configuration for different databases (and other things like API credentials, …) is read from individual .env files (https://github.com/punktDe/dotenv-adapter)
  • We use separate contexts for setting adjustments that could not be done with .env
  • We use an IDP and openIdConnect to manage the backend user (https://github.com/flownative/flow-openidconnect-client)

That feels way better now, scales pretty decent and is definitely much more secure than adding restrictions for every part separately.

Maybe that could be a solution for your case as well.

Cheers,
Daniel

Hey @sorenmalling,

I think in general there are two solution directions:

  1. try to make it work inside Neos. This way, you get the policy troubles, etc etc. https://github.com/sandstorm/NeosAcl might be of help here, as it creates dynamic policies. Also check the section " Internal Implementation Details" in there, which explains what workarounds are needed for completely dynamic policies. However this only deals with nodes, you’d also need to take care of the other things mentioned by Daniel - which is a pretty deep rabbit hole I think. And I am also not sure whether we should actually support this.
  2. Do it outside Neos, but using the primitives Neos provides, i.e. by using one database + one application context per tenant. Pretty similar to what @daniellienert described.

My preference would be option 2 instead of 1, as I feel this is a lot cleaner regarding the separation of tenants. I would automate my way around this solution, f.e. to do node migrations in every tenant via a shell script; or other ./flow CLI calls.

IMHO, I’d love to recommend option 2 “officially” and also see whether we can add stuff to the docs explaining this approach; or have a helper package which acts as “glue” between the contexts.

Regarding lots of records, if they are modelled as Nodes, we have used https://github.com/psmb/Psmb.FlatNav/ successfully for lots of data. Previously, we’ve also used https://github.com/sandstorm/CrudForms ( :wink: ) but right now I would actually love to rewrite this some point in the future and base it on Fusion and Neos.Fusion.Form (any takers? :wink: )

All the best,
Sebastian

Officially supporting multi context installations is a great idea. Sounds like the cleanest path to multi tenant Neos.

We would need to establish a single source of truth for all possible contexts and a cli command to execute flow-commands for all or some specific contexts. Tagging would be nice to specify subsets of contexts.

1 Like

Actually a rewrite of crudForms with Fusion is on my “want to do” list… :slight_smile:

1 Like

Do it, do it :slight_smile: :slight_smile: :slight_smile: (In case you need input or want to discuss things, ping me on Slack :slight_smile: )

1 Like