2021-08-10 07:55:12 +02:00
|
|
|
```{eval-rst}
|
2018-01-23 20:36:07 +01:00
|
|
|
:orphan:
|
|
|
|
```
|
|
|
|
|
2017-08-25 03:56:20 +02:00
|
|
|
# Hosting multiple organizations
|
|
|
|
|
2017-10-20 18:53:33 +02:00
|
|
|
The vast majority of Zulip servers host just a single organization (or
|
2021-08-20 21:53:28 +02:00
|
|
|
"realm", as the Zulip code calls organizations). This article
|
2017-10-20 18:53:33 +02:00
|
|
|
documents what's involved in hosting multiple Zulip organizations on a
|
|
|
|
single server.
|
2017-08-25 03:56:20 +02:00
|
|
|
|
2020-10-23 02:43:28 +02:00
|
|
|
Throughout this article, we'll assume you're working on a Zulip server
|
2021-08-20 21:53:28 +02:00
|
|
|
with hostname `zulip.example.com`. You may also find the more
|
2019-09-30 19:37:56 +02:00
|
|
|
[technically focused article on realms](../subsystems/realms.md) to be useful
|
2017-10-20 18:53:33 +02:00
|
|
|
reading.
|
2017-08-25 03:56:20 +02:00
|
|
|
|
|
|
|
## Subdomains
|
|
|
|
|
|
|
|
Zulip's approach for supporting multiple organizations on a single
|
|
|
|
Zulip server is for each organization to be hosted on its own
|
2021-08-20 21:53:28 +02:00
|
|
|
subdomain. E.g. you'd have `org1.zulip.example.com` and
|
2017-08-25 03:56:20 +02:00
|
|
|
`org2.zulip.example.com`.
|
|
|
|
|
|
|
|
Web security standards mean that one subdomain per organization is
|
2017-12-31 02:11:24 +01:00
|
|
|
required to support a user logging into multiple organizations on a
|
2017-08-25 03:56:20 +02:00
|
|
|
server at the same time.
|
|
|
|
|
|
|
|
When you want to create a new organization, you need to do a few
|
|
|
|
things:
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- If you're using Zulip older than 1.7, you'll need to set
|
2017-08-25 03:56:20 +02:00
|
|
|
`REALMS_HAVE_SUBDOMAINS=True` in your `/etc/zulip/settings.py`
|
2021-08-20 21:53:28 +02:00
|
|
|
file. That setting is the default in 1.7 and later.
|
2021-08-20 21:45:39 +02:00
|
|
|
- Make sure you have SSL certificates for all of the subdomains you're
|
2021-08-20 21:53:28 +02:00
|
|
|
going to use. If you're using
|
2020-10-23 02:43:28 +02:00
|
|
|
[our Let's Encrypt instructions](ssl-certificates.md), it's easy to
|
2017-08-25 03:56:20 +02:00
|
|
|
just specify multiple subdomains in your certificate request.
|
2021-08-20 21:45:39 +02:00
|
|
|
- If necessary, modify your `nginx` configuration to use your new
|
2017-08-25 03:56:20 +02:00
|
|
|
certificates.
|
2021-08-20 21:45:39 +02:00
|
|
|
- Use `./manage.py generate_realm_creation_link` again to create your
|
2021-08-20 21:53:28 +02:00
|
|
|
new organization. Review
|
2019-09-30 19:37:56 +02:00
|
|
|
[the install instructions](install.md) if you need a
|
2017-08-25 03:56:20 +02:00
|
|
|
refresher on how this works.
|
2021-08-20 21:45:39 +02:00
|
|
|
- If you're planning on using GitHub auth or another social
|
2018-07-10 08:07:23 +02:00
|
|
|
authentication method, review
|
2019-12-11 02:33:53 +01:00
|
|
|
[the notes on `SOCIAL_AUTH_SUBDOMAIN` below](#authentication).
|
2017-08-25 03:56:20 +02:00
|
|
|
|
2020-08-11 01:47:54 +02:00
|
|
|
### SSL certificates
|
2018-11-13 21:53:12 +01:00
|
|
|
|
|
|
|
You'll need to install an SSL certificate valid for all the
|
2021-08-20 21:53:28 +02:00
|
|
|
(sub)domains you're using your Zulip server with. You can get an SSL
|
2018-11-13 21:53:12 +01:00
|
|
|
certificate covering several domains for free by using
|
2022-02-16 01:39:15 +01:00
|
|
|
[our Certbot wrapper tool](ssl-certificates.md#after-zulip-is-already-installed),
|
2018-11-13 21:53:12 +01:00
|
|
|
though if you're going to host a large number of organizations, you
|
2021-08-20 21:53:28 +02:00
|
|
|
may want to get a wildcard certificate. You can also get a wildcard
|
2018-11-13 21:53:12 +01:00
|
|
|
certificate for
|
|
|
|
[free using Certbot](https://community.letsencrypt.org/t/getting-wildcard-certificates-with-certbot/56285),
|
|
|
|
but because of the stricter security checks for acquiring a wildcard
|
|
|
|
cert, it isn't possible for a generic script like `setup-certbot` to
|
|
|
|
create it for you; you'll have to do some manual steps with your DNS
|
|
|
|
provider.
|
|
|
|
|
2018-05-16 16:02:13 +02:00
|
|
|
### Other hostnames
|
|
|
|
|
|
|
|
If you'd like to use hostnames that are not subdomains of each other,
|
|
|
|
you can set the `REALM_HOSTS` setting in `/etc/zulip/settings.py` to a
|
|
|
|
Python dictionary, like this:
|
|
|
|
|
2021-08-20 07:09:04 +02:00
|
|
|
```python
|
2018-05-16 16:02:13 +02:00
|
|
|
REALM_HOSTS = {
|
2022-08-17 00:00:53 +02:00
|
|
|
"mysubdomain": "hostname.example.com",
|
2018-05-16 16:02:13 +02:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2022-08-17 00:00:53 +02:00
|
|
|
This will make `hostname.example.com` the hostname for the realm that
|
|
|
|
would, without this configuration, have been
|
|
|
|
`mysubdomain.zulip.example.com`. To create your new realm on
|
|
|
|
`hostname.example.com`, one should enter `mysubdomain` as the
|
|
|
|
"subdomain" for the new realm.
|
|
|
|
|
|
|
|
The value you choose for `mysubdomain` will not be displayed to users;
|
|
|
|
the main constraint is that it will be impossible to create a
|
|
|
|
different realm on `mysubdomain.zulip.example.com`.
|
2018-05-16 16:02:13 +02:00
|
|
|
|
|
|
|
In a future version of Zulip, we expect to move this configuration
|
|
|
|
into the database.
|
|
|
|
|
2017-08-25 03:56:20 +02:00
|
|
|
### The root domain
|
|
|
|
|
|
|
|
Most Zulip servers host a single Zulip organization on the root domain
|
2021-08-20 21:53:28 +02:00
|
|
|
(e.g. `zulip.example.com`). The way this is implemented internally
|
2017-08-25 03:56:20 +02:00
|
|
|
involves the organization having the empty string (`''`) as its
|
2018-05-31 21:17:16 +02:00
|
|
|
"subdomain".
|
|
|
|
|
|
|
|
You can mix having an organization on the root domain and some others
|
|
|
|
on subdomains (e.g. `subdivision.zulip.example.com`), but this only
|
|
|
|
works well if there are no users in common between the two
|
|
|
|
organizations, because the auth cookies for the root domain are
|
|
|
|
visible to the subdomain (so it's not possible for a single
|
2021-08-20 21:53:28 +02:00
|
|
|
browser/client to be logged into both). So we don't recommend that
|
2018-05-31 21:17:16 +02:00
|
|
|
configuration.
|
2017-10-20 18:53:33 +02:00
|
|
|
|
2022-08-17 00:08:01 +02:00
|
|
|
### Changing subdomains
|
|
|
|
|
|
|
|
You can [change the subdomain][help-center-change-url] for an existing
|
|
|
|
organization using a [management command][management-commands]. Be
|
|
|
|
sure you understand the implications of changing the organization URL
|
|
|
|
before doing so, as it can be disruptive to users.
|
|
|
|
|
|
|
|
[management-commands]: ../production/management-commands.md
|
|
|
|
[help-center-change-url]: https://zulip.com/help/change-organization-url
|
|
|
|
|
2019-12-11 01:10:24 +01:00
|
|
|
### Authentication
|
|
|
|
|
|
|
|
Many of Zulip's supported authentication methods (Google, GitHub,
|
|
|
|
SAML, etc.) can require providing the third-party authentication
|
|
|
|
provider with a whitelist of callback URLs to your Zulip server (or
|
2021-08-20 21:53:28 +02:00
|
|
|
even a single URL). For those vendors that support a whitelist, you
|
2019-12-11 01:10:24 +01:00
|
|
|
can provide the callback URLs for each of your Zulip organizations.
|
|
|
|
|
|
|
|
The cleaner solution is to register a special subdomain, e.g.
|
|
|
|
`auth.zulip.example.com` with the third-party provider, and then set
|
|
|
|
`SOCIAL_AUTH_SUBDOMAIN = 'auth'` in `/etc/zulip/settings.py`, so that
|
|
|
|
Zulip knows to use that subdomain for these authentication callbacks.
|
2018-07-10 08:07:23 +02:00
|
|
|
|
2017-10-20 18:53:33 +02:00
|
|
|
### The system bot realm
|
|
|
|
|
|
|
|
This is very much an implementation detail, but worth documenting to
|
|
|
|
avoid confusion as to why there's an extra realm when inspecting the
|
|
|
|
Zulip database.
|
|
|
|
|
|
|
|
Every Zulip server comes with 1 realm that isn't created by users: the
|
2021-08-20 21:53:28 +02:00
|
|
|
`zulipinternal` realm. By default, this realm only contains the Zulip "system
|
|
|
|
bots". You can get a list of these on your system via
|
2017-10-20 18:53:33 +02:00
|
|
|
`./scripts/get-django-setting INTERNAL_BOTS`, but this is where bots
|
2021-08-20 21:53:28 +02:00
|
|
|
like "Notification Bot", "Welcome Bot", etc. exist. In the future,
|
2017-10-20 18:53:33 +02:00
|
|
|
we're considering moving these bots to exist in every realm, so that
|
|
|
|
we wouldn't need the system realm anymore.
|
2018-12-12 21:08:25 +01:00
|
|
|
|
2020-08-11 01:47:54 +02:00
|
|
|
### Migrating / troubleshooting
|
2018-12-12 21:08:25 +01:00
|
|
|
|
|
|
|
If you're migrating from a configuration using the root domain to one
|
|
|
|
with realms hosted on subdomains, be sure to clear cookies in any
|
|
|
|
browsers that were logged in on the root domain; otherwise, those
|
|
|
|
browsers will experience weird/confusing redirects.
|
2022-10-22 23:52:48 +02:00
|
|
|
|
|
|
|
## Open realm creation
|
|
|
|
|
|
|
|
Installations like [Zulip Cloud](https://zulip.com/plans) that wish to
|
|
|
|
allow anyone on the Internet to create new Zulip organizations can do
|
|
|
|
so by setting `OPEN_REALM_CREATION = True` in
|
|
|
|
`/etc/zulip/settings.py`. Note that offering Zulip hosting to anyone
|
|
|
|
on the Internet entails significant responsibility around security,
|
|
|
|
abuse/spam, legal issues like GDPR/CCPA compliance, and more.
|