diff --git a/inventory/groups.yaml b/inventory/groups.yaml
index 4b659bdf64..188184b397 100644
--- a/inventory/groups.yaml
+++ b/inventory/groups.yaml
@@ -63,6 +63,8 @@ groups:
     - graphite*.open*.org
   health:
     - health[0-9]*.openstack.org
+  jvb:
+    - jvb[0-9]*.opendev.org
   kdc:
     - kdc[0-9]*.open*.org
   kubernetes:
diff --git a/playbooks/group_vars/jvb.yaml b/playbooks/group_vars/jvb.yaml
new file mode 100644
index 0000000000..e3ca786f22
--- /dev/null
+++ b/playbooks/group_vars/jvb.yaml
@@ -0,0 +1,3 @@
+meetpad_jvb_xmpp_server: "{{ hostvars['meetpad01.opendev.org'].ansible_host }}"
+iptables_extra_public_udp_ports:
+  - 10000
diff --git a/playbooks/group_vars/meetpad.yaml b/playbooks/group_vars/meetpad.yaml
index e3398eb03b..4b5c5cade6 100644
--- a/playbooks/group_vars/meetpad.yaml
+++ b/playbooks/group_vars/meetpad.yaml
@@ -4,3 +4,5 @@ iptables_extra_public_tcp_ports:
   - 4443
 iptables_extra_public_udp_ports:
   - 10000
+iptables_extra_allowed_groups:
+  - {'protocol': 'tcp', 'port': '5222', 'group': 'jvb'}
diff --git a/playbooks/roles/jitsi-meet/defaults/main.yaml b/playbooks/roles/jitsi-meet/defaults/main.yaml
new file mode 100644
index 0000000000..5a0930507f
--- /dev/null
+++ b/playbooks/roles/jitsi-meet/defaults/main.yaml
@@ -0,0 +1,2 @@
+docker_compose_file: meet-docker-compose.yaml
+docker_compose_env_file: meet-env.j2
diff --git a/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/jvb-docker-compose.yaml b/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/jvb-docker-compose.yaml
new file mode 100644
index 0000000000..d20dd4006c
--- /dev/null
+++ b/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/jvb-docker-compose.yaml
@@ -0,0 +1,26 @@
+# Based on https://github.com/jitsi/docker-jitsi-meet/blob/df404476160526d8512fb23b606965b98f7f25f3/docker-compose.yml
+# Licensed under the ASL v2.
+
+version: '2'
+
+services:
+    # Video bridge
+    jvb:
+        image: docker.io/jitsi/jvb
+        network_mode: host
+        volumes:
+            - ${CONFIG}/jvb:/config
+        environment:
+            - DOCKER_HOST_ADDRESS
+            - XMPP_AUTH_DOMAIN
+            - XMPP_INTERNAL_MUC_DOMAIN
+            - XMPP_SERVER
+            - JVB_AUTH_USER
+            - JVB_AUTH_PASSWORD
+            - JVB_BREWERY_MUC
+            - JVB_PORT
+            - JVB_TCP_HARVESTER_DISABLED
+            - JVB_TCP_PORT
+            - JVB_STUN_SERVERS
+            - JVB_ENABLE_APIS
+            - TZ
diff --git a/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/docker-compose.yaml b/playbooks/roles/jitsi-meet/files/jitsi-meet-docker/meet-docker-compose.yaml
similarity index 100%
rename from playbooks/roles/jitsi-meet/files/jitsi-meet-docker/docker-compose.yaml
rename to playbooks/roles/jitsi-meet/files/jitsi-meet-docker/meet-docker-compose.yaml
diff --git a/playbooks/roles/jitsi-meet/tasks/main.yaml b/playbooks/roles/jitsi-meet/tasks/main.yaml
index 0a1c708bb4..975529e077 100644
--- a/playbooks/roles/jitsi-meet/tasks/main.yaml
+++ b/playbooks/roles/jitsi-meet/tasks/main.yaml
@@ -1,10 +1,20 @@
-- name: Synchronize docker-compose directory
-  synchronize:
-    src: jitsi-meet-docker/
-    dest: /etc/jitsi-meet-docker/
+- name: Create docker-compose dir
+  file:
+    name: /etc/jitsi-meet-docker
+    state: directory
+    mode: 0755
+    owner: root
+    group: root
+- name: Copy docker-compose config
+  copy:
+    src: "jitsi-meet-docker/{{ docker_compose_file }}"
+    dest: /etc/jitsi-meet-docker/docker-compose.yaml
+    mode: 0644
+    owner: root
+    group: root
 - name: Write env file
   template:
-    src: env.j2
+    src: "{{ docker_compose_env_file }}"
     dest: /etc/jitsi-meet-docker/.env
 - name: Ensure jitsi-meet volume directories exist
   file:
diff --git a/playbooks/roles/jitsi-meet/templates/jvb-env.j2 b/playbooks/roles/jitsi-meet/templates/jvb-env.j2
new file mode 100644
index 0000000000..5752cc09b1
--- /dev/null
+++ b/playbooks/roles/jitsi-meet/templates/jvb-env.j2
@@ -0,0 +1,195 @@
+# Based on https://github.com/jitsi/docker-jitsi-meet/blob/df404476160526d8512fb23b606965b98f7f25f3/env.example
+# Licensed under the ASL v2.
+
+# Customized for OpenDev:
+
+# Directory where all configuration will be stored.
+CONFIG=/var/jitsi-meet
+
+# System time zone.
+TZ=Etc/UTC
+
+# Public URL for the web service.
+PUBLIC_URL="https://meetpad.opendev.org"
+
+# Set etherpad-lite URL (uncomment to enable).
+ETHERPAD_URL_BASE=https://etherpad.opendev.org/p/
+
+#
+# Basic configuration options
+#
+
+# IP address of the Docker host. See the "Running on a LAN environment" section
+# in the README.
+#DOCKER_HOST_ADDRESS=192.168.1.1
+
+#
+# Let's Encrypt configuration
+#
+
+# Enable Let's Encrypt certificate generation.
+#ENABLE_LETSENCRYPT=1
+
+# Domain for which to generate the certificate.
+#LETSENCRYPT_DOMAIN=meet.example.com
+
+# E-Mail for receiving important account notifications (mandatory).
+#LETSENCRYPT_EMAIL=alice@atlanta.net
+
+
+#
+# Basic Jigasi configuration options (needed for SIP gateway support)
+#
+
+# SIP URI for incoming / outgoing calls.
+#JIGASI_SIP_URI=test@sip2sip.info
+
+# Password for the specified SIP account as a clear text
+#JIGASI_SIP_PASSWORD=passw0rd
+
+# SIP server (use the SIP account domain if in doubt).
+#JIGASI_SIP_SERVER=sip2sip.info
+
+# SIP server port
+#JIGASI_SIP_PORT=5060
+
+# SIP server transport
+#JIGASI_SIP_TRANSPORT=UDP
+
+#
+# Authentication configuration (see README for details)
+#
+
+# Enable authentication.
+#ENABLE_AUTH=1
+
+# Enable guest access.
+#ENABLE_GUESTS=1
+
+# Select authentication type: internal, jwt or ldap
+#AUTH_TYPE=internal
+
+# JWT auuthentication
+#
+
+# Application identifier.
+#JWT_APP_ID=my_jitsi_app_id
+
+# Application secret known only to your token.
+#JWT_APP_SECRET=my_jitsi_app_secret
+
+# (Optional) Set asap_accepted_issuers as a comma separated list.
+#JWT_ACCEPTED_ISSUERS=my_web_client,my_app_client
+
+# (Optional) Set asap_accepted_audiences as a comma separated list.
+#JWT_ACCEPTED_AUDIENCES=my_server1,my_server2
+
+
+# LDAP authentication (for more information see the Cyrus SASL saslauthd.conf man page)
+#
+
+# LDAP url for connection.
+#LDAP_URL=ldaps://ldap.domain.com/
+
+# LDAP base DN. Can be empty
+#LDAP_BASE=DC=example,DC=domain,DC=com
+
+# LDAP user DN. Do not specify this parameter for the anonymous bind.
+#LDAP_BINDDN=CN=binduser,OU=users,DC=example,DC=domain,DC=com
+
+# LDAP user password. Do not specify this parameter for the anonymous bind.
+#LDAP_BINDPW=LdapUserPassw0rd
+
+# LDAP filter. Tokens example:
+# %1-9 - if the input key is user@mail.domain.com, then %1 is com, %2 is domain and %3 is mail.
+# %s - %s is replaced by the complete service string.
+# %r - %r is replaced by the complete realm string.
+#LDAP_FILTER=(sAMAccountName=%u)
+
+# LDAP authentication method
+#LDAP_AUTH_METHOD=bind
+
+# LDAP version
+#LDAP_VERSION=3
+
+# LDAP TLS using
+#LDAP_USE_TLS=1
+
+# List of SSL/TLS ciphers to allow.
+#LDAP_TLS_CIPHERS=SECURE256:SECURE128:!AES-128-CBC:!ARCFOUR-128:!CAMELLIA-128-CBC:!3DES-CBC:!CAMELLIA-128-CBC
+
+# Require and verify server certificate
+#LDAP_TLS_CHECK_PEER=1
+
+# Path to CA cert file. Used when server sertificate verify is enabled.
+#LDAP_TLS_CACERT_FILE=/etc/ssl/certs/ca-certificates.crt
+
+# Path to CA certs directory. Used when server sertificate verify is enabled.
+#LDAP_TLS_CACERT_DIR=/etc/ssl/certs
+
+# Wether to use starttls, implies LDAPv3 and requires ldap:// instead of ldaps://
+# LDAP_START_TLS=1
+
+
+#
+# Advanced configuration options (you generally don't need to change these)
+#
+
+# Internal XMPP domain.
+XMPP_DOMAIN=localhost
+
+# Internal XMPP server
+XMPP_SERVER={{ meetpad_jvb_xmpp_server }}
+
+# Internal XMPP server URL
+XMPP_BOSH_URL_BASE=http://localhost:5280
+
+# Internal XMPP domain for authenticated services.
+XMPP_AUTH_DOMAIN=auth.localhost
+
+# XMPP domain for the MUC.
+XMPP_MUC_DOMAIN=muc.localhost
+
+# XMPP domain for the internal MUC used for jibri, jigasi and jvb pools.
+XMPP_INTERNAL_MUC_DOMAIN=internal-muc.localhost
+
+# XMPP domain for unauthenticated users.
+XMPP_GUEST_DOMAIN=guest.localhost
+
+# Custom Prosody modules for XMPP_DOMAIN (comma separated)
+XMPP_MODULES=
+
+# Custom Prosody modules for MUC component (comma separated)
+XMPP_MUC_MODULES=
+
+# Custom Prosody modules for internal MUC component (comma separated)
+XMPP_INTERNAL_MUC_MODULES=
+
+# MUC for the JVB pool.
+JVB_BREWERY_MUC=jvbbrewery
+
+# XMPP user for JVB client connections.
+JVB_AUTH_USER=jvb
+
+# XMPP password for JVB client connections.
+JVB_AUTH_PASSWORD={{ meetpad_jvb_auth_password }}
+
+# STUN servers used to discover the server's public IP.
+JVB_STUN_SERVERS=stun.l.google.com:19302,stun1.l.google.com:19302,stun2.l.google.com:19302
+
+# Media port for the Jitsi Videobridge
+JVB_PORT=10000
+
+# TCP Fallback for Jitsi Videobridge for when UDP isn't available
+JVB_TCP_HARVESTER_DISABLED=true
+JVB_TCP_PORT=4443
+
+# A comma separated list of APIs to enable when the JVB is started. The default is none.
+# See https://github.com/jitsi/jitsi-videobridge/blob/master/doc/rest.md for more information
+#JVB_ENABLE_APIS=rest,colibri
+
+# Disable HTTPS. This can be useful if TLS connections are going to be handled outside of this setup.
+#DISABLE_HTTPS=1
+
+# Redirects HTTP traffic to HTTPS. Only works with the standard HTTPS port (443).
+#ENABLE_HTTP_REDIRECT=1
diff --git a/playbooks/roles/jitsi-meet/templates/env.j2 b/playbooks/roles/jitsi-meet/templates/meet-env.j2
similarity index 100%
rename from playbooks/roles/jitsi-meet/templates/env.j2
rename to playbooks/roles/jitsi-meet/templates/meet-env.j2
diff --git a/playbooks/service-meetpad.yaml b/playbooks/service-meetpad.yaml
index e98e801669..63dced8c85 100644
--- a/playbooks/service-meetpad.yaml
+++ b/playbooks/service-meetpad.yaml
@@ -3,3 +3,11 @@
   roles:
     - install-docker
     - jitsi-meet
+
+- hosts: "jvb:!disabled"
+  name: "Configure extra jitsi video bridges"
+  roles:
+    - install-docker
+    - role: jitsi-meet
+      docker_compose_file: jvb-docker-compose.yaml
+      docker_compose_env_file: jvb-env.j2
diff --git a/playbooks/zuul/run-base.yaml b/playbooks/zuul/run-base.yaml
index 66a6b99e28..03dd275781 100644
--- a/playbooks/zuul/run-base.yaml
+++ b/playbooks/zuul/run-base.yaml
@@ -56,6 +56,7 @@
         - group_vars/gitea-lb.yaml
         - group_vars/letsencrypt.yaml
         - group_vars/meetpad.yaml
+        - group_vars/jvb.yaml
         - group_vars/nodepool-launcher.yaml
         - group_vars/registry.yaml
         - group_vars/review.yaml
diff --git a/playbooks/zuul/templates/group_vars/jvb.yaml.j2 b/playbooks/zuul/templates/group_vars/jvb.yaml.j2
new file mode 100644
index 0000000000..06deb123fc
--- /dev/null
+++ b/playbooks/zuul/templates/group_vars/jvb.yaml.j2
@@ -0,0 +1 @@
+meetpad_jvb_auth_password: 8c64807830bcc7581821d3157899e3b0
diff --git a/zuul.d/system-config-run.yaml b/zuul.d/system-config-run.yaml
index b22d1140e9..b96d8bcefa 100644
--- a/zuul.d/system-config-run.yaml
+++ b/zuul.d/system-config-run.yaml
@@ -543,6 +543,8 @@
           label: ubuntu-bionic
         - name: meetpad01.opendev.org
           label: ubuntu-bionic
+        - name: jvb01.opendev.org
+          label: ubuntu-bionic
     vars:
       run_playbooks:
         - playbooks/service-letsencrypt.yaml
@@ -551,6 +553,9 @@
       meetpad01.opendev.org:
         host_copy_output:
           '/var/jitsi-meet': logs
+      jvb01.opendev.org:
+        host_copy_output:
+          '/var/jitsi-meet': logs
     files:
       - playbooks/install-ansible.yaml
       - playbooks/group_vars/meetpad.yaml