# Run Mattermost and Jitsi behind one HTTPS proxy

> Use chat.example.com for Mattermost and meet.example.com for Jitsi, both pointing to the same server. Let a host-installed Caddy own ports 80 and 443 and manage HTTPS. Bind Mattermost to 127.0.0.1:8065 and Jitsi web to 127.0.0.1:8000. Jitsi media still needs direct UDP 10000 access. One proxy can manage both certificates; copying certificate files between the apps is unnecessary.

Source: https://jitsi.help/guides/mattermost-jitsi-docker-shared-https/
Updated: October 13, 2026
Publisher: Jitsi Help (https://jitsi.help/)

This guide is for administrators connecting two existing Docker deployments on one Ubuntu or Debian server, including a DigitalOcean Droplet. The result is two HTTPS hostnames with one certificate manager. Mattermost's database and Jitsi's internal services remain in their own Compose projects.

## Before changing the proxy

- Have a working Mattermost Docker installation, its database and persistent volumes, following the [official container deployment guide](https://docs.mattermost.com/deployment-guide/server/deploy-containers). [S1]
- Have a working Jitsi installation with generated internal passwords. Use matching Compose files and image tags. The example below uses docker-jitsi-meet `stable-11248`, released September 14, 2026. Its web container uses internal HTTP port `8000`. [S2]
- Use Docker Compose 2.24.4 or newer: the port replacement below uses `!override`. [S3]
- Install Caddy on the host using its [official package instructions](https://caddyserver.com/docs/install#debian-ubuntu-raspbian). The paths and service commands below assume that package. [S4]
- Back up both `.env` files, Compose overrides and the existing proxy configuration. Schedule a maintenance window when moving an existing service off ports 80/443.

Choose VM resources for Mattermost, PostgreSQL and Jitsi together, including concurrent meetings. A Jitsi-only sizing recommendation is not a capacity estimate for the combined server.

Use these placeholders throughout:

| Placeholder | Replace with |
| --- | --- |
| `chat.example.com` | Your Mattermost hostname |
| `meet.example.com` | Your Jitsi hostname |
| `203.0.113.10` | The Droplet's reachable public IP, not its private VPC IP |
| `/opt/mattermost` | Your existing Mattermost Compose directory |
| `/opt/jitsi-meet` | Your existing Jitsi Compose directory |

## 1. Give each app its own hostname

Point both DNS A records to the server's public IPv4 address. Only publish AAAA records if IPv6 also reaches the correct server. Caddy's automatic HTTPS needs reachable domains and certificate-validation traffic. [S5]

In the DigitalOcean Cloud Firewall and the host firewall, permit TCP 80/443 for HTTPS and certificate validation, and UDP 10000 for Jitsi media. Restrict SSH to the administrators who need it. Keep the database and HTTP backends private. Cloud Firewall rules and the host firewall both need to agree. [S6][S2]

The traffic paths will be:

```text
chat.example.com -> Caddy on the host -> 127.0.0.1:8065 -> Mattermost
meet.example.com -> Caddy on the host -> 127.0.0.1:8000 -> Jitsi web
Jitsi media     -> public IP, UDP 10000               -> Jitsi Videobridge
```

## 2. Bind Mattermost's HTTP backend to loopback

In the existing Mattermost `.env`, set its public URL:

```dotenv
DOMAIN=chat.example.com
MM_SERVICESETTINGS_SITEURL=https://chat.example.com
```

Keep the existing database credentials and image version. The official Mattermost base Compose file includes the application and PostgreSQL, and passes `MM_SERVICESETTINGS_SITEURL` to the application. [S7]

Save this as `/opt/mattermost/compose.proxy.yml`:

```yaml
services:
  mattermost:
    ports: !override
      - "127.0.0.1:8065:8065"
```

Run the base file with this override:

```bash
cd /opt/mattermost
docker compose -f docker-compose.yml -f compose.proxy.yml config --quiet
docker compose -f docker-compose.yml -f compose.proxy.yml up -d
curl -I http://127.0.0.1:8065/
```

Use this same file list for subsequent `up`, `ps` and `logs` commands. This replaces the bundled Nginx or without-Nginx file list for the proxy arrangement shown here. If a previous Nginx container still owns 80/443, stop that specific proxy in the maintenance window; preserve application and database volumes. The official Mattermost proxy guide recommends restricting port 8065 to the proxy. [S1][S8]

This example serves Mattermost chat and the Jitsi integration. Mattermost's separate Calls feature has its own media-network requirements; enabling it needs additional configuration.

## 3. Put Jitsi web behind the same host proxy

In Jitsi's existing `.env`, use:

```dotenv
JITSI_IMAGE_VERSION=stable-11248
PUBLIC_URL=https://meet.example.com
HTTP_PORT=8000
DISABLE_HTTPS=1
ENABLE_LETSENCRYPT=0
ENABLE_HTTP_REDIRECT=0
JVB_ADVERTISE_IPS=203.0.113.10
```

Use these values with the Compose file from the same Jitsi release. If your installation is on an older release, follow the [upgrade guide](/guides/upgrade-jitsi-docker-rootless/) first; changing the image tag alone is not an upgrade procedure. Preserve generated internal passwords. [S2]

Save `/opt/jitsi-meet/compose.proxy.yml`:

```yaml
services:
  web:
    ports: !override
      - "127.0.0.1:8000:8000"
```

`!override` replaces the base web port list instead of adding another binding. The videobridge's UDP port remains in the base file. The Jitsi handbook documents disabling internal HTTPS behind a same-host proxy and keeping web ports off public interfaces. [S3][S9]

```bash
cd /opt/jitsi-meet
docker compose -f docker-compose.yml -f compose.proxy.yml config --quiet
docker compose -f docker-compose.yml -f compose.proxy.yml up -d
curl -I http://127.0.0.1:8000/
```

For a fresh Jitsi setup, complete the [Docker installation prerequisites](/guides/install-jitsi-docker/) before applying this proxy arrangement.

## 4. Let Caddy manage HTTPS for both domains

Merge these site blocks into `/etc/caddy/Caddyfile`, preserving any other sites the proxy serves:

```caddyfile
chat.example.com {
    reverse_proxy 127.0.0.1:8065
}

meet.example.com {
    reverse_proxy 127.0.0.1:8000
}
```

Caddy's `reverse_proxy` supports WebSocket upgrades, including Mattermost's WebSocket endpoint and Jitsi's `/xmpp-websocket` route. Automatic HTTPS manages certificates for the configured hostnames and HTTP-to-HTTPS redirects. You do not need to mount either app's certificate files into the other. [S5][S10]

```bash
sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo systemctl enable --now caddy
sudo systemctl reload caddy
sudo journalctl -u caddy --since "10 minutes ago" --no-pager
```

Use Caddy's packaged service for this arrangement. Reload during the maintenance window: existing WebSocket connections can close on a configuration reload. Review the certificate and upstream messages in the service log. [S4][S10][S11]

A certificate must cover every hostname using it. Sharing one certificate file would require coverage for both names and a coordinated renewal process. One proxy managing the hostnames is sufficient; this example does not require a shared wildcard certificate. [S5]

## 5. Connect the Mattermost Jitsi plugin

Install the community Jitsi plugin from its [official repository](https://github.com/mattermost-community/mattermost-plugin-jitsi), then configure its Jitsi server URL as `https://meet.example.com`. Follow the [Mattermost integration settings](/guides/jitsi-integrations-mattermost-rocketchat-nextcloud-moodle/#mattermost) for plugin options. [S12]

HTTPS is transport protection. Decide separately who can create rooms and join them. If your Jitsi server requires JWT, configure the plugin's app ID and secret to match that server and verify room access. See [Jitsi JWT authentication](/guides/jitsi-jwt-authentication/). Keep signing secrets out of browser code and support screenshots.

## Verify web, signaling and media separately

1. Open both HTTPS URLs. Check that the certificate matches each hostname, Mattermost loads its login page and Jitsi loads its preview.
2. Sign in to Mattermost and check its browser Network panel for the WebSocket connection. A successful upgrade uses HTTP 101. [S8]
3. Start a Jitsi meeting from the plugin. Check `/xmpp-websocket` for a successful WebSocket connection, or the configured BOSH signaling flow if WebSockets are intentionally disabled. [S9]
4. Run a three-person meeting, including a guest on a different network. Check two-way audio, video and screen sharing. Successful HTTPS alone does not validate videobridge connectivity. [S2]
5. Test the chosen password, lobby or token rules with a separate guest session. Save sanitized results and recheck after upgrades.

These are verification steps for your deployment. Our publication checks validate the example configuration syntax, not a live Mattermost/Jitsi meeting or a load test.

## Troubleshooting and rollback

| Symptom | Next check |
| --- | --- |
| Proxy cannot bind 80/443 | Identify the old proxy or container still publishing those ports before starting Caddy. |
| Caddy returns 502 | Test the corresponding loopback URL and check the application's Compose logs using the same file list. |
| Certificate issuance fails | Check DNS, any published AAAA record and firewall access, then read Caddy's certificate error. [S5] |
| Chat loads but real-time updates fail | Check Mattermost's public Site URL and WebSocket connection. [S8] |
| Jitsi disconnects before joining | Check signaling with [the disconnection checklist](/troubleshooting/jitsi-you-have-been-disconnected/). |
| Two-person calls work but larger calls fail | Check the advertised public IP, UDP path and [videobridge troubleshooting](/troubleshooting/jitsi-video-not-working-3-participants/). |
| Caddy is in Docker and localhost fails | This example runs Caddy on the host. A container proxy needs reachable service names on shared Docker networks. |

If a proxy migration fails, restore the saved proxy configuration, `.env` files and previous Compose file lists, then re-create the affected services in the maintenance window. Preserve database and application volumes. Review this guide when Jitsi's internal ports, Mattermost's Compose layout or Caddy's proxy behavior changes.

## Sources and scope

Researched October 13, 2026. This is a configuration guide for existing deployments. Jitsi examples are pinned to `stable-11248`; Mattermost's Docker layout was checked at commit `497414659ee7127677d2b91b44bb4f3ea9d14695`. Keep your own application versions pinned and supported. It is not an assertion of a tested production integration or capacity guarantee.

- [S1] [Mattermost container deployment](https://docs.mattermost.com/deployment-guide/server/deploy-containers), official documentation.
- [S2] [docker-jitsi-meet stable-11248 Compose](https://github.com/jitsi/docker-jitsi-meet/blob/stable-11248/docker-compose.yml), [environment example](https://github.com/jitsi/docker-jitsi-meet/blob/stable-11248/env.example) and [release](https://github.com/jitsi/docker-jitsi-meet/releases/tag/stable-11248), official source.
- [S3] [Docker Compose merge and override rules](https://docs.docker.com/reference/compose-file/merge/), including the 2.24.4 requirement, official documentation.
- [S4] [Caddy package installation](https://caddyserver.com/docs/install#debian-ubuntu-raspbian), official documentation.
- [S5] [Caddy automatic HTTPS](https://caddyserver.com/docs/automatic-https), official documentation.
- [S6] [DigitalOcean firewall rules](https://docs.digitalocean.com/products/networking/firewalls/how-to/configure-rules/), official documentation.
- [S7] [Mattermost Compose](https://github.com/mattermost/docker/blob/497414659ee7127677d2b91b44bb4f3ea9d14695/docker-compose.yml) and [environment file](https://github.com/mattermost/docker/blob/497414659ee7127677d2b91b44bb4f3ea9d14695/env.example), official source snapshot.
- [S8] [Mattermost reverse proxy configuration](https://docs.mattermost.com/deployment-guide/server/setup-nginx-proxy), official documentation.
- [S9] [Jitsi Docker reverse proxy guidance](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker/#running-behind-a-reverse-proxy), official documentation.
- [S10] [Caddy reverse_proxy](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy), official documentation.
- [S11] [Caddy service management](https://caddyserver.com/docs/running#using-the-service), official documentation.
- [S12] [Mattermost community Jitsi plugin](https://github.com/mattermost-community/mattermost-plugin-jitsi), official project source.

## Frequently asked questions

### Can Mattermost and Jitsi share an SSL certificate?

A certificate must cover each hostname using it. A single proxy can manage HTTPS for both apps, so they do not need copies of each other's certificate files. In this example Caddy manages certificates for chat.example.com and meet.example.com.

### Why does localhost fail when Caddy is in Docker?

Inside a Caddy container, 127.0.0.1 is that container, not the host or another container. This guide runs Caddy on the host. A container-based proxy needs a shared Docker network and service names instead.

### Does HTTPS make Jitsi audio and video work?

HTTPS covers the web app and signaling. The videobridge also needs its advertised public IP and direct media connectivity, normally UDP 10000. Test a three-person meeting after setting up HTTPS.


---

Jitsi Help is an independent service. It is not affiliated with, endorsed by or sponsored by 8x8, Inc. or the Jitsi project. Jitsi and Jitsi Meet are trademarks of 8x8, Inc., used here only to describe the software we host and support.
