mirror of https://github.com/zulip/zulip.git
docs: Split /production/deployment.html into multiple pages.
- Makes "Deployment options" easier to navigate by splitting the "Reverse proxies" and "System configuration" sections out into dedicated pages. Fixes #28928.
This commit is contained in:
parent
b9c4a8a811
commit
2b95068406
|
@ -6,7 +6,7 @@
|
||||||
# version e.g. to say that something is likely to have changed.
|
# version e.g. to say that something is likely to have changed.
|
||||||
# For more info see: https://www.sphinx-doc.org/en/master/templating.html
|
# For more info see: https://www.sphinx-doc.org/en/master/templating.html
|
||||||
#}
|
#}
|
||||||
{% if pagename in [] and release.endswith('+git') %}
|
{% if pagename in ["production/system-configuration", "production/reverse-proxies"] and release.endswith('+git') %}
|
||||||
{#
|
{#
|
||||||
# This page doesn't exist in the stable documentation yet.
|
# This page doesn't exist in the stable documentation yet.
|
||||||
# This temporary workaround prevents test failures and should be removed after the next release.
|
# This temporary workaround prevents test failures and should be removed after the next release.
|
||||||
|
|
|
@ -345,7 +345,7 @@ _Released 2023-08-25_
|
||||||
- Fixed a bug, introduced in Zulip Server 7.2, when the
|
- Fixed a bug, introduced in Zulip Server 7.2, when the
|
||||||
[email gateway](../production/email-gateway.md)
|
[email gateway](../production/email-gateway.md)
|
||||||
was used in conjunction with a
|
was used in conjunction with a
|
||||||
[reverse proxy](../production/deployment.md#putting-the-zulip-application-behind-a-reverse-proxy).
|
[reverse proxy](../production/reverse-proxies.md).
|
||||||
- Improved the performance of
|
- Improved the performance of
|
||||||
[resolving](https://zulip.com/help/resolve-a-topic) or
|
[resolving](https://zulip.com/help/resolve-a-topic) or
|
||||||
[moving](https://zulip.com/help/move-content-to-another-topic) long topics.
|
[moving](https://zulip.com/help/move-content-to-another-topic) long topics.
|
||||||
|
@ -404,7 +404,7 @@ _Released 2023-07-05_
|
||||||
`X-Forwarded-Proto` is also necessary.
|
`X-Forwarded-Proto` is also necessary.
|
||||||
|
|
||||||
- Removed [reverse proxy][proxies] nginx configuration files when the
|
- Removed [reverse proxy][proxies] nginx configuration files when the
|
||||||
[`loadbalancer.ips`](../production/deployment.md#ips)
|
[`loadbalancer.ips`](../production/system-configuration.md#ips)
|
||||||
setting has been unset.
|
setting has been unset.
|
||||||
- Improved error-handling of scheduled emails, so they cannot attempt infinite
|
- Improved error-handling of scheduled emails, so they cannot attempt infinite
|
||||||
deliveries of a message with no recipients.
|
deliveries of a message with no recipients.
|
||||||
|
@ -422,10 +422,10 @@ _Released 2023-07-05_
|
||||||
[import](https://zulip.com/help/import-from-slack#export-your-slack-data),
|
[import](https://zulip.com/help/import-from-slack#export-your-slack-data),
|
||||||
such as a token having too few permissions.
|
such as a token having too few permissions.
|
||||||
- Added support for IPv6
|
- Added support for IPv6
|
||||||
[nameservers in the nginx configuration](../production/deployment.md#nameserver).
|
[nameservers in the nginx configuration](../production/system-configuration.md#nameserver).
|
||||||
- Updated translations.
|
- Updated translations.
|
||||||
|
|
||||||
[proxies]: ../production/deployment.md#configuring-zulip-to-trust-proxies
|
[proxies]: ../production/reverse-proxies.md#configuring-zulip-to-trust-proxies
|
||||||
|
|
||||||
### Zulip Server 7.1
|
### Zulip Server 7.1
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ _Released 2023-05-31_
|
||||||
- High volume log files like `server.log` are now by default retained
|
- High volume log files like `server.log` are now by default retained
|
||||||
for 14 days, configured via the `access_log_retention_days`
|
for 14 days, configured via the `access_log_retention_days`
|
||||||
[deployment
|
[deployment
|
||||||
option](../production/deployment.md#system-and-deployment-configuration). This
|
option](../production/system-configuration.md). This
|
||||||
replaces a harder to understand size-based algorithm that was not
|
replaces a harder to understand size-based algorithm that was not
|
||||||
easily configurable.
|
easily configurable.
|
||||||
- The URL patterns for
|
- The URL patterns for
|
||||||
|
@ -613,8 +613,8 @@ _Released 2023-05-31_
|
||||||
- Zulip's Twitter preview integration has been disabled due to Twitter
|
- Zulip's Twitter preview integration has been disabled due to Twitter
|
||||||
desupporting the API that it relied on.
|
desupporting the API that it relied on.
|
||||||
|
|
||||||
[reverse-proxy-docs]: ../production/deployment.md#putting-the-zulip-application-behind-a-reverse-proxy
|
[reverse-proxy-docs]: ../production/reverse-proxies.md
|
||||||
[loadbalancer-ips]: ../production/deployment.md#configuring-zulip-to-trust-proxies
|
[loadbalancer-ips]: ../production/reverse-proxies.md#configuring-zulip-to-trust-proxies
|
||||||
|
|
||||||
## Zulip Server 6.x series
|
## Zulip Server 6.x series
|
||||||
|
|
||||||
|
@ -1772,7 +1772,7 @@ _Released 2021-05-13_
|
||||||
codebase with Prettier.
|
codebase with Prettier.
|
||||||
- Migrated testing from CircleCI to GitHub Actions.
|
- Migrated testing from CircleCI to GitHub Actions.
|
||||||
|
|
||||||
[zulip-conf-settings]: ../production/deployment.md#system-and-deployment-configuration
|
[zulip-conf-settings]: ../production/system-configuration.md
|
||||||
|
|
||||||
## Zulip Server 3.x series
|
## Zulip Server 3.x series
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ as well as those mentioned in the
|
||||||
- `--no-overwrite-settings`: This option preserves existing
|
- `--no-overwrite-settings`: This option preserves existing
|
||||||
`/etc/zulip` configuration files.
|
`/etc/zulip` configuration files.
|
||||||
|
|
||||||
[missing-dicts]: #missing_dictionaries
|
[missing-dicts]: system-configuration.md#missing_dictionaries
|
||||||
|
|
||||||
## Installing on an existing server
|
## Installing on an existing server
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ configure that as follows:
|
||||||
We also have documentation for a Zulip server [using HTTP][using-http] for use
|
We also have documentation for a Zulip server [using HTTP][using-http] for use
|
||||||
behind reverse proxies.
|
behind reverse proxies.
|
||||||
|
|
||||||
[using-http]: #configuring-zulip-to-allow-http
|
[using-http]: reverse-proxies.md#configuring-zulip-to-allow-http
|
||||||
|
|
||||||
## Customizing the outgoing HTTP proxy
|
## Customizing the outgoing HTTP proxy
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ In Zulip 4.7 and older, to enable SSRF protection via Smokescreen, you
|
||||||
will need to explicitly add the `zulip::profile::smokescreen` Puppet
|
will need to explicitly add the `zulip::profile::smokescreen` Puppet
|
||||||
class, and configure the `[http_proxy]` block as above.
|
class, and configure the `[http_proxy]` block as above.
|
||||||
|
|
||||||
[proxy.enable_for_camo]: #enable_for_camo
|
[proxy.enable_for_camo]: system-configuration.md#enable_for_camo
|
||||||
[smokescreen]: https://github.com/stripe/smokescreen
|
[smokescreen]: https://github.com/stripe/smokescreen
|
||||||
[smokescreen-acls]: https://github.com/stripe/smokescreen#acls
|
[smokescreen-acls]: https://github.com/stripe/smokescreen#acls
|
||||||
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
||||||
|
@ -367,284 +367,6 @@ some other proxy, you can override this default by setting
|
||||||
|
|
||||||
[s3]: upload-backends.md#s3-backend-configuration
|
[s3]: upload-backends.md#s3-backend-configuration
|
||||||
|
|
||||||
## Putting the Zulip application behind a reverse proxy
|
|
||||||
|
|
||||||
Zulip is designed to support being run behind a reverse proxy server.
|
|
||||||
This section contains notes on the configuration required with
|
|
||||||
variable reverse proxy implementations.
|
|
||||||
|
|
||||||
### Installer options
|
|
||||||
|
|
||||||
If your Zulip server will not be on the public Internet, we recommend,
|
|
||||||
installing with the `--self-signed-cert` option (rather than the
|
|
||||||
`--certbot` option), since Certbot requires the server to be on the
|
|
||||||
public Internet.
|
|
||||||
|
|
||||||
#### Configuring Zulip to allow HTTP
|
|
||||||
|
|
||||||
Zulip requires clients to connect to Zulip servers over the secure
|
|
||||||
HTTPS protocol; the insecure HTTP protocol is not supported. However,
|
|
||||||
we do support using a reverse proxy that speaks HTTPS to clients and
|
|
||||||
connects to the Zulip server over HTTP; this can be secure when the
|
|
||||||
Zulip server is not directly exposed to the public Internet.
|
|
||||||
|
|
||||||
After installing the Zulip server as [described
|
|
||||||
above](#installer-options), you can configure Zulip to accept HTTP
|
|
||||||
requests from a reverse proxy as follows:
|
|
||||||
|
|
||||||
1. Add the following block to `/etc/zulip/zulip.conf`:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[application_server]
|
|
||||||
http_only = true
|
|
||||||
```
|
|
||||||
|
|
||||||
1. As root, run
|
|
||||||
`/home/zulip/deployments/current/scripts/zulip-puppet-apply`. This
|
|
||||||
will convert Zulip's main `nginx` configuration file to allow HTTP
|
|
||||||
instead of HTTPS.
|
|
||||||
|
|
||||||
1. Finally, restart the Zulip server, using
|
|
||||||
`/home/zulip/deployments/current/scripts/restart-server`.
|
|
||||||
|
|
||||||
Note that Zulip must be able to accurately determine if its connection to the
|
|
||||||
client was over HTTPS or not; if you enable `http_only`, it is very important
|
|
||||||
that you correctly configure Zulip to trust the `X-Forwarded-Proto` header from
|
|
||||||
its proxy (see the next section), or clients may see infinite redirects.
|
|
||||||
|
|
||||||
#### Configuring Zulip to trust proxies
|
|
||||||
|
|
||||||
Before placing Zulip behind a reverse proxy, it needs to be configured to trust
|
|
||||||
the client IP addresses that the proxy reports via the `X-Forwarded-For` header,
|
|
||||||
and the protocol reported by the `X-Forwarded-Proto` header. This is important
|
|
||||||
to have accurate IP addresses in server logs, as well as in notification emails
|
|
||||||
which are sent to end users. Zulip doesn't default to trusting all
|
|
||||||
`X-Forwarded-*` headers, because doing so would allow clients to spoof any IP
|
|
||||||
address, and claim connections were over a secure connection when they were not;
|
|
||||||
we specify which IP addresses are the Zulip server's incoming proxies, so we
|
|
||||||
know which `X-Forwarded-*` headers to trust.
|
|
||||||
|
|
||||||
1. Determine the IP addresses of all reverse proxies you are setting up, as seen
|
|
||||||
from the Zulip host. Depending on your network setup, these may not be the
|
|
||||||
same as the public IP addresses of the reverse proxies. These can also be IP
|
|
||||||
address ranges, as expressed in CIDR notation.
|
|
||||||
|
|
||||||
1. Add the following block to `/etc/zulip/zulip.conf`.
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[loadbalancer]
|
|
||||||
# Use the IP addresses you determined above, separated by commas.
|
|
||||||
ips = 192.168.0.100
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Reconfigure Zulip with these settings. As root, run
|
|
||||||
`/home/zulip/deployments/current/scripts/zulip-puppet-apply`. This will
|
|
||||||
adjust Zulip's `nginx` configuration file to accept the `X-Forwarded-For`
|
|
||||||
header when it is sent from one of the reverse proxy IPs.
|
|
||||||
|
|
||||||
1. Finally, restart the Zulip server, using
|
|
||||||
`/home/zulip/deployments/current/scripts/restart-server`.
|
|
||||||
|
|
||||||
### nginx configuration
|
|
||||||
|
|
||||||
Below is a working example of a full nginx configuration. It assumes
|
|
||||||
that your Zulip server sits at `https://10.10.10.10:443`; see
|
|
||||||
[above](#configuring-zulip-to-allow-http) to switch to HTTP.
|
|
||||||
|
|
||||||
1. Follow the instructions to [configure Zulip to trust
|
|
||||||
proxies](#configuring-zulip-to-trust-proxies).
|
|
||||||
|
|
||||||
1. Configure the root `nginx.conf` file. We recommend using
|
|
||||||
`/etc/nginx/nginx.conf` from your Zulip server for our recommended
|
|
||||||
settings. E.g. if you don't set `client_max_body_size`, it won't be
|
|
||||||
possible to upload large files to your Zulip server.
|
|
||||||
|
|
||||||
1. Configure the `nginx` site-specific configuration (in
|
|
||||||
`/etc/nginx/sites-available`) for the Zulip app. The following
|
|
||||||
example is a good starting point:
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
listen [::]:80;
|
|
||||||
location / {
|
|
||||||
return 301 https://$host$request_uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
listen [::]:443 ssl http2;
|
|
||||||
server_name zulip.example.com;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/zulip.example.com/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/zulip.example.com/privkey.pem;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_read_timeout 20m;
|
|
||||||
proxy_pass https://10.10.10.10:443;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Don't forget to update `server_name`, `ssl_certificate`,
|
|
||||||
`ssl_certificate_key` and `proxy_pass` with the appropriate values
|
|
||||||
for your deployment.
|
|
||||||
|
|
||||||
[nginx-proxy-longpolling-config]: https://github.com/zulip/zulip/blob/main/puppet/zulip/files/nginx/zulip-include-common/proxy_longpolling
|
|
||||||
[standalone.pp]: https://github.com/zulip/zulip/blob/main/puppet/zulip/manifests/profile/standalone.pp
|
|
||||||
[zulipchat-puppet]: https://github.com/zulip/zulip/tree/main/puppet/kandra/manifests
|
|
||||||
|
|
||||||
### Apache2 configuration
|
|
||||||
|
|
||||||
Below is a working example of a full Apache2 configuration. It assumes
|
|
||||||
that your Zulip server sits at `https://internal.zulip.hostname:443`.
|
|
||||||
Note that if you wish to use SSL to connect to the Zulip server,
|
|
||||||
Apache requires you use the hostname, not the IP address; see
|
|
||||||
[above](#configuring-zulip-to-allow-http) to switch to HTTP.
|
|
||||||
|
|
||||||
1. Follow the instructions to [configure Zulip to trust
|
|
||||||
proxies](#configuring-zulip-to-trust-proxies).
|
|
||||||
|
|
||||||
1. Set `USE_X_FORWARDED_HOST = True` in `/etc/zulip/settings.py` and
|
|
||||||
restart Zulip.
|
|
||||||
|
|
||||||
1. Enable some required Apache modules:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
a2enmod ssl proxy proxy_http headers rewrite
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Create an Apache2 virtual host configuration file, similar to the
|
|
||||||
following. Place it the appropriate path for your Apache2
|
|
||||||
installation and enable it (E.g. if you use Debian or Ubuntu, then
|
|
||||||
place it in `/etc/apache2/sites-available/zulip.example.com.conf`
|
|
||||||
and then run
|
|
||||||
`a2ensite zulip.example.com && systemctl reload apache2`):
|
|
||||||
|
|
||||||
```apache
|
|
||||||
<VirtualHost *:80>
|
|
||||||
ServerName zulip.example.com
|
|
||||||
RewriteEngine On
|
|
||||||
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
|
|
||||||
</VirtualHost>
|
|
||||||
|
|
||||||
<VirtualHost *:443>
|
|
||||||
ServerName zulip.example.com
|
|
||||||
|
|
||||||
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
|
|
||||||
|
|
||||||
RewriteEngine On
|
|
||||||
RewriteRule /(.*) https://internal.zulip.hostname:443/$1 [P,L]
|
|
||||||
|
|
||||||
<Location />
|
|
||||||
Require all granted
|
|
||||||
ProxyPass https://internal.zulip.hostname:443/ timeout=1200
|
|
||||||
</Location>
|
|
||||||
|
|
||||||
SSLEngine on
|
|
||||||
SSLProxyEngine on
|
|
||||||
SSLCertificateFile /etc/letsencrypt/live/zulip.example.com/fullchain.pem
|
|
||||||
SSLCertificateKeyFile /etc/letsencrypt/live/zulip.example.com/privkey.pem
|
|
||||||
# This file can be found in ~zulip/deployments/current/puppet/zulip/files/nginx/dhparam.pem
|
|
||||||
SSLOpenSSLConfCmd DHParameters "/etc/nginx/dhparam.pem"
|
|
||||||
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
|
|
||||||
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
|
||||||
SSLHonorCipherOrder off
|
|
||||||
SSLSessionTickets off
|
|
||||||
Header set Strict-Transport-Security "max-age=31536000"
|
|
||||||
</VirtualHost>
|
|
||||||
```
|
|
||||||
|
|
||||||
Don't forget to update `ServerName`, `RewriteRule`, `ProxyPass`,
|
|
||||||
`SSLCertificateFile`, and `SSLCertificateKeyFile` as are
|
|
||||||
appropriate for your deployment.
|
|
||||||
|
|
||||||
### HAProxy configuration
|
|
||||||
|
|
||||||
Below is a working example of a HAProxy configuration. It assumes that
|
|
||||||
your Zulip server sits at `https://10.10.10.10:443`; see
|
|
||||||
[above](#configuring-zulip-to-allow-http) to switch to HTTP.
|
|
||||||
|
|
||||||
1. Follow the instructions to [configure Zulip to trust
|
|
||||||
proxies](#configuring-zulip-to-trust-proxies).
|
|
||||||
|
|
||||||
1. Configure HAProxy. The below is a minimal `frontend` and `backend`
|
|
||||||
configuration:
|
|
||||||
|
|
||||||
```text
|
|
||||||
frontend zulip
|
|
||||||
mode http
|
|
||||||
bind *:80
|
|
||||||
bind *:443 ssl crt /etc/ssl/private/zulip-combined.crt
|
|
||||||
http-request redirect scheme https code 301 unless { ssl_fc }
|
|
||||||
http-request set-header X-Forwarded-Proto http unless { ssl_fc }
|
|
||||||
http-request set-header X-Forwarded-Proto https if { ssl_fc }
|
|
||||||
default_backend zulip
|
|
||||||
|
|
||||||
backend zulip
|
|
||||||
mode http
|
|
||||||
timeout server 20m
|
|
||||||
server zulip 10.10.10.10:443 check ssl ca-file /etc/ssl/certs/ca-certificates.crt
|
|
||||||
```
|
|
||||||
|
|
||||||
Don't forget to update `bind *:443 ssl crt` and `server` as is
|
|
||||||
appropriate for your deployment.
|
|
||||||
|
|
||||||
### Other proxies
|
|
||||||
|
|
||||||
If you're using another reverse proxy implementation, there are few
|
|
||||||
things you need to be careful about when configuring it:
|
|
||||||
|
|
||||||
1. Configure your reverse proxy (or proxies) to correctly maintain the
|
|
||||||
`X-Forwarded-For` HTTP header, which is supposed to contain the series
|
|
||||||
of IP addresses the request was forwarded through. Additionally,
|
|
||||||
[configure Zulip to respect the addresses sent by your reverse
|
|
||||||
proxies](#configuring-zulip-to-trust-proxies). You can verify
|
|
||||||
your work by looking at `/var/log/zulip/server.log` and checking it
|
|
||||||
has the actual IP addresses of clients, not the IP address of the
|
|
||||||
proxy server.
|
|
||||||
|
|
||||||
1. Configure your reverse proxy (or proxies) to correctly maintain the
|
|
||||||
`X-Forwarded-Proto` HTTP header, which is supposed to contain either `https`
|
|
||||||
or `http` depending on the connection between your browser and your
|
|
||||||
proxy. This will be used by Django to perform CSRF checks regardless of your
|
|
||||||
connection mechanism from your proxy to Zulip. Note that the proxies _must_
|
|
||||||
set the header, overriding any existing values, not add a new header.
|
|
||||||
|
|
||||||
1. Configure your proxy to pass along the `Host:` header as was sent
|
|
||||||
from the client, not the internal hostname as seen by the proxy.
|
|
||||||
If this is not possible, you can set `USE_X_FORWARDED_HOST = True`
|
|
||||||
in `/etc/zulip/settings.py`, and pass the client's `Host` header to
|
|
||||||
Zulip in an `X-Forwarded-Host` header.
|
|
||||||
|
|
||||||
1. Ensure your proxy doesn't interfere with Zulip's use of
|
|
||||||
long-polling for real-time push from the server to your users'
|
|
||||||
browsers. This [nginx code snippet][nginx-proxy-longpolling-config]
|
|
||||||
does this.
|
|
||||||
|
|
||||||
The key configuration options are, for the `/json/events` and
|
|
||||||
`/api/1/events` endpoints:
|
|
||||||
|
|
||||||
- `proxy_read_timeout 1200;`. It's critical that this be
|
|
||||||
significantly above 60s, but the precise value isn't important.
|
|
||||||
- `proxy_buffering off`. If you don't do this, your `nginx` proxy may
|
|
||||||
return occasional 502 errors to clients using Zulip's events API.
|
|
||||||
|
|
||||||
1. The other tricky failure mode we've seen with `nginx` reverse
|
|
||||||
proxies is that they can load-balance between the IPv4 and IPv6
|
|
||||||
addresses for a given hostname. This can result in mysterious errors
|
|
||||||
that can be quite difficult to debug. Be sure to declare your
|
|
||||||
`upstreams` equivalent in a way that won't do load-balancing
|
|
||||||
unexpectedly (e.g. pointing to a DNS name that you haven't configured
|
|
||||||
with multiple IPs for your Zulip machine; sometimes this happens with
|
|
||||||
IPv6 configuration).
|
|
||||||
|
|
||||||
## PostgreSQL warm standby
|
## PostgreSQL warm standby
|
||||||
|
|
||||||
Zulip's configuration allows for [warm standby database
|
Zulip's configuration allows for [warm standby database
|
||||||
|
@ -673,341 +395,3 @@ If you are using password authentication, you can set a
|
||||||
|
|
||||||
[warm-standby]: https://www.postgresql.org/docs/current/warm-standby.html
|
[warm-standby]: https://www.postgresql.org/docs/current/warm-standby.html
|
||||||
[wal-g]: export-and-import.md#database-only-backup-tools
|
[wal-g]: export-and-import.md#database-only-backup-tools
|
||||||
|
|
||||||
## System and deployment configuration
|
|
||||||
|
|
||||||
The file `/etc/zulip/zulip.conf` is used to configure properties of
|
|
||||||
the system and deployment; `/etc/zulip/settings.py` is used to
|
|
||||||
[configure the application itself](settings.md). The `zulip.conf`
|
|
||||||
sections and settings are described below.
|
|
||||||
|
|
||||||
When a setting refers to "set to true" or "set to false", the values
|
|
||||||
`true` and `false` are canonical, but any of the following values will
|
|
||||||
be considered "true", case-insensitively:
|
|
||||||
|
|
||||||
- 1
|
|
||||||
- y
|
|
||||||
- t
|
|
||||||
- yes
|
|
||||||
- true
|
|
||||||
- enable
|
|
||||||
- enabled
|
|
||||||
|
|
||||||
Any other value (including the empty string) is considered false.
|
|
||||||
|
|
||||||
### `[machine]`
|
|
||||||
|
|
||||||
#### `puppet_classes`
|
|
||||||
|
|
||||||
A comma-separated list of the Puppet classes to install on the server.
|
|
||||||
The most common is **`zulip::profile::standalone`**, used for a
|
|
||||||
stand-alone single-host deployment.
|
|
||||||
[Components](../overview/architecture-overview.md#components) of
|
|
||||||
that include:
|
|
||||||
|
|
||||||
- **`zulip::profile::app_frontend`**
|
|
||||||
- **`zulip::profile::memcached`**
|
|
||||||
- **`zulip::profile::postgresql`**
|
|
||||||
- **`zulip::profile::redis`**
|
|
||||||
- **`zulip::profile::rabbitmq`**
|
|
||||||
|
|
||||||
If you are using a [Apache as a single-sign-on
|
|
||||||
authenticator](authentication-methods.md#apache-based-sso-with-remote_user),
|
|
||||||
you will need to add **`zulip::apache_sso`** to the list.
|
|
||||||
|
|
||||||
#### `pgroonga`
|
|
||||||
|
|
||||||
Set to true if enabling the [multi-language PGroonga search
|
|
||||||
extension](../subsystems/full-text-search.md#multi-language-full-text-search).
|
|
||||||
|
|
||||||
#### `timesync`
|
|
||||||
|
|
||||||
What time synchronization daemon to use; defaults to `chrony`, but also supports
|
|
||||||
`ntpd` and `none`. Installations should not adjust this unless they are aligning
|
|
||||||
with a fleet-wide standard of `ntpd`. `none` is only reasonable in containers
|
|
||||||
like LXC which do not allow adjustment of the clock; a Zulip server will not
|
|
||||||
function correctly without an accurate clock.
|
|
||||||
|
|
||||||
### `[deployment]`
|
|
||||||
|
|
||||||
#### `deploy_options`
|
|
||||||
|
|
||||||
Options passed by `upgrade-zulip` and `upgrade-zulip-from-git` into
|
|
||||||
`upgrade-zulip-stage-2`. These might be any of:
|
|
||||||
|
|
||||||
- **`--skip-puppet`** skips doing Puppet/apt upgrades. The user will need
|
|
||||||
to run `zulip-puppet-apply` manually after the upgrade.
|
|
||||||
- **`--skip-migrations`** skips running database migrations. The
|
|
||||||
user will need to run `./manage.py migrate` manually after the upgrade.
|
|
||||||
- **`--skip-purge-old-deployments`** skips purging old deployments;
|
|
||||||
without it, only deployments with the last two weeks are kept.
|
|
||||||
|
|
||||||
Generally installations will not want to set any of these options; the
|
|
||||||
`--skip-*` options are primarily useful for reducing upgrade downtime
|
|
||||||
for servers that are upgraded frequently by core Zulip developers.
|
|
||||||
|
|
||||||
#### `git_repo_url`
|
|
||||||
|
|
||||||
Default repository URL used when [upgrading from a Git
|
|
||||||
repository](upgrade.md#upgrading-from-a-git-repository).
|
|
||||||
|
|
||||||
### `[application_server]`
|
|
||||||
|
|
||||||
#### `http_only`
|
|
||||||
|
|
||||||
If set to true, [configures Zulip to allow HTTP access][using-http];
|
|
||||||
use if Zulip is deployed behind a reverse proxy that is handling
|
|
||||||
SSL/TLS termination.
|
|
||||||
|
|
||||||
#### `nginx_listen_port`
|
|
||||||
|
|
||||||
Set to the port number if you [prefer to listen on a port other than
|
|
||||||
443](#using-an-alternate-port).
|
|
||||||
|
|
||||||
#### `nginx_worker_connections`
|
|
||||||
|
|
||||||
Adjust the [`worker_connections`][nginx_worker_connections] setting in
|
|
||||||
the nginx server. This defaults to 10000; increasing it allows more
|
|
||||||
concurrent connections per CPU core, at the cost of more memory
|
|
||||||
consumed by NGINX. This number, times the number of CPU cores, should
|
|
||||||
be more than twice the concurrent number of users.
|
|
||||||
|
|
||||||
[nginx_worker_connections]: http://nginx.org/en/docs/ngx_core_module.html#worker_connections
|
|
||||||
|
|
||||||
#### `queue_workers_multiprocess`
|
|
||||||
|
|
||||||
By default, Zulip automatically detects whether the system has enough
|
|
||||||
memory to run Zulip queue processors in the higher-throughput but more
|
|
||||||
multiprocess mode (or to save 1.5GiB of RAM with the multithreaded
|
|
||||||
mode). The calculation is based on whether the system has enough
|
|
||||||
memory (currently 3.5GiB) to run a single-server Zulip installation in
|
|
||||||
the multiprocess mode.
|
|
||||||
|
|
||||||
Set explicitly to true or false to override the automatic
|
|
||||||
calculation. This override is useful both Docker systems (where the
|
|
||||||
above algorithm might see the host's memory, not the container's)
|
|
||||||
and/or when using remote servers for postgres, memcached, redis, and
|
|
||||||
RabbitMQ.
|
|
||||||
|
|
||||||
#### `rolling_restart`
|
|
||||||
|
|
||||||
If set to true, when using `./scripts/restart-server` to restart
|
|
||||||
Zulip, restart the uwsgi processes one-at-a-time, instead of all at
|
|
||||||
once. This decreases the number of 502's served to clients, at the
|
|
||||||
cost of slightly increased memory usage, and the possibility that
|
|
||||||
different requests will be served by different versions of the code.
|
|
||||||
|
|
||||||
#### `service_file_descriptor_limit`
|
|
||||||
|
|
||||||
The number of file descriptors which [Supervisor is configured to allow
|
|
||||||
processes to use][supervisor-minfds]; defaults to 40000. If your Zulip deployment
|
|
||||||
is very large (hundreds of thousands of concurrent users), your Django processes
|
|
||||||
hit this limit and refuse connections to clients. Raising it above this default
|
|
||||||
may require changing system-level limits, particularly if you are using a
|
|
||||||
virtualized environment (e.g. Docker, or Proxmox LXC).
|
|
||||||
|
|
||||||
[supervisor-minfds]: http://supervisord.org/configuration.html?highlight=minfds#supervisord-section-values
|
|
||||||
|
|
||||||
#### `s3_memory_cache_size`
|
|
||||||
|
|
||||||
Used only when the [S3 storage backend][s3-backend] is in use.
|
|
||||||
Controls the in-memory size of the cache _index_; the default is 1MB,
|
|
||||||
which is enough to store about 8 thousand entries.
|
|
||||||
|
|
||||||
#### `s3_disk_cache_size`
|
|
||||||
|
|
||||||
Used only when the [S3 storage backend][s3-backend] is in use.
|
|
||||||
Controls the on-disk size of the cache _contents_; the default is
|
|
||||||
200MB.
|
|
||||||
|
|
||||||
#### `s3_cache_inactive_time`
|
|
||||||
|
|
||||||
Used only when the [S3 storage backend][s3-backend] is in use.
|
|
||||||
Controls the longest amount of time an entry will be cached since last
|
|
||||||
use; the default is 30 days. Since the contents of the cache are
|
|
||||||
immutable, this serves only as a potential additional limit on the
|
|
||||||
size of the contents on disk; `s3_disk_cache_size` is expected to be
|
|
||||||
the primary control for cache sizing.
|
|
||||||
|
|
||||||
#### `nameserver`
|
|
||||||
|
|
||||||
When the [S3 storage backend][s3-backend] is in use, downloads from S3 are
|
|
||||||
proxied from nginx, whose configuration requires an explicit value of a DNS
|
|
||||||
nameserver to resolve the S3 server's hostname. Zulip defaults to using the
|
|
||||||
resolver found in `/etc/resolv.conf`; this setting overrides any value found
|
|
||||||
there.
|
|
||||||
|
|
||||||
[s3-backend]: upload-backends.md
|
|
||||||
|
|
||||||
#### `uwsgi_listen_backlog_limit`
|
|
||||||
|
|
||||||
Override the default uwsgi backlog of 128 connections.
|
|
||||||
|
|
||||||
#### `uwsgi_processes`
|
|
||||||
|
|
||||||
Override the default `uwsgi` (Django) process count of 6 on hosts with
|
|
||||||
more than 3.5GiB of RAM, 4 on hosts with less.
|
|
||||||
|
|
||||||
#### `access_log_retention_days`
|
|
||||||
|
|
||||||
Number of days of access logs to keep, for both nginx and the application.
|
|
||||||
Defaults to 14 days.
|
|
||||||
|
|
||||||
### `[postfix]`
|
|
||||||
|
|
||||||
#### `mailname`
|
|
||||||
|
|
||||||
The hostname that [Postfix should be configured to receive mail
|
|
||||||
at](email-gateway.md#local-delivery-setup), as well as identify itself as for
|
|
||||||
outgoing email.
|
|
||||||
|
|
||||||
### `[postgresql]`
|
|
||||||
|
|
||||||
#### `effective_io_concurrency`
|
|
||||||
|
|
||||||
Override PostgreSQL's [`effective_io_concurrency`
|
|
||||||
setting](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-EFFECTIVE-IO-CONCURRENCY).
|
|
||||||
|
|
||||||
#### `listen_addresses`
|
|
||||||
|
|
||||||
Override PostgreSQL's [`listen_addresses`
|
|
||||||
setting](https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-LISTEN-ADDRESSES).
|
|
||||||
|
|
||||||
#### `random_page_cost`
|
|
||||||
|
|
||||||
Override PostgreSQL's [`random_page_cost`
|
|
||||||
setting](https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-RANDOM-PAGE-COST)
|
|
||||||
|
|
||||||
#### `replication_primary`
|
|
||||||
|
|
||||||
On the [warm standby replicas](#postgresql-warm-standby), set to the
|
|
||||||
hostname of the primary PostgreSQL server that streaming replication
|
|
||||||
should be done from.
|
|
||||||
|
|
||||||
#### `replication_user`
|
|
||||||
|
|
||||||
On the [warm standby replicas](#postgresql-warm-standby), set to the
|
|
||||||
username that the host should authenticate to the primary PostgreSQL
|
|
||||||
server as, for streaming replication. Authentication will be done
|
|
||||||
based on the `pg_hba.conf` file; if you are using password
|
|
||||||
authentication, you can set a `postgresql_replication_password` secret
|
|
||||||
for authentication.
|
|
||||||
|
|
||||||
#### `skip_backups`
|
|
||||||
|
|
||||||
If set to as true value, inhibits the nightly [`wal-g` backups][wal-g] which
|
|
||||||
would be taken on all non-replicated hosts and [all warm standby
|
|
||||||
replicas](#postgresql-warm-standby). This is generally only set if you have
|
|
||||||
multiple warm standby replicas, in order to avoid taking multiple backups, one
|
|
||||||
per replica.
|
|
||||||
|
|
||||||
#### `backups_disk_concurrency`
|
|
||||||
|
|
||||||
Number of concurrent disk reads to use when taking backups. Defaults to 1; you
|
|
||||||
may wish to increase this if you are taking backups on a replica, so can afford
|
|
||||||
to affect other disk I/O, and have an SSD which is good at parallel random
|
|
||||||
reads.
|
|
||||||
|
|
||||||
#### `backups_storage_class`
|
|
||||||
|
|
||||||
What [storage class](https://aws.amazon.com/s3/storage-classes/) to use when
|
|
||||||
uploading database backups. Defaults to `STANDARD`, meaning "[S3
|
|
||||||
standard][s3-standard]", but many deployments will have overall lower costs if
|
|
||||||
"[S3 Standard - Infrequent Access][s3-ia]" is used, via the `STANDARD_IA`
|
|
||||||
value. Also supported is "[S3 Reduced Redundancy][s3-rr]", by setting
|
|
||||||
`REDUCED_REDUNDANCY`, but this is not suggested for production use.
|
|
||||||
|
|
||||||
[s3-standard]: https://aws.amazon.com/s3/storage-classes/#General_purpose
|
|
||||||
[s3-ia]: https://aws.amazon.com/s3/storage-classes/#Infrequent_access
|
|
||||||
[s3-rr]: https://aws.amazon.com/s3/reduced-redundancy/
|
|
||||||
|
|
||||||
#### `missing_dictionaries`
|
|
||||||
|
|
||||||
If set to a true value during initial database creation, uses PostgreSQL's
|
|
||||||
standard `pg_catalog.english` text search configuration, rather than Zulip's
|
|
||||||
improved set of stopwords. Has no effect after initial database construction.
|
|
||||||
|
|
||||||
#### `ssl_ca_file`
|
|
||||||
|
|
||||||
Set to the path to the PEM-encoded certificate authority used to
|
|
||||||
authenticate client connections.
|
|
||||||
|
|
||||||
#### `ssl_cert_file`
|
|
||||||
|
|
||||||
Set to the path to the PEM-encoded public certificate used to secure
|
|
||||||
client connections.
|
|
||||||
|
|
||||||
#### `ssl_key_file`
|
|
||||||
|
|
||||||
Set to the path to the PEM-encoded private key used to secure client
|
|
||||||
connections.
|
|
||||||
|
|
||||||
#### `ssl_mode`
|
|
||||||
|
|
||||||
The mode that should be used to verify the server certificate. The
|
|
||||||
PostgreSQL default is `prefer`, which provides no security benefit; we
|
|
||||||
strongly suggest setting this to `require` or better if you are using
|
|
||||||
certificate authentication. See the [PostgreSQL
|
|
||||||
documentation](https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS)
|
|
||||||
for potential values.
|
|
||||||
|
|
||||||
#### `version`
|
|
||||||
|
|
||||||
The version of PostgreSQL that is in use. Do not set by hand; use the
|
|
||||||
[PostgreSQL upgrade tool](upgrade.md#upgrading-postgresql).
|
|
||||||
|
|
||||||
### `[memcached]`
|
|
||||||
|
|
||||||
#### `memory`
|
|
||||||
|
|
||||||
Override the number of megabytes of memory that memcached should be
|
|
||||||
configured to consume; defaults to 1/8th of the total server memory.
|
|
||||||
|
|
||||||
#### `max_item_size`
|
|
||||||
|
|
||||||
Override the maximum size that an item in memcached can store. This defaults to
|
|
||||||
1m; adjusting it should only be necessary if your Zulip server has organizations
|
|
||||||
which have more than 20k users.
|
|
||||||
|
|
||||||
### `[loadbalancer]`
|
|
||||||
|
|
||||||
#### `ips`
|
|
||||||
|
|
||||||
Comma-separated list of IP addresses or netmasks of external load balancers
|
|
||||||
whose `X-Forwarded-For` and `X-Forwarded-Proto` should be respected. These can
|
|
||||||
be individual IP addresses, or CIDR IP address ranges.
|
|
||||||
|
|
||||||
### `[http_proxy]`
|
|
||||||
|
|
||||||
#### `host`
|
|
||||||
|
|
||||||
The hostname or IP address of an [outgoing HTTP `CONNECT`
|
|
||||||
proxy](#customizing-the-outgoing-http-proxy). Defaults to `localhost`
|
|
||||||
if unspecified.
|
|
||||||
|
|
||||||
#### `port`
|
|
||||||
|
|
||||||
The TCP port of the HTTP `CONNECT` proxy on the host specified above.
|
|
||||||
Defaults to `4750` if unspecified.
|
|
||||||
|
|
||||||
#### `listen_address`
|
|
||||||
|
|
||||||
The IP address that Smokescreen should bind to and listen on.
|
|
||||||
Defaults to `127.0.0.1`.
|
|
||||||
|
|
||||||
#### `enable_for_camo`
|
|
||||||
|
|
||||||
Because Camo includes logic to deny access to private subnets, routing
|
|
||||||
its requests through Smokescreen is generally not necessary. Set to
|
|
||||||
true or false to override the default, which uses the proxy only if
|
|
||||||
it is not the default of Smokescreen on a local host.
|
|
||||||
|
|
||||||
### `[sentry]`
|
|
||||||
|
|
||||||
#### `organization`
|
|
||||||
|
|
||||||
The Sentry organization used for the [Sentry deploy hook](#sentry-deploy-hook).
|
|
||||||
|
|
||||||
#### `project`
|
|
||||||
|
|
||||||
The Sentry project used for the [Sentry deploy hook](#sentry-deploy-hook).
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ using an [HTTP reverse proxy][reverse-proxy]).
|
||||||
|
|
||||||
Congratulations! The integration should be fully operational.
|
Congratulations! The integration should be fully operational.
|
||||||
|
|
||||||
[reverse-proxy]: deployment.md#putting-the-zulip-application-behind-a-reverse-proxy
|
[reverse-proxy]: reverse-proxies.md
|
||||||
|
|
||||||
## Polling setup
|
## Polling setup
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ install
|
||||||
troubleshooting
|
troubleshooting
|
||||||
management-commands
|
management-commands
|
||||||
settings
|
settings
|
||||||
|
system-configuration
|
||||||
mobile-push-notifications
|
mobile-push-notifications
|
||||||
upgrade
|
upgrade
|
||||||
modify
|
modify
|
||||||
|
@ -21,6 +22,7 @@ upload-backends
|
||||||
ssl-certificates
|
ssl-certificates
|
||||||
email
|
email
|
||||||
deployment
|
deployment
|
||||||
|
reverse-proxies
|
||||||
multiple-organizations
|
multiple-organizations
|
||||||
email-gateway
|
email-gateway
|
||||||
video-calls
|
video-calls
|
||||||
|
|
|
@ -119,7 +119,7 @@ access to incoming port 22 for SSH access for remote access.
|
||||||
|
|
||||||
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
||||||
[smokescreen-proxy]: deployment.md#customizing-the-outgoing-http-proxy
|
[smokescreen-proxy]: deployment.md#customizing-the-outgoing-http-proxy
|
||||||
[reverse-proxy]: deployment.md#putting-the-zulip-application-behind-a-reverse-proxy
|
[reverse-proxy]: reverse-proxies.md
|
||||||
|
|
||||||
## Credentials needed
|
## Credentials needed
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,277 @@
|
||||||
|
## Reverse proxies
|
||||||
|
|
||||||
|
Zulip is designed to support being run behind a reverse proxy server.
|
||||||
|
This section contains notes on the configuration required with
|
||||||
|
variable reverse proxy implementations.
|
||||||
|
|
||||||
|
### Installer options
|
||||||
|
|
||||||
|
If your Zulip server will not be on the public Internet, we recommend,
|
||||||
|
installing with the `--self-signed-cert` option (rather than the
|
||||||
|
`--certbot` option), since Certbot requires the server to be on the
|
||||||
|
public Internet.
|
||||||
|
|
||||||
|
#### Configuring Zulip to allow HTTP
|
||||||
|
|
||||||
|
Zulip requires clients to connect to Zulip servers over the secure
|
||||||
|
HTTPS protocol; the insecure HTTP protocol is not supported. However,
|
||||||
|
we do support using a reverse proxy that speaks HTTPS to clients and
|
||||||
|
connects to the Zulip server over HTTP; this can be secure when the
|
||||||
|
Zulip server is not directly exposed to the public Internet.
|
||||||
|
|
||||||
|
After installing the Zulip server as [described
|
||||||
|
above](#installer-options), you can configure Zulip to accept HTTP
|
||||||
|
requests from a reverse proxy as follows:
|
||||||
|
|
||||||
|
1. Add the following block to `/etc/zulip/zulip.conf`:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[application_server]
|
||||||
|
http_only = true
|
||||||
|
```
|
||||||
|
|
||||||
|
1. As root, run
|
||||||
|
`/home/zulip/deployments/current/scripts/zulip-puppet-apply`. This
|
||||||
|
will convert Zulip's main `nginx` configuration file to allow HTTP
|
||||||
|
instead of HTTPS.
|
||||||
|
|
||||||
|
1. Finally, restart the Zulip server, using
|
||||||
|
`/home/zulip/deployments/current/scripts/restart-server`.
|
||||||
|
|
||||||
|
Note that Zulip must be able to accurately determine if its connection to the
|
||||||
|
client was over HTTPS or not; if you enable `http_only`, it is very important
|
||||||
|
that you correctly configure Zulip to trust the `X-Forwarded-Proto` header from
|
||||||
|
its proxy (see the next section), or clients may see infinite redirects.
|
||||||
|
|
||||||
|
#### Configuring Zulip to trust proxies
|
||||||
|
|
||||||
|
Before placing Zulip behind a reverse proxy, it needs to be configured to trust
|
||||||
|
the client IP addresses that the proxy reports via the `X-Forwarded-For` header,
|
||||||
|
and the protocol reported by the `X-Forwarded-Proto` header. This is important
|
||||||
|
to have accurate IP addresses in server logs, as well as in notification emails
|
||||||
|
which are sent to end users. Zulip doesn't default to trusting all
|
||||||
|
`X-Forwarded-*` headers, because doing so would allow clients to spoof any IP
|
||||||
|
address, and claim connections were over a secure connection when they were not;
|
||||||
|
we specify which IP addresses are the Zulip server's incoming proxies, so we
|
||||||
|
know which `X-Forwarded-*` headers to trust.
|
||||||
|
|
||||||
|
1. Determine the IP addresses of all reverse proxies you are setting up, as seen
|
||||||
|
from the Zulip host. Depending on your network setup, these may not be the
|
||||||
|
same as the public IP addresses of the reverse proxies. These can also be IP
|
||||||
|
address ranges, as expressed in CIDR notation.
|
||||||
|
|
||||||
|
1. Add the following block to `/etc/zulip/zulip.conf`.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[loadbalancer]
|
||||||
|
# Use the IP addresses you determined above, separated by commas.
|
||||||
|
ips = 192.168.0.100
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Reconfigure Zulip with these settings. As root, run
|
||||||
|
`/home/zulip/deployments/current/scripts/zulip-puppet-apply`. This will
|
||||||
|
adjust Zulip's `nginx` configuration file to accept the `X-Forwarded-For`
|
||||||
|
header when it is sent from one of the reverse proxy IPs.
|
||||||
|
|
||||||
|
1. Finally, restart the Zulip server, using
|
||||||
|
`/home/zulip/deployments/current/scripts/restart-server`.
|
||||||
|
|
||||||
|
### nginx configuration
|
||||||
|
|
||||||
|
Below is a working example of a full nginx configuration. It assumes
|
||||||
|
that your Zulip server sits at `https://10.10.10.10:443`; see
|
||||||
|
[above](#configuring-zulip-to-allow-http) to switch to HTTP.
|
||||||
|
|
||||||
|
1. Follow the instructions to [configure Zulip to trust
|
||||||
|
proxies](#configuring-zulip-to-trust-proxies).
|
||||||
|
|
||||||
|
1. Configure the root `nginx.conf` file. We recommend using
|
||||||
|
`/etc/nginx/nginx.conf` from your Zulip server for our recommended
|
||||||
|
settings. E.g. if you don't set `client_max_body_size`, it won't be
|
||||||
|
possible to upload large files to your Zulip server.
|
||||||
|
|
||||||
|
1. Configure the `nginx` site-specific configuration (in
|
||||||
|
`/etc/nginx/sites-available`) for the Zulip app. The following
|
||||||
|
example is a good starting point:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
location / {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
server_name zulip.example.com;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/zulip.example.com/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/zulip.example.com/privkey.pem;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_read_timeout 20m;
|
||||||
|
proxy_pass https://10.10.10.10:443;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Don't forget to update `server_name`, `ssl_certificate`,
|
||||||
|
`ssl_certificate_key` and `proxy_pass` with the appropriate values
|
||||||
|
for your deployment.
|
||||||
|
|
||||||
|
[nginx-proxy-longpolling-config]: https://github.com/zulip/zulip/blob/main/puppet/zulip/files/nginx/zulip-include-common/proxy_longpolling
|
||||||
|
[standalone.pp]: https://github.com/zulip/zulip/blob/main/puppet/zulip/manifests/profile/standalone.pp
|
||||||
|
[zulipchat-puppet]: https://github.com/zulip/zulip/tree/main/puppet/kandra/manifests
|
||||||
|
|
||||||
|
### Apache2 configuration
|
||||||
|
|
||||||
|
Below is a working example of a full Apache2 configuration. It assumes
|
||||||
|
that your Zulip server sits at `https://internal.zulip.hostname:443`.
|
||||||
|
Note that if you wish to use SSL to connect to the Zulip server,
|
||||||
|
Apache requires you use the hostname, not the IP address; see
|
||||||
|
[above](#configuring-zulip-to-allow-http) to switch to HTTP.
|
||||||
|
|
||||||
|
1. Follow the instructions to [configure Zulip to trust
|
||||||
|
proxies](#configuring-zulip-to-trust-proxies).
|
||||||
|
|
||||||
|
1. Set `USE_X_FORWARDED_HOST = True` in `/etc/zulip/settings.py` and
|
||||||
|
restart Zulip.
|
||||||
|
|
||||||
|
1. Enable some required Apache modules:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
a2enmod ssl proxy proxy_http headers rewrite
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Create an Apache2 virtual host configuration file, similar to the
|
||||||
|
following. Place it the appropriate path for your Apache2
|
||||||
|
installation and enable it (E.g. if you use Debian or Ubuntu, then
|
||||||
|
place it in `/etc/apache2/sites-available/zulip.example.com.conf`
|
||||||
|
and then run
|
||||||
|
`a2ensite zulip.example.com && systemctl reload apache2`):
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<VirtualHost *:80>
|
||||||
|
ServerName zulip.example.com
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
|
||||||
|
</VirtualHost>
|
||||||
|
|
||||||
|
<VirtualHost *:443>
|
||||||
|
ServerName zulip.example.com
|
||||||
|
|
||||||
|
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
|
||||||
|
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteRule /(.*) https://internal.zulip.hostname:443/$1 [P,L]
|
||||||
|
|
||||||
|
<Location />
|
||||||
|
Require all granted
|
||||||
|
ProxyPass https://internal.zulip.hostname:443/ timeout=1200
|
||||||
|
</Location>
|
||||||
|
|
||||||
|
SSLEngine on
|
||||||
|
SSLProxyEngine on
|
||||||
|
SSLCertificateFile /etc/letsencrypt/live/zulip.example.com/fullchain.pem
|
||||||
|
SSLCertificateKeyFile /etc/letsencrypt/live/zulip.example.com/privkey.pem
|
||||||
|
# This file can be found in ~zulip/deployments/current/puppet/zulip/files/nginx/dhparam.pem
|
||||||
|
SSLOpenSSLConfCmd DHParameters "/etc/nginx/dhparam.pem"
|
||||||
|
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
|
||||||
|
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
||||||
|
SSLHonorCipherOrder off
|
||||||
|
SSLSessionTickets off
|
||||||
|
Header set Strict-Transport-Security "max-age=31536000"
|
||||||
|
</VirtualHost>
|
||||||
|
```
|
||||||
|
|
||||||
|
Don't forget to update `ServerName`, `RewriteRule`, `ProxyPass`,
|
||||||
|
`SSLCertificateFile`, and `SSLCertificateKeyFile` as are
|
||||||
|
appropriate for your deployment.
|
||||||
|
|
||||||
|
### HAProxy configuration
|
||||||
|
|
||||||
|
Below is a working example of a HAProxy configuration. It assumes that
|
||||||
|
your Zulip server sits at `https://10.10.10.10:443`; see
|
||||||
|
[above](#configuring-zulip-to-allow-http) to switch to HTTP.
|
||||||
|
|
||||||
|
1. Follow the instructions to [configure Zulip to trust
|
||||||
|
proxies](#configuring-zulip-to-trust-proxies).
|
||||||
|
|
||||||
|
1. Configure HAProxy. The below is a minimal `frontend` and `backend`
|
||||||
|
configuration:
|
||||||
|
|
||||||
|
```text
|
||||||
|
frontend zulip
|
||||||
|
mode http
|
||||||
|
bind *:80
|
||||||
|
bind *:443 ssl crt /etc/ssl/private/zulip-combined.crt
|
||||||
|
http-request redirect scheme https code 301 unless { ssl_fc }
|
||||||
|
http-request set-header X-Forwarded-Proto http unless { ssl_fc }
|
||||||
|
http-request set-header X-Forwarded-Proto https if { ssl_fc }
|
||||||
|
default_backend zulip
|
||||||
|
|
||||||
|
backend zulip
|
||||||
|
mode http
|
||||||
|
timeout server 20m
|
||||||
|
server zulip 10.10.10.10:443 check ssl ca-file /etc/ssl/certs/ca-certificates.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
Don't forget to update `bind *:443 ssl crt` and `server` as is
|
||||||
|
appropriate for your deployment.
|
||||||
|
|
||||||
|
### Other proxies
|
||||||
|
|
||||||
|
If you're using another reverse proxy implementation, there are few
|
||||||
|
things you need to be careful about when configuring it:
|
||||||
|
|
||||||
|
1. Configure your reverse proxy (or proxies) to correctly maintain the
|
||||||
|
`X-Forwarded-For` HTTP header, which is supposed to contain the series
|
||||||
|
of IP addresses the request was forwarded through. Additionally,
|
||||||
|
[configure Zulip to respect the addresses sent by your reverse
|
||||||
|
proxies](#configuring-zulip-to-trust-proxies). You can verify
|
||||||
|
your work by looking at `/var/log/zulip/server.log` and checking it
|
||||||
|
has the actual IP addresses of clients, not the IP address of the
|
||||||
|
proxy server.
|
||||||
|
|
||||||
|
1. Configure your reverse proxy (or proxies) to correctly maintain the
|
||||||
|
`X-Forwarded-Proto` HTTP header, which is supposed to contain either `https`
|
||||||
|
or `http` depending on the connection between your browser and your
|
||||||
|
proxy. This will be used by Django to perform CSRF checks regardless of your
|
||||||
|
connection mechanism from your proxy to Zulip. Note that the proxies _must_
|
||||||
|
set the header, overriding any existing values, not add a new header.
|
||||||
|
|
||||||
|
1. Configure your proxy to pass along the `Host:` header as was sent
|
||||||
|
from the client, not the internal hostname as seen by the proxy.
|
||||||
|
If this is not possible, you can set `USE_X_FORWARDED_HOST = True`
|
||||||
|
in `/etc/zulip/settings.py`, and pass the client's `Host` header to
|
||||||
|
Zulip in an `X-Forwarded-Host` header.
|
||||||
|
|
||||||
|
1. Ensure your proxy doesn't interfere with Zulip's use of
|
||||||
|
long-polling for real-time push from the server to your users'
|
||||||
|
browsers. This [nginx code snippet][nginx-proxy-longpolling-config]
|
||||||
|
does this.
|
||||||
|
|
||||||
|
The key configuration options are, for the `/json/events` and
|
||||||
|
`/api/1/events` endpoints:
|
||||||
|
|
||||||
|
- `proxy_read_timeout 1200;`. It's critical that this be
|
||||||
|
significantly above 60s, but the precise value isn't important.
|
||||||
|
- `proxy_buffering off`. If you don't do this, your `nginx` proxy may
|
||||||
|
return occasional 502 errors to clients using Zulip's events API.
|
||||||
|
|
||||||
|
1. The other tricky failure mode we've seen with `nginx` reverse
|
||||||
|
proxies is that they can load-balance between the IPv4 and IPv6
|
||||||
|
addresses for a given hostname. This can result in mysterious errors
|
||||||
|
that can be quite difficult to debug. Be sure to declare your
|
||||||
|
`upstreams` equivalent in a way that won't do load-balancing
|
||||||
|
unexpectedly (e.g. pointing to a DNS name that you haven't configured
|
||||||
|
with multiple IPs for your Zulip machine; sometimes this happens with
|
||||||
|
IPv6 configuration).
|
|
@ -260,7 +260,7 @@ strength allowed is controlled by two settings in
|
||||||
[go-camo]: https://github.com/cactus/go-camo
|
[go-camo]: https://github.com/cactus/go-camo
|
||||||
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
||||||
[smokescreen-setup]: deployment.md#customizing-the-outgoing-http-proxy
|
[smokescreen-setup]: deployment.md#customizing-the-outgoing-http-proxy
|
||||||
[proxy.enable_for_camo]: deployment.md#enable_for_camo
|
[proxy.enable_for_camo]: system-configuration.md#enable_for_camo
|
||||||
|
|
||||||
## Rate limiting
|
## Rate limiting
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ to each new major release.
|
||||||
|
|
||||||
Since Zulip’s settings file is a Python script, there are a number of
|
Since Zulip’s settings file is a Python script, there are a number of
|
||||||
other things that one can configure that are documented in
|
other things that one can configure that are documented in
|
||||||
[System and deployment configuration](deployment.md#system-and-deployment-configuration).
|
[System and deployment configuration](system-configuration.md).
|
||||||
Otherwise, ask in [the Zulip development community](https://zulip.com/development-community/)
|
Otherwise, ask in [the Zulip development community](https://zulip.com/development-community/)
|
||||||
if there’s something you’d like to do but can’t figure out how to.
|
if there’s something you’d like to do but can’t figure out how to.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,337 @@
|
||||||
|
## System configuration
|
||||||
|
|
||||||
|
The file `/etc/zulip/zulip.conf` is used to configure properties of
|
||||||
|
the system and deployment; `/etc/zulip/settings.py` is used to
|
||||||
|
[configure the application itself](settings.md). The `zulip.conf`
|
||||||
|
sections and settings are described below.
|
||||||
|
|
||||||
|
When a setting refers to "set to true" or "set to false", the values
|
||||||
|
`true` and `false` are canonical, but any of the following values will
|
||||||
|
be considered "true", case-insensitively:
|
||||||
|
|
||||||
|
- 1
|
||||||
|
- y
|
||||||
|
- t
|
||||||
|
- yes
|
||||||
|
- true
|
||||||
|
- enable
|
||||||
|
- enabled
|
||||||
|
|
||||||
|
Any other value (including the empty string) is considered false.
|
||||||
|
|
||||||
|
### `[machine]`
|
||||||
|
|
||||||
|
#### `puppet_classes`
|
||||||
|
|
||||||
|
A comma-separated list of the Puppet classes to install on the server.
|
||||||
|
The most common is **`zulip::profile::standalone`**, used for a
|
||||||
|
stand-alone single-host deployment.
|
||||||
|
[Components](../overview/architecture-overview.md#components) of
|
||||||
|
that include:
|
||||||
|
|
||||||
|
- **`zulip::profile::app_frontend`**
|
||||||
|
- **`zulip::profile::memcached`**
|
||||||
|
- **`zulip::profile::postgresql`**
|
||||||
|
- **`zulip::profile::redis`**
|
||||||
|
- **`zulip::profile::rabbitmq`**
|
||||||
|
|
||||||
|
If you are using a [Apache as a single-sign-on
|
||||||
|
authenticator](authentication-methods.md#apache-based-sso-with-remote_user),
|
||||||
|
you will need to add **`zulip::apache_sso`** to the list.
|
||||||
|
|
||||||
|
#### `pgroonga`
|
||||||
|
|
||||||
|
Set to true if enabling the [multi-language PGroonga search
|
||||||
|
extension](../subsystems/full-text-search.md#multi-language-full-text-search).
|
||||||
|
|
||||||
|
#### `timesync`
|
||||||
|
|
||||||
|
What time synchronization daemon to use; defaults to `chrony`, but also supports
|
||||||
|
`ntpd` and `none`. Installations should not adjust this unless they are aligning
|
||||||
|
with a fleet-wide standard of `ntpd`. `none` is only reasonable in containers
|
||||||
|
like LXC which do not allow adjustment of the clock; a Zulip server will not
|
||||||
|
function correctly without an accurate clock.
|
||||||
|
|
||||||
|
### `[deployment]`
|
||||||
|
|
||||||
|
#### `deploy_options`
|
||||||
|
|
||||||
|
Options passed by `upgrade-zulip` and `upgrade-zulip-from-git` into
|
||||||
|
`upgrade-zulip-stage-2`. These might be any of:
|
||||||
|
|
||||||
|
- **`--skip-puppet`** skips doing Puppet/apt upgrades. The user will need
|
||||||
|
to run `zulip-puppet-apply` manually after the upgrade.
|
||||||
|
- **`--skip-migrations`** skips running database migrations. The
|
||||||
|
user will need to run `./manage.py migrate` manually after the upgrade.
|
||||||
|
- **`--skip-purge-old-deployments`** skips purging old deployments;
|
||||||
|
without it, only deployments with the last two weeks are kept.
|
||||||
|
|
||||||
|
Generally installations will not want to set any of these options; the
|
||||||
|
`--skip-*` options are primarily useful for reducing upgrade downtime
|
||||||
|
for servers that are upgraded frequently by core Zulip developers.
|
||||||
|
|
||||||
|
#### `git_repo_url`
|
||||||
|
|
||||||
|
Default repository URL used when [upgrading from a Git
|
||||||
|
repository](upgrade.md#upgrading-from-a-git-repository).
|
||||||
|
|
||||||
|
### `[application_server]`
|
||||||
|
|
||||||
|
#### `http_only`
|
||||||
|
|
||||||
|
If set to true, [configures Zulip to allow HTTP access][using-http];
|
||||||
|
use if Zulip is deployed behind a reverse proxy that is handling
|
||||||
|
SSL/TLS termination.
|
||||||
|
|
||||||
|
#### `nginx_listen_port`
|
||||||
|
|
||||||
|
Set to the port number if you [prefer to listen on a port other than
|
||||||
|
443](deployment.md#using-an-alternate-port).
|
||||||
|
|
||||||
|
#### `nginx_worker_connections`
|
||||||
|
|
||||||
|
Adjust the [`worker_connections`][nginx_worker_connections] setting in
|
||||||
|
the nginx server. This defaults to 10000; increasing it allows more
|
||||||
|
concurrent connections per CPU core, at the cost of more memory
|
||||||
|
consumed by NGINX. This number, times the number of CPU cores, should
|
||||||
|
be more than twice the concurrent number of users.
|
||||||
|
|
||||||
|
[nginx_worker_connections]: http://nginx.org/en/docs/ngx_core_module.html#worker_connections
|
||||||
|
|
||||||
|
#### `queue_workers_multiprocess`
|
||||||
|
|
||||||
|
By default, Zulip automatically detects whether the system has enough
|
||||||
|
memory to run Zulip queue processors in the higher-throughput but more
|
||||||
|
multiprocess mode (or to save 1.5GiB of RAM with the multithreaded
|
||||||
|
mode). The calculation is based on whether the system has enough
|
||||||
|
memory (currently 3.5GiB) to run a single-server Zulip installation in
|
||||||
|
the multiprocess mode.
|
||||||
|
|
||||||
|
Set explicitly to true or false to override the automatic
|
||||||
|
calculation. This override is useful both Docker systems (where the
|
||||||
|
above algorithm might see the host's memory, not the container's)
|
||||||
|
and/or when using remote servers for postgres, memcached, redis, and
|
||||||
|
RabbitMQ.
|
||||||
|
|
||||||
|
#### `rolling_restart`
|
||||||
|
|
||||||
|
If set to true, when using `./scripts/restart-server` to restart
|
||||||
|
Zulip, restart the uwsgi processes one-at-a-time, instead of all at
|
||||||
|
once. This decreases the number of 502's served to clients, at the
|
||||||
|
cost of slightly increased memory usage, and the possibility that
|
||||||
|
different requests will be served by different versions of the code.
|
||||||
|
|
||||||
|
#### `service_file_descriptor_limit`
|
||||||
|
|
||||||
|
The number of file descriptors which [Supervisor is configured to allow
|
||||||
|
processes to use][supervisor-minfds]; defaults to 40000. If your Zulip deployment
|
||||||
|
is very large (hundreds of thousands of concurrent users), your Django processes
|
||||||
|
hit this limit and refuse connections to clients. Raising it above this default
|
||||||
|
may require changing system-level limits, particularly if you are using a
|
||||||
|
virtualized environment (e.g. Docker, or Proxmox LXC).
|
||||||
|
|
||||||
|
[supervisor-minfds]: http://supervisord.org/configuration.html?highlight=minfds#supervisord-section-values
|
||||||
|
|
||||||
|
#### `s3_memory_cache_size`
|
||||||
|
|
||||||
|
Used only when the [S3 storage backend][s3-backend] is in use.
|
||||||
|
Controls the in-memory size of the cache _index_; the default is 1MB,
|
||||||
|
which is enough to store about 8 thousand entries.
|
||||||
|
|
||||||
|
#### `s3_disk_cache_size`
|
||||||
|
|
||||||
|
Used only when the [S3 storage backend][s3-backend] is in use.
|
||||||
|
Controls the on-disk size of the cache _contents_; the default is
|
||||||
|
200MB.
|
||||||
|
|
||||||
|
#### `s3_cache_inactive_time`
|
||||||
|
|
||||||
|
Used only when the [S3 storage backend][s3-backend] is in use.
|
||||||
|
Controls the longest amount of time an entry will be cached since last
|
||||||
|
use; the default is 30 days. Since the contents of the cache are
|
||||||
|
immutable, this serves only as a potential additional limit on the
|
||||||
|
size of the contents on disk; `s3_disk_cache_size` is expected to be
|
||||||
|
the primary control for cache sizing.
|
||||||
|
|
||||||
|
#### `nameserver`
|
||||||
|
|
||||||
|
When the [S3 storage backend][s3-backend] is in use, downloads from S3 are
|
||||||
|
proxied from nginx, whose configuration requires an explicit value of a DNS
|
||||||
|
nameserver to resolve the S3 server's hostname. Zulip defaults to using the
|
||||||
|
resolver found in `/etc/resolv.conf`; this setting overrides any value found
|
||||||
|
there.
|
||||||
|
|
||||||
|
[s3-backend]: upload-backends.md
|
||||||
|
|
||||||
|
#### `uwsgi_listen_backlog_limit`
|
||||||
|
|
||||||
|
Override the default uwsgi backlog of 128 connections.
|
||||||
|
|
||||||
|
#### `uwsgi_processes`
|
||||||
|
|
||||||
|
Override the default `uwsgi` (Django) process count of 6 on hosts with
|
||||||
|
more than 3.5GiB of RAM, 4 on hosts with less.
|
||||||
|
|
||||||
|
#### `access_log_retention_days`
|
||||||
|
|
||||||
|
Number of days of access logs to keep, for both nginx and the application.
|
||||||
|
Defaults to 14 days.
|
||||||
|
|
||||||
|
### `[postfix]`
|
||||||
|
|
||||||
|
#### `mailname`
|
||||||
|
|
||||||
|
The hostname that [Postfix should be configured to receive mail
|
||||||
|
at](email-gateway.md#local-delivery-setup), as well as identify itself as for
|
||||||
|
outgoing email.
|
||||||
|
|
||||||
|
### `[postgresql]`
|
||||||
|
|
||||||
|
#### `effective_io_concurrency`
|
||||||
|
|
||||||
|
Override PostgreSQL's [`effective_io_concurrency`
|
||||||
|
setting](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-EFFECTIVE-IO-CONCURRENCY).
|
||||||
|
|
||||||
|
#### `listen_addresses`
|
||||||
|
|
||||||
|
Override PostgreSQL's [`listen_addresses`
|
||||||
|
setting](https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-LISTEN-ADDRESSES).
|
||||||
|
|
||||||
|
#### `random_page_cost`
|
||||||
|
|
||||||
|
Override PostgreSQL's [`random_page_cost`
|
||||||
|
setting](https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-RANDOM-PAGE-COST)
|
||||||
|
|
||||||
|
#### `replication_primary`
|
||||||
|
|
||||||
|
On the [warm standby replicas](deployment.md#postgresql-warm-standby), set to the
|
||||||
|
hostname of the primary PostgreSQL server that streaming replication
|
||||||
|
should be done from.
|
||||||
|
|
||||||
|
#### `replication_user`
|
||||||
|
|
||||||
|
On the [warm standby replicas](deployment.md#postgresql-warm-standby), set to the
|
||||||
|
username that the host should authenticate to the primary PostgreSQL
|
||||||
|
server as, for streaming replication. Authentication will be done
|
||||||
|
based on the `pg_hba.conf` file; if you are using password
|
||||||
|
authentication, you can set a `postgresql_replication_password` secret
|
||||||
|
for authentication.
|
||||||
|
|
||||||
|
#### `skip_backups`
|
||||||
|
|
||||||
|
If set to as true value, inhibits the nightly [`wal-g` backups][wal-g] which
|
||||||
|
would be taken on all non-replicated hosts and [all warm standby
|
||||||
|
replicas](deployment.md#postgresql-warm-standby). This is generally only set if you have
|
||||||
|
multiple warm standby replicas, in order to avoid taking multiple backups, one
|
||||||
|
per replica.
|
||||||
|
|
||||||
|
#### `backups_disk_concurrency`
|
||||||
|
|
||||||
|
Number of concurrent disk reads to use when taking backups. Defaults to 1; you
|
||||||
|
may wish to increase this if you are taking backups on a replica, so can afford
|
||||||
|
to affect other disk I/O, and have an SSD which is good at parallel random
|
||||||
|
reads.
|
||||||
|
|
||||||
|
#### `backups_storage_class`
|
||||||
|
|
||||||
|
What [storage class](https://aws.amazon.com/s3/storage-classes/) to use when
|
||||||
|
uploading database backups. Defaults to `STANDARD`, meaning "[S3
|
||||||
|
standard][s3-standard]", but many deployments will have overall lower costs if
|
||||||
|
"[S3 Standard - Infrequent Access][s3-ia]" is used, via the `STANDARD_IA`
|
||||||
|
value. Also supported is "[S3 Reduced Redundancy][s3-rr]", by setting
|
||||||
|
`REDUCED_REDUNDANCY`, but this is not suggested for production use.
|
||||||
|
|
||||||
|
[s3-standard]: https://aws.amazon.com/s3/storage-classes/#General_purpose
|
||||||
|
[s3-ia]: https://aws.amazon.com/s3/storage-classes/#Infrequent_access
|
||||||
|
[s3-rr]: https://aws.amazon.com/s3/reduced-redundancy/
|
||||||
|
|
||||||
|
#### `missing_dictionaries`
|
||||||
|
|
||||||
|
If set to a true value during initial database creation, uses PostgreSQL's
|
||||||
|
standard `pg_catalog.english` text search configuration, rather than Zulip's
|
||||||
|
improved set of stopwords. Has no effect after initial database construction.
|
||||||
|
|
||||||
|
#### `ssl_ca_file`
|
||||||
|
|
||||||
|
Set to the path to the PEM-encoded certificate authority used to
|
||||||
|
authenticate client connections.
|
||||||
|
|
||||||
|
#### `ssl_cert_file`
|
||||||
|
|
||||||
|
Set to the path to the PEM-encoded public certificate used to secure
|
||||||
|
client connections.
|
||||||
|
|
||||||
|
#### `ssl_key_file`
|
||||||
|
|
||||||
|
Set to the path to the PEM-encoded private key used to secure client
|
||||||
|
connections.
|
||||||
|
|
||||||
|
#### `ssl_mode`
|
||||||
|
|
||||||
|
The mode that should be used to verify the server certificate. The
|
||||||
|
PostgreSQL default is `prefer`, which provides no security benefit; we
|
||||||
|
strongly suggest setting this to `require` or better if you are using
|
||||||
|
certificate authentication. See the [PostgreSQL
|
||||||
|
documentation](https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS)
|
||||||
|
for potential values.
|
||||||
|
|
||||||
|
#### `version`
|
||||||
|
|
||||||
|
The version of PostgreSQL that is in use. Do not set by hand; use the
|
||||||
|
[PostgreSQL upgrade tool](upgrade.md#upgrading-postgresql).
|
||||||
|
|
||||||
|
### `[memcached]`
|
||||||
|
|
||||||
|
#### `memory`
|
||||||
|
|
||||||
|
Override the number of megabytes of memory that memcached should be
|
||||||
|
configured to consume; defaults to 1/8th of the total server memory.
|
||||||
|
|
||||||
|
#### `max_item_size`
|
||||||
|
|
||||||
|
Override the maximum size that an item in memcached can store. This defaults to
|
||||||
|
1m; adjusting it should only be necessary if your Zulip server has organizations
|
||||||
|
which have more than 20k users.
|
||||||
|
|
||||||
|
### `[loadbalancer]`
|
||||||
|
|
||||||
|
#### `ips`
|
||||||
|
|
||||||
|
Comma-separated list of IP addresses or netmasks of external load balancers
|
||||||
|
whose `X-Forwarded-For` and `X-Forwarded-Proto` should be respected. These can
|
||||||
|
be individual IP addresses, or CIDR IP address ranges.
|
||||||
|
|
||||||
|
### `[http_proxy]`
|
||||||
|
|
||||||
|
#### `host`
|
||||||
|
|
||||||
|
The hostname or IP address of an [outgoing HTTP `CONNECT`
|
||||||
|
proxy](deployment.md#customizing-the-outgoing-http-proxy). Defaults to
|
||||||
|
`localhost` if unspecified.
|
||||||
|
|
||||||
|
#### `port`
|
||||||
|
|
||||||
|
The TCP port of the HTTP `CONNECT` proxy on the host specified above.
|
||||||
|
Defaults to `4750` if unspecified.
|
||||||
|
|
||||||
|
#### `listen_address`
|
||||||
|
|
||||||
|
The IP address that Smokescreen should bind to and listen on.
|
||||||
|
Defaults to `127.0.0.1`.
|
||||||
|
|
||||||
|
#### `enable_for_camo`
|
||||||
|
|
||||||
|
Because Camo includes logic to deny access to private subnets, routing
|
||||||
|
its requests through Smokescreen is generally not necessary. Set to
|
||||||
|
true or false to override the default, which uses the proxy only if
|
||||||
|
it is not the default of Smokescreen on a local host.
|
||||||
|
|
||||||
|
### `[sentry]`
|
||||||
|
|
||||||
|
#### `organization`
|
||||||
|
|
||||||
|
The Sentry organization used for the [Sentry deploy hook](deployment.md#sentry-deploy-hook).
|
||||||
|
|
||||||
|
#### `project`
|
||||||
|
|
||||||
|
The Sentry project used for the [Sentry deploy hook](deployment.md#sentry-deploy-hook).
|
|
@ -95,7 +95,7 @@ servers; Zulip defaults this value to the first nameserver found in
|
||||||
will need to run `/home/zulip/deployments/current/scripts/zulip-puppet-apply` to
|
will need to run `/home/zulip/deployments/current/scripts/zulip-puppet-apply` to
|
||||||
update the nginx configuration for the new value.
|
update the nginx configuration for the new value.
|
||||||
|
|
||||||
[s3-resolver]: deployment.md#nameserver
|
[s3-resolver]: system-configuration.md#nameserver
|
||||||
|
|
||||||
## S3 bucket policy
|
## S3 bucket policy
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue