Compare commits

9 Commits

120 changed files with 6350 additions and 288 deletions
+19 -6
View File
@@ -7,7 +7,7 @@ DOMAIN=bigbluebutton.example.com
## Domain aliases
#EXTRA_DOMAINS=', `www.bigbluebutton.example.com`'
PUBLIC_IPV4=
PUBLIC_IPV4=195.201.196.39
LETS_ENCRYPT_ENV=production
@@ -16,20 +16,33 @@ SECRET_SHARED_SECRET_VERSION=v1
SECRET_RAILS_SECRET_VERSION=v1
SECRET_TURN_SECRET_VERSION=v1
SECRET_FSESL_PASSWORD_VERSION=v1
SECRET_HASURA_ADMIN_SECRET_VERSION=v1
ETHERPAD_API_KEY_VERSION=v1
ENTRYPOINT_GREENLIGHT_VERSION=v1
ENTRYPOINT_COTURN_VERSION=v1
TURNSERVER_CONF_VERSION=v1
BBBHTML5_CONF_VERSION=v1
ENTRYPOINT_APPSAKKA_VERSION=v1
ENTRYPOINT_FSESLAKKA_VERSION=v1
ENTRYPOINT_WEBRTCSFU_VERSION=v1
MONGOD_CONF_VERSION=v1
INIT_REPLICA_VERSION=v1
ENTRYPOINT_GRAPHQLSERVER_VERSION=v1
INITDB_SH_VERSION=v1
ENTRYPOINT_BBBPADS_VERSION=v1
ENTRYPOINT_ETHERPAD_VERSION=v1
ENTRYPOINT_FREESWITCH_VERSION=v1
ENTRYPOINT_BBBWEB_VERSION=v1
WS_CONF_VERSION=v1
WN_CONF_VERSION=v1
WSN_CONF_VERSION=v1
NGINX_CONF_VERSION=v1
BRF_CONF_VERSION=v1
BHDN_CONF_VERSION=v1
BEG_CONF_VERSION=v1
AA_CONF_VERSION=v1
PRES_CONF_VERSION=v1
DEMO_CONF_VERSION=v1
FREESWITCH_EX_VERSION=v1
# ====================================
# ADDITIONS to BigBlueButton
@@ -87,7 +100,7 @@ ENABLE_GREENLIGHT=true
# CONNECTION
# ====================================
EXTERNAL_IPv4=
EXTERNAL_IPv4=0.0.0.0
# EXTERNAL_IPv6=2010
# STUN SERVER
@@ -103,7 +116,7 @@ STUN_PORT=3478
# due to high traffic caused by bots, by default the SIP port is blocked.
# but you can allow access by your providers IP or IP ranges (comma seperated)
# Hint: if you want to allow requests from every IP, you can use 0.0.0.0/0
SIP_IP_ALLOWLIST=
SIP_IP_ALLOWLIST=0.0.0.0/0
# ====================================
# CUSTOMIZATION
@@ -120,7 +133,7 @@ WELCOME_FOOTER="This server is running <a href='https://docs.bigbluebutton.org/'
# for a different default presentation, place the pdf file in ./conf/ and
# adjust the following path
DEFAULT_PRESENTATION=./mod/nginx/default.pdf
DEFAULT_PRESENTATION=/etc/nginx/bbb/default.pdf
# language of sound announcements
# options:
+3
View File
@@ -0,0 +1,3 @@
# Set any config versions here
# Docs: https://docs.coopcloud.tech/maintainers/handbook/#manage-configs
export APP_ENTRYPOINT_VERSION=v1
+4
View File
@@ -0,0 +1,4 @@
# this file equals the /etc/bigbluebutton/bbb-html5.yml file referenced in the docs
public:
app:
appName: BigBlueButton HTML5 Client (docker)
+32
View File
@@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFfzCCA2egAwIBAgIURu7kezJgCtWhxm4WNaQLr35BQSIwDQYJKoZIhvcNAQEL
BQAwTzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkdBMRUwEwYDVQQHDAxEZWZhdWx0
IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMjYwNDE0MTk1
NjI4WhcNMjcwNDE0MTk1NjI4WjBPMQswCQYDVQQGEwJVUzELMAkGA1UECAwCR0Ex
FTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55
IEx0ZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYAfc7Rj7jYqRFC
DwymWnxPqxmmEoS9qKSAETEJLkMuozGMu2lc501YPv73ifua8xUmFEJybHQnBoTv
jYk7E9brGOJh2u5CB3WqRxMB7GWXjRvyvV1gGGwdMWwWjJG2d1Zp5WHLHv1kD57c
dbzbscGPK8tg3SL28UXHnzOGMmOH3TnpiAo+0NXOnB29rJOoz5dVp2Q0tAwMiqBg
2V9rwdyJdtJiW23rJWl0TJwdvXbNuhj9RBZSwP1JnQJPhSM31ZRtXOZhOzFCDfDV
N0Rs5ePnqEz9LoufugC5GYUfm06dukHtn5eCLFHV4VUk4FI/ks9IePmbQYvuUfno
OPxF8zsqnS6kYbvqAZkISqpP13UCoa7cy7iYlH3GPLiA4S8/Dt/z1LpvCv19Gi3Z
FJ7gP+T1a0zORkPCk234ALNJ9uD8D1pmE9YIEyZ2qW7vQdwyohjIwi7DBpZldMD9
8rOHL7clax9Dwgol71L+a/6UV4WRnkXmNQAIlzIgEnyCfFSmrzH0fz2hOeEgkJkG
d3Y9Inx3559vsFHMso8ZmJzY4RYTObPzKx4FtDPv3Lm99J/5GZqweH57pj9vdm2n
JSa4XTePrj/HCY3oI+EsfFVTy6tT4uMFW8fzwTFCbsvL8VcvL6tNOD9hF92Nb+wA
acepiKYtYiBlmO0xx2mdCT4FS2xbAgMBAAGjUzBRMB0GA1UdDgQWBBRUluyVxMzb
HdZjsA46ZI2xNvc2zzAfBgNVHSMEGDAWgBRUluyVxMzbHdZjsA46ZI2xNvc2zzAP
BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCVde12/Z5SNOb6rH0T
3y16or0atLQxll/s9xK813635rZ1KJUTVGsQ4Eu7b/NhFWXhL5/IkhSbET0W5zm2
jpEp5Bc407D3Wzd2cnH91Bw6jPX50E4+z6os0AdGFI2dxUZLc3MvLGixjP2BGYH9
WWuAGrDpWVxnT8bz3A0CFBc4hiJ7DWh1kwDGqA8Kd23Q2HT2fzXff6lX6IWKGnZQ
irvLfMYTlG1juhmHJzSwUgHZRIh0JNbdyewx2HXM2WcGWKZCp87JgWquI44gXtrq
7JErnFGXraYRxQX/gLZyO1OVuj40E10ouUZJdByPH/zyQHoQ3yyYFBiqvMFSIZ8t
gteN+6dHXTxmFDVw5/Cbt0SY+z89kU9DlGYotoToXmLNMJP9ePAOvqxzSm+F1bjo
Lewr7VArjY+jWDicRE8RME16aBWXKn7MB7dEphATMWfVRhA+Mg9Al3gbLHgYAmQj
jBmwrMXvZY/Z6DyouvzOc1J5elgpGBeI/Ns5XBEl6NlyLFOnWYNfObzl1IlPWLym
aEqBxaiz0TxP1KzG1HpqpBVzPKwRujU7ysVcIhC/GtcALJKf8nB59DnUY+atOS6B
N/bb2R8qn02AVdaqZaZHj6BVkanI3fs4oCuzhH+JsvjQWzisbeS0REZyBBpyP06o
yBRR5CvFgLdbPdTza8lkvHg/Xg==
-----END CERTIFICATE-----
+54
View File
@@ -0,0 +1,54 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIJtTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQvHeSSSq8RGcMNqpn
8EEiogICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEPy3kvUZhgfhnFYE
NQk4x3cEgglQgQtktEu85J0FpIfVShO3oPR50LdyLo4FUtJzRfWZGsUljr1TAKbo
XHI8PykISGlAsE29NeiH6h5PEMEvf9IIV31DWaM73OKhwsDA4OpR9Nj+uJ8brV7l
9jSNrg7qnUzVmHq/8OdPL8JRAtxrZTsxkCCffR4htT6kSLnAfrYPq9yYZxvQviXy
6kuAr1cI0pm9Y2KiX9CYdk2PdxNV7iblP2QYeiSP/AUjI5T1fmgtw9WE9kZ3aJsU
CxKHTF39zYptOw9rfwxYfIPJniD2F4sTd4ypeAzgRAJZOZMNj43jJZ2FQTjXRMxO
swKURjUyqunvCmo/mX8e9yR3gHieeGLa6+6Ar+P13YQ+5mPSA+ClBu6iF+m+dHNn
lzMggUABPfih1cuUBA0HhHSBtCLHCy4D3WqGkRMWMKotPXv2MEvqZlc78JTpoEpO
m6DL9lywUaa85p4dD6j4fXW2vz9cTH5M0S1JJkn8lHSOz3REMpky0LFKAGeGt7mM
VnekyVrQ27ygGHNMkyHYXDM/4Fx9eWw0wXR6UKgvp5MSnR8IzcrLlthn8Nwxr1jR
eL+a3oULntPRqgl5gA/n4rCzx4UjQf3ZF8Tf+YIko8pL3LpeF4SNJ0s3mLYO1oIh
Hhv7KodwFlKhTAD8qpp8doG9TRJ7tnlDwJYUHP5pPG4UEWKyFo7SAKUIMz81Tw8i
yB+FMKd3v2pIIYmfRDmVSOzPpqeq4HoAp2ane79i67K9gtkdsofCD56Q/j+pPFbE
sUYEs2UmPXumfFuPZsZqrQAKl5j05/+grV3kFgIstUAzywbtDsWzVroQZ6UNCW83
HdzEqpGy1YMorxk99InSMBWxv2E+LcAvyIUxcgLVs1bdzlGP8fOnD3u2jWudQCo8
EQRVbF0/XQYiyiozspQYaC1RMebg8snllYzNuzqdJKzRwqYmx2uGQG2xnVqMyB5c
sVD2QykK2JBwxMkmQy2WVMhXWI/UplsSmr4ddAY0EdZNfYl70aLXO/g9JRN8Isil
bMt2HChqiGTskXJOm7X7m8DD/aSmCdAsRQTadvyZxU4t0G0lyplq0JLDTxPGM+Lq
zwzZlRGX/CWdCJCmZt3GqF0oZUg7CvuQBP6XbQJCmobDmSyjfaxOQ/gdHxEtsLbL
JOuueX4Woo7sHSKkZOaDduKDzf8R29WLJiqoku4Yg4DvQrv20xoG7ys3HovPRy19
nKG6sV2k3WjI3hYHSBXvBBhqb1WvUI4/gwNsN58WNYI4fimoV9g+KXavMeP/Db1Z
5Qrc9pfUQLCJT1XQgYYbyQfTX1oYYqsRsW3xWfQoVUlt7CxkCHzxzG7fo/NbuelU
i7PeGF6AwAJ7bNQRaZzWHNT08ZRcVEIZPDGGuSWyavyFckiDYn2xCPBmTTBHogdX
sCNfZx+DBlm5Tj+vdOLYXbdWGahidTCQ3z34uM9IfJ+0Yxiz9IxAnVmRoz4ckQeE
jIVKCb8AApQLh4hkfNRFT/uyiWV6y/FGRO82IU0vY4FcMihHN59dou86cdXxoCeT
yiMAn6H0WNQ59CdHd7hCg0xrrh8UPF5FDNuTGvosekJbKm45nYGcc8loPNcZztW7
W5YCAnVEnaGr6kVVfGeViTuyTDMeu6gQBEJ6Xx9gtrYxUQBcELe0sUPjEqyhflIw
X6rrqD8+YZyPkP5rSCxOquV1Yh8zdeayXGXi673wrPRFMF0H9DE4AxwJoJVU4akn
Hr7n3iF/WtqxOfuxo/uH+u0D5n2Kz+8EBS2I0K1RzmuPfdx0E6mcOYqUio/FixWr
JBnuWSLtnKrmuA0czFq49/0mHMDtZQHjOHpPUFca1pjV6JIpKah/GuqIyoeb6ULq
Bb3eI+Zls6BvTxjp7Owhd4yKx8dBq3t5dVuFAnxSTInV130c/lOaGX9xBkAnKNk3
gDwC4KhfD+iJkJP+HoQ0Z6mzfVWMLQp8JFrrTnDm+EFzYNjNqbDluYp+UO6rVNb+
34TWRg15lrHYJbUHySYXycMpa4ChsWerMnfv1oBQ5LvqVoEgRYUGzUcAlAFrVXmg
M+fwK5/PDij5cHh8quHTtffAw+PwGLqht9z24ZsY1AHnhlQpde4avXMH0LFIgfZZ
GTOFE29L/xmdFXeOSZyTZAT4JDImXfTewbAu0GIMR20c10UDhB7N/x+SY3vrmGk1
iY0i8SA/f65dn3onF8QFBd1dnSR8oe7byQ8NvePoQSFIfHmwgvWMVbKS//4AgyaQ
puPu/mvBzRvWk2s2VAaXz6xVpXv1/FWsNdBm+Si10QJRuN+Hwpyt+proJf4TCEZ9
L17H/sLt6DJIYbdYVsD8p12MJmFZDLnOuOS0jtSlLEq1DX8p8wevuyuNacppg2em
CCFi8fMNGxStEPPg3iL6e7W41GjM3+ux3cSR9s0FVaW1BBgQaGqBQYfDgKmSs6CO
DHnAMsu4vsayexUEplLbUgW+/ae2gu7ZJXUCuaunaGPP/gk3K5JQiq3X38AY00hF
F3/l2ro5r4Z6BuTujq+9ui9zPER6Em4jugsIXuHSwPgiLgoDBwZ1mm0cuAe3ocEO
K5PSHvS7a8ZrRevkt/3ZggDfWzeUCu9f6JEebUOtGYoemA8rhM8xf81lky34njQT
R88L+m9pt212135rygB0PehZmY1JeUmcwIyJInHZcFIX+Ya7ae4EBr39mztNmzlb
UAcYuHH8O2v7WoIdUbw+/iGcgq7VgkV3GjAlsuvtCOY9i3JXTGBDVgsPrUwuBUSa
qdQ3oE3MrBRa+UW9E1jyeAswCK+8t4K2ndYJKF20j7aPRD3OGVDzSB/elbhbGLrv
LDC/uzz3Eaf/pu7Vdae4CW8Mv/SIDzlVGAKeEvGJ3SB0sRvXQlaB+RsEN0TrtAE8
JlDCuhKhJpBpgzZQ/NBh0F7BWF5XClPZBWx+USkD5zS8JB3lArns7fb17hSLf5gR
GDhjB0giQcCtTBs+FW6WCr/+B/dAkCrNnssErBvZfrciAvt2mk7YT2lyZRG1Y9yh
DD2M6uSz4CKifbLaDcnhM49KimkL9YzB3CR9XQ5JeH1dU8RJgbWLOTfKIzro60c0
1oWCMMZRQRe2tMbKRmIMhycsv2Ftcj+5K0MYO5AZltKYa+a6TjvIVunREJZ3smnv
4rUaF8BP0cwJ4mItNPGCVgQFqn5FnK0Ncq4zPu6JNKeAcqX2uaOxBAQ=
-----END ENCRYPTED PRIVATE KEY-----
+552
View File
@@ -0,0 +1,552 @@
# auto generated by ./scripts/generate-compose
# don't edit this directly.
services:
bbb-web:
build:
context: mod/bbb-web
additional_contexts:
- src-web=./repos/bigbluebutton/bigbluebutton-web
- src-common-message=./repos/bigbluebutton/bbb-common-message
- src-common-web=./repos/bigbluebutton/bbb-common-web
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-web:v3.0.19
restart: unless-stopped
depends_on:
- redis
- etherpad
- bbb-pads
- collabora
healthcheck:
test: wget --no-proxy --no-verbose --tries=1 --spider http://10.7.7.2:8090/bigbluebutton/api || exit 1
start_period: 2m
environment:
IGNORE_TLS_CERT_ERRORS: false
DOMAIN: ${DOMAIN}
ENABLE_RECORDING: ${ENABLE_RECORDING:-false}
SHARED_SECRET: ${SHARED_SECRET}
WELCOME_MESSAGE: ${WELCOME_MESSAGE:-}
WELCOME_FOOTER: ${WELCOME_FOOTER}
STUN_SERVER: stun:${STUN_IP}:${STUN_PORT}
ENABLE_HTTPS_PROXY: ${ENABLE_HTTPS_PROXY:-false}
TURN_SECRET: ${TURN_SECRET:-}
TURN_EXT_SERVER: ${TURN_EXT_SERVER:-}
TURN_EXT_SECRET: ${TURN_EXT_SECRET:-}
ENABLE_LEARNING_DASHBOARD: ${ENABLE_LEARNING_DASHBOARD:-true}
COLLABORA_URL: ${COLLABORA_URL:-https://collabora:9980/cool}
# volumes:
# - ./data/bigbluebutton:/var/bigbluebutton
# - ./data/freeswitch-meetings:/var/freeswitch/meetings
# - type: bind
# source: ./fairblue.js
# target: /var/www/bigbluebutton-default/assets/plugins/fairblue/fairblue.js
# - type: bind
# source: ./manifest.json
# target: /var/www/bigbluebutton-default/assets/plugins/fairblue/manifest.json
configs:
- source: bbb_web_plugin_config
target: /etc/bigbluebutton/bbb-web.properties.tmpl
volumes:
- ./bbb-release:/etc/bigbluebutton/bigbluebutton-release
networks:
bbb-net:
ipv4_address: 10.7.7.2
freeswitch:
container_name: bbb-freeswitch
build:
context: mod/freeswitch
additional_contexts:
- freeswitch=./repos/freeswitch/
- build-files=./repos/bigbluebutton/build/packages-template/bbb-freeswitch-core/
- fs-config=./repos/bigbluebutton/bbb-voice-conference/config/freeswitch/conf/
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-freeswitch:v1.10.12-v3.0.19
restart: unless-stopped
cap_add:
- IPC_LOCK
- NET_ADMIN
- NET_RAW
- NET_BROADCAST
- SYS_NICE
- SYS_RESOURCE
environment:
DOMAIN: ${DOMAIN}
EXTERNAL_IPv4: ${EXTERNAL_IPv4}
EXTERNAL_IPv6: ${EXTERNAL_IPv6:-::1}
SIP_IP_ALLOWLIST: ${SIP_IP_ALLOWLIST:-}
DISABLE_SOUND_MUTED: ${DISABLE_SOUND_MUTED:-false}
DISABLE_SOUND_ALONE: ${DISABLE_SOUND_ALONE:-false}
SOUNDS_LANGUAGE: ${SOUNDS_LANGUAGE:-en-us-callie}
ESL_PASSWORD: ${FSESL_PASSWORD:-ClueCon}
volumes:
- ./conf/sip_profiles:/etc/freeswitch/sip_profiles/external-dialin
- ./data/freeswitch-meetings:/var/freeswitch/meetings
networks:
bbb-net:
ipv4_address: 10.7.7.10
logging:
# reduce logs to a minimum, so `docker compose logs -f` still works
driver: "local"
options:
max-size: "10k"
max-file: "1"
compress: "false"
nginx:
build:
context: mod/nginx
additional_contexts:
- src-learning-dashboard=./repos/bigbluebutton/bbb-learning-dashboard
- src-playback=./repos/bbb-playback
- src-html5=./repos/bigbluebutton/bigbluebutton-html5
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
TAG_BBB: v3.0.19
image: alangecker/bbb-docker-nginx:v3.0.19-v5.4.3-1.29
restart: unless-stopped
configs:
- source: bbb_nginx_fairblue_config
target: /etc/nginx/conf.d/default.conf
volumes:
- ./data/bigbluebutton:/var/bigbluebutton
- ${DEFAULT_PRESENTATION:-/dev/null}:/www/default.pdf:ro
- ./fairblue.js:/www/fairblue.js:ro
- ./manifest.json:/www/manifest.json:ro
ports:
# make sure nginx ports are also still available under the
# IPs 127.0.0.1 & 10.7.7.1 for backwards compatibility with exiting setup
# Warning: deprecated! this gets removed at some point
# Use 10.7.7.34 for new setups
- "127.0.0.1:48082:48082"
- "127.0.0.1:48081:48081"
- "127.0.0.1:48087:48087"
- "10.7.7.1:48082:48082"
- "10.7.7.1:48081:48081"
- "10.7.7.1:48087:48087"
networks:
bbb-net:
ipv4_address: 10.7.7.34
tmpfs:
- /tmp
extra_hosts:
- "host.docker.internal:10.7.7.1"
- "bbb-web:10.7.7.2"
- "etherpad:10.7.7.4"
- "webrtc-sfu:10.7.7.1"
- "greenlight:10.7.7.21"
- "bbb-graphql-server:10.7.7.31"
- "bbb-graphql-middleware:10.7.7.32"
etherpad:
build:
context: mod/etherpad
additional_contexts:
- plugin=./repos/bbb-etherpad-plugin
- skin=./repos/bbb-etherpad-skin
args:
TAG_ETHERPAD: "2.4.2"
image: alangecker/bbb-docker-etherpad:2.4.2-s8328b77-p88f3f6b
restart: unless-stopped
depends_on:
- redis
- collabora
environment:
ETHERPAD_API_KEY: ${ETHERPAD_API_KEY}
COLLABORA_URL: ${COLLABORA_URL:-https://collabora:9980/cool}
networks:
bbb-net:
ipv4_address: 10.7.7.4
bbb-pads:
build:
context: mod/bbb-pads
additional_contexts:
- src=./repos/bbb-pads
image: alangecker/bbb-docker-pads:v1.5.6
restart: unless-stopped
depends_on:
- redis
- etherpad
environment:
ETHERPAD_API_KEY: ${ETHERPAD_API_KEY}
networks:
bbb-net:
ipv4_address: 10.7.7.18
bbb-export-annotations:
build:
context: mod/bbb-export-annotations
additional_contexts:
src: ./repos/bigbluebutton/bbb-export-annotations
image: alangecker/bbb-docker-bbb-export-annotations:v3.0.19
restart: unless-stopped
depends_on:
- redis
- etherpad
- bbb-pads
networks:
# need connections to:
# https://github.com/bigbluebutton/bigbluebutton/blob/v2.7.0/bbb-export-annotations/config/settings.json
# "bbbWebAPI": "http://127.0.0.1:8090", -> bbb-web
# "bbbPadsAPI": "http://127.0.0.1:9002", -> bbb-pads
bbb-net:
ipv4_address: 10.7.7.19
volumes:
- ./data/bigbluebutton:/var/bigbluebutton
tmpfs:
- /tmp
redis:
image: redis:8.4-alpine
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 1s
timeout: 3s
retries: 30
networks:
bbb-net:
ipv4_address: 10.7.7.5
volumes:
- ./data/redis:/data
webrtc-sfu:
build:
context: mod/webrtc-sfu
additional_contexts:
- source=./repos/bbb-webrtc-sfu
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-webrtc-sfu:v2.21.2
restart: unless-stopped
depends_on:
- redis
- freeswitch
environment:
ESL_PASSWORD: ${FSESL_PASSWORD:-ClueCon}
MS_WEBRTC_LISTEN_IPS: '[{"ip":"::", "announcedIp":"${EXTERNAL_IPv6}"}, {"ip":"${EXTERNAL_IPv4}", "announcedIp":"${EXTERNAL_IPv4}"}]'
volumes:
- ./data/mediasoup:/var/mediasoup
tmpfs:
- /var/log/bbb-webrtc-sfu
network_mode: host
security_opt:
- seccomp:unconfined # allow io_uring access for mediasoup
ulimits:
memlock: -1 # allow io_uring_register_buffers to allocate enough ram
fsesl-akka:
build:
context: mod/fsesl-akka
additional_contexts:
- src-common-message=./repos/bigbluebutton/bbb-common-message
- src-fsesl-client=./repos/bigbluebutton/bbb-fsesl-client
- src-fsesl-akka=./repos/bigbluebutton/akka-bbb-fsesl
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-fsesl-akka:v3.0.19
restart: unless-stopped
depends_on:
- redis
- freeswitch
environment:
FSESL_PASSWORD: ${FSESL_PASSWORD:-ClueCon}
networks:
bbb-net:
ipv4_address: 10.7.7.14
apps-akka:
build:
context: mod/apps-akka
additional_contexts:
- src-common-message=./repos/bigbluebutton/bbb-common-message
- src-apps-akka=./repos/bigbluebutton/akka-bbb-apps
- src-config=./repos/bigbluebutton/bigbluebutton-html5/private/config/
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
TAG_BBB: v3.0.19
image: alangecker/bbb-docker-apps-akka:v3.0.19
restart: unless-stopped
depends_on:
- redis
- postgres
environment:
DOMAIN: ${DOMAIN}
SHARED_SECRET: ${SHARED_SECRET}
POSTGRES_PASSWORD: ${POSTGRESQL_SECRET:-password}
volumes:
- ./data/freeswitch-meetings:/var/freeswitch/meetings
- ./conf/bbb-html5.yml:/etc/bigbluebutton/bbb-html5.yml:ro
networks:
bbb-net:
ipv4_address: 10.7.7.15
bbb-graphql-server:
build:
context: mod/bbb-graphql-server
additional_contexts:
- src=./repos/bigbluebutton/bbb-graphql-server
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
GRAPHQL_ENGINE_TAG: v2.48.1
image: alangecker/bbb-docker-graphql-server:v3.0.19
depends_on:
- postgres
- bbb-web
- apps-akka
- bbb-graphql-actions
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${POSTGRESQL_SECRET:-password}
HASURA_GRAPHQL_ADMIN_SECRET: TODO_CHANGE_ME
networks:
bbb-net:
ipv4_address: 10.7.7.31
bbb-graphql-actions:
build:
context: mod/bbb-graphql-actions
additional_contexts:
- src=./repos/bigbluebutton/bbb-graphql-actions
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-graphql-actions:v3.0.19
restart: unless-stopped
depends_on:
- redis
- apps-akka
networks:
bbb-net:
ipv4_address: 10.7.7.30
bbb-graphql-middleware:
build:
context: mod/bbb-graphql-middleware
additional_contexts:
- src=./repos/bigbluebutton/bbb-graphql-middleware
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-graphql-middleware:v3.0.19
restart: unless-stopped
depends_on:
- bbb-graphql-server
- bbb-graphql-actions
- bbb-web
- redis
networks:
bbb-net:
ipv4_address: 10.7.7.32
collabora:
image: collabora/code:latest
restart: unless-stopped
tmpfs:
- /tmp
networks:
bbb-net:
ipv4_address: 10.7.7.20
# disable logging (way to verbose)
logging:
driver: none
periodic:
build: mod/periodic
image: alangecker/bbb-docker-periodic:v3.0.0
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data/bigbluebutton:/var/bigbluebutton
- ./data/mediasoup:/var/mediasoup
tmpfs:
- /var/log/bigbluebutton
environment:
ENABLE_RECORDING: ${ENABLE_RECORDING}
REMOVE_OLD_RECORDING: ${REMOVE_OLD_RECORDING}
RECORDING_MAX_AGE_DAYS: ${RECORDING_MAX_AGE_DAYS}
networks:
bbb-net:
ipv4_address: 10.7.7.12
# recordings
recordings:
build:
context: mod/recordings
additional_contexts:
- record-core=./repos/bigbluebutton/record-and-playback/core
- presentation=./repos/bigbluebutton/record-and-playback/presentation
- bbb-conf=./repos/bigbluebutton/bigbluebutton-config
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
TAG_BBB_PRESENTATION_VIDEO: "5.0.0"
image: alangecker/bbb-docker-recordings:v3.0.19
restart: unless-stopped
depends_on:
- redis
- bbb-pads
environment:
DOMAIN: ${DOMAIN}
SHARED_SECRET: ${SHARED_SECRET}
volumes:
- ./data/bigbluebutton:/var/bigbluebutton
- ./data/freeswitch-meetings:/var/freeswitch/meetings
- ./data/mediasoup:/var/mediasoup
- ./data/bbb-webrtc-recorder:/var/lib/bbb-webrtc-recorder
tmpfs:
- /var/log/bigbluebutton
- /tmp
networks:
bbb-net:
ipv4_address: 10.7.7.16
bbb-webrtc-recorder:
build:
context: mod/bbb-webrtc-recorder
additional_contexts:
- src=./repos/bbb-webrtc-recorder
image: alangecker/bbb-docker-webrtc-recorder:v0.13.1
depends_on:
- redis
volumes:
- ./data/bbb-webrtc-recorder:/var/lib/bbb-webrtc-recorder
# WebRTC connection to bbb-webrtc-sfu seem to
# only to work via the external IP
network_mode: host
extra_hosts:
- "redis:10.7.7.5"
# HAPROXY NOT NECESSARY FOR CO-OP CLOUD
haproxy:
build: mod/haproxy
image: alangecker/bbb-haproxy:3.0.9
restart: unless-stopped
volumes:
- ./data/haproxy/letsencrypt:/etc/letsencrypt
- ./mod/haproxy/haproxy.cfg:/etc/haproxy/haproxy.cfg
- ./mod/haproxy/protocolmap:/etc/haproxy/protocolmap
environment:
- IGNORE_TLS_CERT_ERRORS=false
- CERT1=${DOMAIN}
- EMAIL=${LETSENCRYPT_EMAIL}
ports:
- 80:80
- 443:443
networks:
bbb-net:
ipv4_address: 10.7.7.35
# coturn
coturn:
image: coturn/coturn:4.8-alpine
restart: unless-stopped
command:
- "--external-ip=${EXTERNAL_IPv4}/${EXTERNAL_IPv4}"
- "--external-ip=${EXTERNAL_IPv6:-::1}/${EXTERNAL_IPv6:-::1}"
- "--static-auth-secret=${TURN_SECRET}"
- "--allowed-peer-ip=${EXTERNAL_IPv4}"
- "--relay-ip=${EXTERNAL_IPv4}"
- "--relay-ip=${EXTERNAL_IPv6:-::1}"
volumes:
- ./mod/coturn/turnserver.conf:/etc/coturn/turnserver.conf
- ./data/coturn:/var/lib/coturn
network_mode: host
# greenlight
greenlight:
image: bigbluebutton/greenlight:v3.6.3
restart: unless-stopped
env_file: .env
depends_on:
- postgres
- redis
environment:
DATABASE_URL: postgres://postgres:${POSTGRESQL_SECRET:-password}@postgres:5432/greenlight
REDIS_URL: redis://redis:6379
BIGBLUEBUTTON_ENDPOINT: https://${DOMAIN}/bigbluebutton/api
BIGBLUEBUTTON_SECRET: ${SHARED_SECRET}
SECRET_KEY_BASE: ${RAILS_SECRET}
RELATIVE_URL_ROOT: /
volumes:
- ./data/greenlight:/usr/src/app/storage
networks:
bbb-net:
ipv4_address: 10.7.7.21
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_MULTIPLE_DATABASES: bbb_graphql,hasura_app,greenlight
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${POSTGRESQL_SECRET:-password}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- ./data/postgres:/var/lib/postgresql/data
- ./mod/postgres/initdb.sh:/docker-entrypoint-initdb.d/initdb.sh
networks:
bbb-net:
ipv4_address: 10.7.7.22
# prometheus
prometheus-exporter:
image: greenstatic/bigbluebutton-exporter:latest
restart: unless-stopped
environment:
API_BASE_URL: http://10.7.7.34:48087/bigbluebutton/api/
API_SECRET: ${SHARED_SECRET}
RECORDINGS_METRICS_READ_FROM_DISK: "${ENABLE_PROMETHEUS_EXPORTER_OPTIMIZATION:-false}"
networks:
bbb-net:
ipv4_address: 10.7.7.33
volumes:
- ./data/bigbluebutton:/var/bigbluebutton:ro
# the exporter requires /etc/bigbluebutton/bigbluebutton-release
tmpfs:
- /etc/bigbluebutton:mode=777
entrypoint: sh -c 'echo "BIGBLUEBUTTON_RELEASE=2.7.3" > /etc/bigbluebutton/bigbluebutton-release && python server.py'
interpretation-data-server:
image: registry.osalliance.com/fairblue/interpretation-data-server:1.1.0
container_name: interpretation-data-server
restart: unless-stopped
networks:
bbb-net:
ipv4_address: 10.7.7.77
networks:
bbb-net:
ipam:
driver: default
config:
- subnet: "10.7.7.0/24"
configs:
bbb_web_plugin_config:
file: ./conf/bigbluebutton.properties.tmpl
bbb_nginx_fairblue_config:
file: ./conf/nginx_default.conf
+367 -193
View File
@@ -1,57 +1,31 @@
---
version: '3.8'
# html5 templates
x-html5-backend: &html5backend
image: alangecker/bbb-docker-html5:v2.7.3
depends_on:
- redis
- mongodb
- etherpad
environment: &html5backend-env
DOMAIN: ${DOMAIN}
CLIENT_TITLE: BigBlueButton
LISTEN_ONLY_MODE: ${LISTEN_ONLY_MODE:-true}
DISABLE_ECHO_TEST: ${DISABLE_ECHO_TEST:-false}
AUTO_SHARE_WEBCAM: ${AUTO_SHARE_WEBCAM:-false}
DISABLE_VIDEO_PREVIEW: ${DISABLE_VIDEO_PREVIEW:-false}
CHAT_ENABLED: ${CHAT_ENABLED:-true}
CHAT_START_CLOSED: ${CHAT_START_CLOSED:-false}
BREAKOUTROOM_LIMIT: ${BREAKOUTROOM_LIMIT:-8}
DEV_MODE: ${DEV_MODE:-}
BBB_HTML5_ROLE: backend
x-html5-frontend: &html5frontend
<<: *html5backend
volumes:
- html5-static:/html5-static:rw
environment: &html5frontend-env
<<: *html5backend-env
BBB_HTML5_ROLE: frontend
# =========================
services:
bbb-web:
image: alangecker/bbb-docker-web:v2.7.3
image: alangecker/bbb-docker-web:v3.0.19
depends_on:
- redis
- etherpad
- bbb-pads
- collabora
# healthcheck:
# test: wget --no-proxy --no-verbose --tries=1 --spider http://10.7.7.2:8090/bigbluebutton/api || exit 1
# start_period: 2m
environment:
DEV_MODE: ${DEV_MODE:-}
IGNORE_TLS_CERT_ERRORS: ${IGNORE_TLS_CERT_ERRORS:-true}
DOMAIN: ${DOMAIN}
ENABLE_RECORDING: ${ENABLE_RECORDING:-false}
# SHARED_SECRET is set via entrypoint.bbb-web.sh
WELCOME_MESSAGE: ${WELCOME_MESSAGE:-}
WELCOME_FOOTER: ${WELCOME_FOOTER}
STUN_SERVER: stun:${STUN_IP}:${STUN_PORT}
TURN_SERVER: ${TURN_SERVER:-}
ENABLE_HTTPS_PROXY: ${ENABLE_HTTPS_PROXY:-false}
# SHARED_SECRET is set via entrypoint.bbb-web.sh
# TURN_SECRET is set via entrypoint.bbb-web.sh
ENABLE_LEARNING_DASHBOARD: ${ENABLE_LEARNING_DASHBOARD:-true}
NUMBER_OF_BACKEND_NODEJS_PROCESSES: 2 # look for containers?
COLLABORA_URL: ${COLLABORA_URL:-https://collabora:9980/cool}
# NUMBER_OF_BACKEND_NODEJS_PROCESSES: 2 # look for containers?
configs:
- source: entrypoint_bbbweb
target: /usr/local/bin/docker-entrypoint.sh
@@ -64,55 +38,14 @@ services:
- bigbluebutton:/var/bigbluebutton
- vol-freeswitch:/var/freeswitch/meetings
networks:
bbb-net:
ipv4_address: 10.7.7.2
# create compose overrides for multiple backend/frontend
# see authentik repo for compose file reference in .env
html5-backend-1:
<<: *html5backend
environment:
<<: *html5backend-env
INSTANCE_ID: 1
PORT: 4000
networks:
bbb-net:
ipv4_address: 10.7.7.100
html5-backend-2:
<<: *html5backend
environment:
<<: *html5backend-env
INSTANCE_ID: 2
PORT: 4001
networks:
bbb-net:
ipv4_address: 10.7.7.101
html5-frontend-1:
<<: *html5frontend
environment:
<<: *html5frontend-env
INSTANCE_ID: 1
PORT: 4100
networks:
bbb-net:
ipv4_address: 10.7.7.200
html5-frontend-2:
<<: *html5frontend
environment:
<<: *html5frontend-env
INSTANCE_ID: 2
PORT: 4101
networks:
bbb-net:
ipv4_address: 10.7.7.201
- internal
# freeswitch (audio input streaming and telco dial-in support)
freeswitch:
container_name: bbb-freeswitch
image: alangecker/bbb-docker-freeswitch:v2.7.0
image: alangecker/bbb-docker-freeswitch:v1.10.12-v3.0.19
deploy:
replicas: 1
endpoint_mode: dnsrr
cap_add:
- IPC_LOCK
- NET_ADMIN
@@ -140,7 +73,9 @@ services:
# - ./conf/sip_profiles:/etc/freeswitch/sip_profiles/external
# - ./conf/dialplan_public:/etc/freeswitch/dialplan/public_docker
- vol-freeswitch:/var/freeswitch/meetings
network_mode: host
# network_mode: host
networks:
- internal
logging:
# reduce logs to a minimum, so `docker compose logs -f` still works
driver: "local"
@@ -151,30 +86,64 @@ services:
# nginx (webserver gateway for a bunch of things)
nginx:
image: alangecker/bbb-docker-nginx:1.23-v5.0.2-v2.7.3
depends_on:
- etherpad
- webrtc-sfu
- html5-backend-1
image: alangecker/bbb-docker-nginx:v3.0.19-v5.4.3-1.29
volumes:
- bigbluebutton:/var/bigbluebutton
- html5-static:/html5-static:ro
- ${DEFAULT_PRESENTATION:-/dev/null}:/www/default.pdf
network_mode: host
extra_hosts:
- "host.docker.internal:10.7.7.1"
- "bbb-web:10.7.7.2"
- "etherpad:10.7.7.4"
- "webrtc-sfu:10.7.7.1"
- "html5:10.7.7.11"
- "greenlight:10.7.7.21"
tmpfs:
- /tmp
configs:
- source: nginx_conf
target: /etc/nginx/nginx.conf
mode: 0555
# - source: beg_conf
# target: /etc/nginx/bbb/bbb-exporter.nginx
# mode: 0555
- source: bhdn_conf # used to be in dev mode
target: /etc/nginx/bbb/bbb-html5.nginx
mode: 0555
- source: wn_conf
target: /etc/nginx/bbb/webhooks.nginx
mode: 0555
- source: wsn_conf
target: /etc/nginx/bbb/webrtc-sfu.nginx
mode: 0555
- source: pres_conf
target: /www/default.pdf
mode: 0555
- source: demo_conf
target: /etc/nginx/bbb/demo.nginx
mode: 0555
networks:
- proxy
- internal
deploy:
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=48087"
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})"
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
- "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect"
- "traefik.http.middlewares.${STACK_NAME}-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.${STACK_NAME}-redirect.redirectscheme.permanent=true"
# extra_hosts:
# - "host.docker.internal:10.7.7.1"
# - "bbb-web:10.7.7.2"
# - "etherpad:10.7.7.4"
# - "webrtc-sfu:10.7.7.1"
# - "greenlight:10.7.7.21"
# - "bbb-graphql-server:10.7.7.31"
# - "bbb-graphql-middleware:10.7.7.32"
# etherpad (collaborative notepad)
etherpad:
image: alangecker/bbb-docker-etherpad:1.9.1
image: alangecker/bbb-docker-etherpad:2.4.2-s8328b77-p88f3f6b
depends_on:
- redis
# environment:
- collabora
environment:
COLLABORA_URL: ${COLLABORA_URL:-https://collabora:9980/cool}
# ETHERPAD_API_KEY is set via entrypoint
configs:
- source: entrypoint_etherpad
@@ -184,12 +153,11 @@ services:
- etherpad_api_key
entrypoint: /usr/local/bin/docker-entrypoint.sh
networks:
bbb-net:
ipv4_address: 10.7.7.4
- internal
# bbb-pads (bbb etherpad integration)
bbb-pads:
image: alangecker/bbb-docker-pads:v1.5.2
image: alangecker/bbb-docker-pads:v1.5.6
depends_on:
- redis
- etherpad
@@ -203,69 +171,156 @@ services:
- etherpad_api_key
entrypoint: /usr/local/bin/docker-entrypoint.sh
networks:
bbb-net:
ipv4_address: 10.7.7.18
- internal
# redis (caching)
redis:
image: redis:7.2-alpine
image: redis:8.4-alpine
#healthcheck:
# test: ["CMD", "redis-cli", "ping"]
# interval: 1s
# timeout: 3s
# retries: 30
networks:
bbb-net:
ipv4_address: 10.7.7.5
# mongodb
mongodb:
container_name: bbb-mongodb
image: mongo:4.4
configs:
- source: mongod_conf
target: /etc/mongod.conf
- source: init_replica
target: /docker-entrypoint-initdb.d/init-replica.sh
tmpfs:
- /data/configdb
- /data/db
command: mongod --config /etc/mongod.conf --oplogSize 8 --replSet rs0 --noauth
# healthcheck:
# test: bash -c "if mongo --eval 'quit(db.runCommand({ ping':' 1 }).ok ? 0 ':' 2)'; then exit 0; fi; exit 1;"
- internal
bbb-export-annotations:
image: alangecker/bbb-docker-bbb-export-annotations:v3.0.19
depends_on:
- redis
- etherpad
- bbb-pads
networks:
bbb-net:
ipv4_address: 10.7.7.6
# kurento (media server for streaming webcam and screensharing)
kurento:
image: kurento/kurento-media-server:6.18
network_mode: host
# need connections to:
# https://github.com/bigbluebutton/bigbluebutton/blob/v2.7.0/bbb-export-annotations/config/settings.json
# "bbbWebAPI": "http://127.0.0.1:8090", -> bbb-web
# "bbbPadsAPI": "http://127.0.0.1:9002", -> bbb-pads
- internal
volumes:
- vol-kurento:/var/kurento
- bigbluebutton:/var/bigbluebutton
tmpfs:
- /tmp
# webrtc-sfu (webrtc controller for negotiation and media stream)
webrtc-sfu:
image: alangecker/bbb-docker-webrtc-sfu:v2.12.0
image: alangecker/bbb-docker-webrtc-sfu:v2.21.2
depends_on:
- redis
- freeswitch
- kurento
ports:
- {target: 24577, published: 24577, protocol: udp, mode: host}
- {target: 24578, published: 24578, protocol: udp, mode: host}
- {target: 24579, published: 24579, protocol: udp, mode: host}
- {target: 24580, published: 24580, protocol: udp, mode: host}
- {target: 24581, published: 24581, protocol: udp, mode: host}
- {target: 24582, published: 24582, protocol: udp, mode: host}
- {target: 24583, published: 24583, protocol: udp, mode: host}
- {target: 24584, published: 24584, protocol: udp, mode: host}
- {target: 24585, published: 24585, protocol: udp, mode: host}
- {target: 24586, published: 24586, protocol: udp, mode: host}
- {target: 24587, published: 24587, protocol: udp, mode: host}
- {target: 24588, published: 24588, protocol: udp, mode: host}
- {target: 24589, published: 24589, protocol: udp, mode: host}
- {target: 24590, published: 24590, protocol: udp, mode: host}
- {target: 24591, published: 24591, protocol: udp, mode: host}
- {target: 24592, published: 24592, protocol: udp, mode: host}
- {target: 24593, published: 24593, protocol: udp, mode: host}
- {target: 24594, published: 24594, protocol: udp, mode: host}
- {target: 24595, published: 24595, protocol: udp, mode: host}
- {target: 24596, published: 24596, protocol: udp, mode: host}
- {target: 24597, published: 24597, protocol: udp, mode: host}
- {target: 24598, published: 24598, protocol: udp, mode: host}
- {target: 24599, published: 24599, protocol: udp, mode: host}
- {target: 24600, published: 24600, protocol: udp, mode: host}
- {target: 24601, published: 24601, protocol: udp, mode: host}
- {target: 24602, published: 24602, protocol: udp, mode: host}
- {target: 24603, published: 24603, protocol: udp, mode: host}
- {target: 24604, published: 24604, protocol: udp, mode: host}
- {target: 24605, published: 24605, protocol: udp, mode: host}
- {target: 24606, published: 24606, protocol: udp, mode: host}
- {target: 24607, published: 24607, protocol: udp, mode: host}
- {target: 24608, published: 24608, protocol: udp, mode: host}
- {target: 24609, published: 24609, protocol: udp, mode: host}
- {target: 24610, published: 24610, protocol: udp, mode: host}
- {target: 24611, published: 24611, protocol: udp, mode: host}
- {target: 24612, published: 24612, protocol: udp, mode: host}
- {target: 24613, published: 24613, protocol: udp, mode: host}
- {target: 24614, published: 24614, protocol: udp, mode: host}
- {target: 24615, published: 24615, protocol: udp, mode: host}
- {target: 24616, published: 24616, protocol: udp, mode: host}
- {target: 24617, published: 24617, protocol: udp, mode: host}
- {target: 24618, published: 24618, protocol: udp, mode: host}
- {target: 24619, published: 24619, protocol: udp, mode: host}
- {target: 24620, published: 24620, protocol: udp, mode: host}
- {target: 24621, published: 24621, protocol: udp, mode: host}
- {target: 24622, published: 24622, protocol: udp, mode: host}
- {target: 24623, published: 24623, protocol: udp, mode: host}
- {target: 24624, published: 24624, protocol: udp, mode: host}
- {target: 24625, published: 24625, protocol: udp, mode: host}
- {target: 24626, published: 24626, protocol: udp, mode: host}
- {target: 24627, published: 24627, protocol: udp, mode: host}
- {target: 24628, published: 24628, protocol: udp, mode: host}
- {target: 24629, published: 24629, protocol: udp, mode: host}
- {target: 24630, published: 24630, protocol: udp, mode: host}
- {target: 24631, published: 24631, protocol: udp, mode: host}
- {target: 24632, published: 24632, protocol: udp, mode: host}
- {target: 24633, published: 24633, protocol: udp, mode: host}
- {target: 24634, published: 24634, protocol: udp, mode: host}
- {target: 24635, published: 24635, protocol: udp, mode: host}
- {target: 24636, published: 24636, protocol: udp, mode: host}
- {target: 24637, published: 24637, protocol: udp, mode: host}
- {target: 24638, published: 24638, protocol: udp, mode: host}
- {target: 24639, published: 24639, protocol: udp, mode: host}
- {target: 24640, published: 24640, protocol: udp, mode: host}
- {target: 24641, published: 24641, protocol: udp, mode: host}
- {target: 24642, published: 24642, protocol: udp, mode: host}
- {target: 24643, published: 24643, protocol: udp, mode: host}
- {target: 24644, published: 24644, protocol: udp, mode: host}
- {target: 24645, published: 24645, protocol: udp, mode: host}
- {target: 24646, published: 24646, protocol: udp, mode: host}
- {target: 24647, published: 24647, protocol: udp, mode: host}
- {target: 24648, published: 24648, protocol: udp, mode: host}
- {target: 24649, published: 24649, protocol: udp, mode: host}
- {target: 24650, published: 24650, protocol: udp, mode: host}
- {target: 24651, published: 24651, protocol: udp, mode: host}
- {target: 24652, published: 24652, protocol: udp, mode: host}
- {target: 24653, published: 24653, protocol: udp, mode: host}
- {target: 24654, published: 24654, protocol: udp, mode: host}
- {target: 24655, published: 24655, protocol: udp, mode: host}
- {target: 24656, published: 24656, protocol: udp, mode: host}
- {target: 24657, published: 24657, protocol: udp, mode: host}
- {target: 24658, published: 24658, protocol: udp, mode: host}
- {target: 24659, published: 24659, protocol: udp, mode: host}
- {target: 24660, published: 24660, protocol: udp, mode: host}
- {target: 24661, published: 24661, protocol: udp, mode: host}
- {target: 24662, published: 24662, protocol: udp, mode: host}
- {target: 24663, published: 24663, protocol: udp, mode: host}
- {target: 24664, published: 24664, protocol: udp, mode: host}
- {target: 24665, published: 24665, protocol: udp, mode: host}
- {target: 24666, published: 24666, protocol: udp, mode: host}
- {target: 24667, published: 24667, protocol: udp, mode: host}
- {target: 24668, published: 24668, protocol: udp, mode: host}
- {target: 24669, published: 24669, protocol: udp, mode: host}
- {target: 24670, published: 24670, protocol: udp, mode: host}
- {target: 24671, published: 24671, protocol: udp, mode: host}
- {target: 24672, published: 24672, protocol: udp, mode: host}
- {target: 24673, published: 24673, protocol: udp, mode: host}
- {target: 24674, published: 24674, protocol: udp, mode: host}
- {target: 24675, published: 24675, protocol: udp, mode: host}
- {target: 24676, published: 24676, protocol: udp, mode: host}
environment:
CLIENT_HOST: 10.7.7.1
REDIS_HOST: 10.7.7.5
FREESWITCH_IP: 10.7.7.1
FREESWITCH_SIP_IP: ${EXTERNAL_IPv4}
MCS_HOST: 0.0.0.0
MCS_ADDRESS: 127.0.0.1
ESL_IP: 10.7.7.1
# ESL_PASSWORD is set via entrypoint.webrtc-sfu.sh
MS_WEBRTC_LISTEN_IPS: '[{"ip":"${EXTERNAL_IPv4}", "announcedIp":"${EXTERNAL_IPv4}"}]'
MS_RTP_LISTEN_IP: '{"ip":"0.0.0.0", "announcedIp":"${EXTERNAL_IPv4}"}'
# ip must be 0.0.0.0 (container binds all interfaces; it can't bind the host's external IP directly).
# announcedIp is the address mediasoup puts in the ICE candidates sent to the browser, so it MUST be
# the server's PUBLIC IPv4 (PUBLIC_IPV4) — NOT 0.0.0.0, or the browser can't connect and ICE times out.
MS_WEBRTC_LISTEN_IPS: '[{"ip":"0.0.0.0", "announcedIp":"${PUBLIC_IPV4}"}]'
configs:
- source: entrypoint_webrtcsfu
target: /usr/local/bin/docker-entrypoint.sh
mode: 0555
- source: ws_conf
target: /etc/bigbluebutton/bbb-webrtc-sfu/production.yml
mode: 0555
entrypoint: /usr/local/bin/docker-entrypoint.sh
volumes:
- vol-mediasoup:/var/mediasoup
@@ -273,11 +328,19 @@ services:
- /var/log/bbb-webrtc-sfu
secrets:
- fsesl_password
network_mode: host
# network_mode: host would be needed for mediasoup UDP to work from outside;
# keeping on overlay network for now so other services can reach it by name.
#security_opt:
# - seccomp:unconfined # allow io_uring access for mediasoup
ulimits:
memlock: -1 # allow io_uring_register_buffers to allocate enough ram
networks:
- internal
# fsesl-akka (bbb freeswitch integration)
fsesl-akka:
image: alangecker/bbb-docker-fsesl-akka:v2.7.0
image: alangecker/bbb-docker-fsesl-akka:v3.0.19
depends_on:
- redis
- freeswitch
@@ -291,12 +354,11 @@ services:
- fsesl_password
entrypoint: /usr/local/bin/docker-entrypoint.sh
networks:
bbb-net:
ipv4_address: 10.7.7.14
- internal
# apps-akka (seems to be an bbb app integration endpoint)
apps-akka:
image: alangecker/bbb-docker-apps-akka:v2.7.3
image: alangecker/bbb-docker-apps-akka:v3.0.19
depends_on:
- redis
environment:
@@ -308,33 +370,81 @@ services:
- source: entrypoint_appsakka
target: /usr/local/bin/docker-entrypoint.sh
mode: 0555
- source: bbbhtml5_conf
target: /etc/bigbluebutton/bbb-html5.yml
mode: 0555
- source: aa_conf
target: /etc/bigbluebutton/bbb-apps-akka.conf.tmpl
mode: 0555
secrets:
- shared_secret
- postgres_password
entrypoint: /usr/local/bin/docker-entrypoint.sh
networks:
bbb-net:
ipv4_address: 10.7.7.15
- internal
# jodconverter (jodconverter most likely just transforms doc files to pdf for the presentation mode)
jodconverter:
image: alangecker/bbb-docker-jodconverter:latest
security_opt:
- 'no-new-privileges:true' # security profile. might work with swarm.
bbb-graphql-server:
image: alangecker/bbb-docker-graphql-server:v3.0.19
depends_on:
- postgres
- bbb-web
- apps-akka
- bbb-graphql-actions
secrets:
- postgres_password
- hasura_admin_secret
environment:
POSTGRES_USER: postgres
# POSTGRES_PASSWORD and HASURA_GRAPHQL_ADMIN_SECRET are set via entrypoint
configs:
- source: entrypoint_graphqlserver
target: /usr/local/bin/docker-entrypoint.sh
mode: 0555
entrypoint: /usr/local/bin/docker-entrypoint.sh
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8085/healthz"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
networks:
- internal
bbb-graphql-actions:
image: alangecker/bbb-docker-graphql-actions:v3.0.19
depends_on:
- redis
- apps-akka
networks:
- internal
bbb-graphql-middleware:
image: alangecker/bbb-docker-graphql-middleware:v3.0.19
depends_on:
- bbb-graphql-server
- bbb-graphql-actions
- bbb-web
- redis
networks:
- internal
# extra_hosts:
# - "nginx:10.7.7.1"
collabora:
image: collabora/code:latest
tmpfs:
- /tmp
deploy:
resources:
limits:
memory: 512M
networks:
bbb-net:
ipv4_address: 10.7.7.20
- internal
# disable logging (way to verbose)
logging:
driver: none
# periodic (runs a freeswitch sync and cleans up recordings, has entrypoint but needs no custom things afaik)
periodic:
image: alangecker/bbb-docker-periodic:v2.7.0
image: alangecker/bbb-docker-periodic:v3.0.0
depends_on:
- mongodb
- postgres
volumes:
- /var/run/docker.sock:/var/run/docker.sock # not sure what prupose this has?
- bigbluebutton:/var/bigbluebutton # access bbb data
@@ -346,12 +456,26 @@ services:
REMOVE_OLD_RECORDING: ${REMOVE_OLD_RECORDING}
RECORDING_MAX_AGE_DAYS: ${RECORDING_MAX_AGE_DAYS}
networks:
bbb-net:
ipv4_address: 10.7.7.12
- internal
# coturn
bbb-webrtc-recorder:
image: alangecker/bbb-docker-webrtc-recorder:v0.13.1
depends_on:
- redis
volumes:
- vol-webrtc-recorder:/var/lib/bbb-webrtc-recorder
networks:
- internal
# coturn (TURN server — must use host networking for UDP relay to reach clients)
coturn:
image: coturn/coturn:4.6-alpine
image: coturn/coturn:4.8-alpine
command:
- "--external-ip=${EXTERNAL_IPv4}/${EXTERNAL_IPv4}"
- "--external-ip=${EXTERNAL_IPv6:-::1}/${EXTERNAL_IPv6:-::1}"
- "--allowed-peer-ip=${EXTERNAL_IPv4}"
- "--relay-ip=${EXTERNAL_IPv4}"
- "--relay-ip=${EXTERNAL_IPv6:-::1}"
configs:
- source: entrypoint_coturn
target: /usr/local/bin/docker-entrypoint.sh
@@ -361,14 +485,17 @@ services:
secrets:
- turn_secret
environment:
ENABLE_HTTPS_PROXY: "true"
ENABLE_HTTPS_PROXY: "false"
# volumes:
# - "/var/home/thebastard/.abra/recipes/bigbluebutton/cert/cert.pem:/tmp/cert.pem:ro"
# - "/var/home/thebastard/.abra/recipes/bigbluebutton/cert/key.pem:/tmp/key.pem:ro"
# network_mode: host <- mine has this commented out
user: root
entrypoint: /usr/local/bin/docker-entrypoint.sh
network_mode: host
# greenlight
greenlight:
image: bigbluebutton/greenlight:v3.1.0
image: bigbluebutton/greenlight:v3.6.3
depends_on:
- postgres
- redis
@@ -391,37 +518,47 @@ services:
- rails_secret
entrypoint: /usr/local/bin/docker-entrypoint.sh
networks:
bbb-net:
ipv4_address: 10.7.7.21 # does static ipv4 work with swarm?
- internal
# postgres for greenlight
# postgres for greenlight
postgres:
image: postgres:12-alpine
image: postgres:16-alpine
environment:
POSTGRES_DB: greenlight-v3
POSTGRES_MULTIPLE_DATABASES: bbb_graphql,hasura_app,greenlight
POSTGRES_USER: postgres
POSTGRES_PASSWORD_FILE: /run/secret/postgres_password
#healthcheck:
#test: ["CMD-SHELL", "pg_isready -U postgres"]
#interval: 10s
#timeout: 5s
#retries: 5
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- "postgres_data:/var/lib/postgresql/data"
configs:
- source: initdb_sh
target: /docker-entrypoint-initdb.d/initdb.sh
mode: 0555
secrets:
- postgres_password
networks:
bbb-net:
ipv4_address: 10.7.7.22
- internal
netshoot:
image: nicolaka/netshoot
entrypoint: /bin/bash
command: -c "sleep infinity"
ports:
- {target: 9999, published: 9999, protocol: udp, mode: host}
networks:
- internal
volumes:
html5-static:
greenlight_data:
postgres_data:
bigbluebutton:
vol-mediasoup:
vol-freeswitch:
vol-kurento:
vol-webrtc-recorder:
configs:
entrypoint_greenlight:
@@ -430,6 +567,9 @@ configs:
turnserver_conf:
name: ${STACK_NAME}_turnserver_conf_${TURNSERVER_CONF_VERSION}
file: ./turnserver.conf
bbbhtml5_conf:
name: ${STACK_NAME}_bbbhtml5_conf_${BBBHTML5_CONF_VERSION}
file: ./bbb-html5.yml
entrypoint_coturn:
name: ${STACK_NAME}_entrypoint_coturn_${ENTRYPOINT_COTURN_VERSION}
file: ./entrypoint.coturn.sh
@@ -442,12 +582,12 @@ configs:
entrypoint_webrtcsfu:
name: ${STACK_NAME}_entrypoint_webrtcsfu_${ENTRYPOINT_WEBRTCSFU_VERSION}
file: ./entrypoint.webrtc-sfu.sh
mongod_conf:
name: ${STACK_NAME}_mongod_conf_${MONGOD_CONF_VERSION}
file: ./mongod.conf
init_replica:
name: ${STACK_NAME}_init_replica_${INIT_REPLICA_VERSION}
file: ./init-replica.sh
entrypoint_graphqlserver:
name: ${STACK_NAME}_entrypoint_graphqlserver_${ENTRYPOINT_GRAPHQLSERVER_VERSION}
file: ./entrypoint.bbb-graphql-server.sh
initdb_sh:
name: ${STACK_NAME}_initdb_sh_${INITDB_SH_VERSION}
file: ./mod/initdb.sh
entrypoint_bbbpads:
name: ${STACK_NAME}_entrypoint_bbbpads_${ENTRYPOINT_BBBPADS_VERSION}
file: ./entrypoint.bbb-pads.sh
@@ -460,6 +600,39 @@ configs:
entrypoint_bbbweb:
name: ${STACK_NAME}_entrypoint_bbbweb_${ENTRYPOINT_BBBWEB_VERSION}
file: ./entrypoint.bbb-web.sh
aa_conf:
name: ${STACK_NAME}_aa_conf_${AA_CONF_VERSION}
file: ./mod/bbb-apps-akka.conf
beg_conf:
name: ${STACK_NAME}_beg_conf_${BEG_CONF_VERSION}
file: ./mod/bbb-exporter.nginx
bhdn_conf:
name: ${STACK_NAME}_bhdn_conf_${BHDN_CONF_VERSION}
file: ./mod/nginx/bbb/bbb-html5.nginx
brf_conf:
name: ${STACK_NAME}_brf_conf_${BRF_CONF_VERSION}
file: ./mod/bbb-resync-freeswitch
nginx_conf:
name: ${STACK_NAME}_nginx_conf_${NGINX_CONF_VERSION}
file: ./mod/nginx.conf
wn_conf:
name: ${STACK_NAME}_wn_conf_${WN_CONF_VERSION}
file: ./mod/webhooks.nginx
wsn_conf:
name: ${STACK_NAME}_wsn_conf_${WSN_CONF_VERSION}
file: ./mod/webrtc-sfu.nginx
ws_conf:
name: ${STACK_NAME}_ws_conf_${WS_CONF_VERSION}
file: ./mod/webrtc-sfu-config.yaml
demo_conf:
name: ${STACK_NAME}_demo_conf_${DEMO_CONF_VERSION}
file: ./mod/nginx/bbb/demo.nginx
pres_conf: # the default presentation for bbb nginx
name: ${STACK_NAME}_pres_conf_${PRES_CONF_VERSION}
file: ./mod/nginx/default.pdf
freeswitch_ex:
name: ${STACK_NAME}_freeswitch_ex_${FREESWITCH_EX_VERSION}
file: ./mod/freeswitch/conf/sip_profiles/external.xml
secrets:
postgres_password:
@@ -480,10 +653,11 @@ secrets:
etherpad_api_key:
external: true
name: ${STACK_NAME}_etherpad_api_key_${ETHERPAD_API_KEY_VERSION}
hasura_admin_secret:
external: true
name: ${STACK_NAME}_hasura_admin_secret_${SECRET_HASURA_ADMIN_SECRET_VERSION}
networks:
bbb-net:
ipam:
driver: default
config:
- subnet: "10.7.7.0/24"
proxy:
external: true
internal:
+4
View File
@@ -0,0 +1,4 @@
*/*
!.gitkeep
!example.xml
*.pdf
View File
+12
View File
@@ -0,0 +1,12 @@
<!-- All Options: https://freeswitch.org/confluence/display/FREESWITCH/Gateways+Configuration -->
<!--
<include>
<gateway name="sipgate.de">
<param name="proxy" value="sipgate.de"/>
<param name="username" value="USERNAME"/>
<param name="password" value="PASSWORD"/>
<param name="extension" value="EXTERNALDID"/>
</gateway>
</include>
-->
View File
BIN
View File
Binary file not shown.
+25 -1
View File
@@ -2,7 +2,7 @@
# set shared_secret variable
if test -f "/run/secrets/shared_secret"; then
pwd=`cat /run/secrets/shared_secret`
pwd=$(cat /run/secrets/shared_secret)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/shared_secret is empty"
exit 1
@@ -15,10 +15,34 @@ else
exit 1
fi
# set postgres_password variable
if test -f "/run/secrets/postgres_password"; then
pwd=$(cat /run/secrets/postgres_password)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/postgres_password is empty"
exit 1
fi
echo "entrypoint.greenlight.sh setting POSTGRES_PASSWORD"
export "POSTGRES_PASSWORD"="${pwd}"
unset "pwd"
else
echo >&2 "error: /run/secrets/postgres_password does not exist"
exit 1
fi
# bbb-apps-akka.conf
TARGET=/etc/bigbluebutton/bbb-apps-akka.conf
cp /etc/bigbluebutton/bbb-apps-akka.conf.tmpl $TARGET
sed -i "s/DOMAIN/$DOMAIN/" $TARGET
sed -i "s/SHARED_SECRET/$SHARED_SECRET/" $TARGET
sed -i "s/POSTGRES_PASSWORD/$POSTGRES_PASSWORD/" $TARGET
# settings.yml
TARGET=/usr/share/bigbluebutton/html5-client/private/config/settings.yml
yq e -i ".public.kurento.wsUrl = \"wss://$DOMAIN/bbb-webrtc-sfu\"" $TARGET
yq e -i ".public.pads.url = \"https://$DOMAIN/pad\"" $TARGET
sleep 50
cd /bbb-apps-akka
/bbb-apps-akka/bin/bbb-apps-akka
+109
View File
@@ -0,0 +1,109 @@
#!/bin/sh
set -e
# set POSTGRES_PASSWORD from Docker secret
if test -f "/run/secrets/postgres_password"; then
pwd=$(cat /run/secrets/postgres_password)
if [ -z "$pwd" ]; then
echo >&2 "error: /run/secrets/postgres_password is empty"
exit 1
fi
echo "entrypoint.bbb-graphql-server.sh setting POSTGRES_PASSWORD"
export POSTGRES_PASSWORD="${pwd}"
unset pwd
else
echo >&2 "error: /run/secrets/postgres_password does not exist"
exit 1
fi
# set HASURA_GRAPHQL_ADMIN_SECRET from Docker secret
if test -f "/run/secrets/hasura_admin_secret"; then
pwd=$(cat /run/secrets/hasura_admin_secret)
if [ -z "$pwd" ]; then
echo >&2 "error: /run/secrets/hasura_admin_secret is empty"
exit 1
fi
echo "entrypoint.bbb-graphql-server.sh setting HASURA_GRAPHQL_ADMIN_SECRET"
export HASURA_GRAPHQL_ADMIN_SECRET="${pwd}"
unset pwd
else
echo >&2 "error: /run/secrets/hasura_admin_secret does not exist"
exit 1
fi
# for psql
export PGHOST=postgres
export PGUSER="${POSTGRES_USER}"
export PGPASSWORD="${POSTGRES_PASSWORD}"
# for hasura
export HASURA_GRAPHQL_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/hasura_app
export HASURA_GRAPHQL_METADATA_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/hasura_app
export HASURA_GRAPHQL_LOG_LEVEL=warn
export HASURA_GRAPHQL_ENABLE_CONSOLE=false
export HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL=333
export HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_BATCH_SIZE=1000
export HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_REFETCH_INTERVAL=150
export HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_BATCH_SIZE=1000
export HASURA_GRAPHQL_SERVER_PORT=8085
export HASURA_GRAPHQL_ENABLE_TELEMETRY=false
export HASURA_GRAPHQL_WEBSOCKET_KEEPALIVE=10
export HASURA_GRAPHQL_AUTH_HOOK=http://apps-akka:8901/userInfo
export HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL=http://bbb-graphql-actions:8093
export HASURA_GRAPHQL_BBB_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/bbb_graphql
# echo "Waiting for Postgres..."
# TIMEOUT=30
# i=0
# until (echo > /dev/tcp/$PGHOST/5432) 2>/dev/null; do
# i=$((i+1))
# if [ $i -ge $TIMEOUT ]; then
# echo "Postgres did not start within $TIMEOUT seconds."
# exit 1
# fi
# sleep 1
# done
# echo "Postgres is ready!"
cd /app/
# patch database url
# TODO: this should be possible upstream in BBB via an environment variable
yq e -i ".[1].configuration.connection_info.database_url = \"$HASURA_GRAPHQL_BBB_DATABASE_URL\"" metadata/databases/databases.yaml
sed -i "s/^admin_secret: .*/admin_secret: $HASURA_GRAPHQL_ADMIN_SECRET/g" /app/config.yaml
echo "SELECT 'CREATE DATABASE hasura_app' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'hasura_app')\gexec" | psql
echo "Restarting database bbb_graphql"
psql -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE datname = 'bbb_graphql'" > /dev/null
psql -c "drop database if exists bbb_graphql with (force)"
psql -c "create database bbb_graphql WITH TEMPLATE template0 LC_COLLATE 'C.UTF-8'"
psql -c "alter database bbb_graphql set timezone to 'UTC'"
echo "Creating tables in bbb_graphql"
psql -U postgres -d bbb_graphql -q -f bbb_schema.sql --set ON_ERROR_STOP=on
echo "Starting hasura-graphql-engine"
gosu nobody graphql-engine serve --log-level debug &
PID=$!
sleep 1
#Check if Hasura is ready before applying metadata
while ! netstat -tuln | grep ":$HASURA_GRAPHQL_SERVER_PORT " > /dev/null; do
echo "Waiting for Hasura's port ($HASURA_GRAPHQL_SERVER_PORT) to be ready..."
sleep 1
done
echo "Applying new metadata to Hasura"
/usr/local/bin/hasura metadata apply --skip-update-check
wait "$PID"
#graphql-engine serve --log-level debug
+1 -1
View File
@@ -3,7 +3,7 @@ set -e
# set ETHERPAD_API_KEY variable
if test -f "/run/secrets/etherpad_api_key"; then
pwd=`cat /run/secrets/etherpad_api_key`
pwd=$(cat /run/secrets/etherpad_api_key)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/etherpad_api_key is empty"
exit 1
+4 -5
View File
@@ -3,7 +3,7 @@ set -e
# set shared_secret variable
if test -f "/run/secrets/shared_secret"; then
pwd=`cat /run/secrets/shared_secret`
pwd=$(cat /run/secrets/shared_secret)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/shared_secret is empty"
exit 1
@@ -18,7 +18,7 @@ fi
# set turn_secret variable
if test -f "/run/secrets/turn_secret"; then
pwd=`cat /run/secrets/turn_secret`
pwd=$(cat /run/secrets/turn_secret)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/turn_secret is empty"
exit 1
@@ -49,9 +49,8 @@ mkdir -p /var/bigbluebutton/unpublished
chown -R bigbluebutton:bigbluebutton /var/bigbluebutton
echo "$NUMBER_OF_BACKEND_NODEJS_PROCESSES" > /tmp/NUMBER_OF_BACKEND_NODEJS_PROCESSES
sleep 100
cd /usr/share/bbb-web/
dockerize \
-template /etc/bigbluebutton/bbb-web.properties.tmpl:/etc/bigbluebutton/bbb-web.properties \
-template /usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml.tmpl:/usr/share/bbb-web/WEB-INF/classes/spring/turn-stun-servers.xml \
gosu bigbluebutton java -Dgrails.env=prod -Dserver.address=0.0.0.0 -Dserver.port=8090 -Dspring.main.allow-circular-references=true -Xms384m -Xmx384m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/bigbluebutton/diagnostics -cp WEB-INF/lib/*:/:WEB-INF/classes/:. org.springframework.boot.loader.WarLauncher
gosu bigbluebutton java -Dgrails.env=prod -Dserver.address=0.0.0.0 -Dserver.port=8090 -Dspring.main.allow-circular-references=true -Xms384m -Xmx384m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/bigbluebutton/diagnostics -cp WEB-INF/lib/*:/:WEB-INF/classes/:. org.springframework.boot.loader.launch.WarLauncher
+8 -10
View File
@@ -5,8 +5,13 @@ apk add jq su-exec
# create certs for proxy
if [ "$ENABLE_HTTPS_PROXY" == true ]; then
while [ ! -f /etc/resty-auto-ssl/storage/file/*latest ]
while true
do
for cert_file in /etc/resty-auto-ssl/storage/file/*latest; do
if [ -f "$cert_file" ]; then
break 2
fi
done
echo "ERROR: certificate doesn't exist yet."
echo "Certificate gets create on the first request to the HTTPS proxy."
echo "We will try again..."
@@ -18,16 +23,9 @@ if [ "$ENABLE_HTTPS_PROXY" == true ]; then
cat /etc/resty-auto-ssl/storage/file/*%3Alatest | jq -r '.privkey_pem' > /tmp/key.pem
fi
if [ ! -f /tmp/cert.pem ] || [ ! -f /tmp/key.pem ]; then
echo "ERROR: certificate not found, but coturn relies on it."
echo "Use either auto HTTPS proxy or"
echo "provide path to certificates in .env file"
exit 1
fi
# set turn_secret variable
if test -f "/run/secrets/turn_secret"; then
pwd=`cat /run/secrets/turn_secret`
pwd=$(cat /run/secrets/turn_secret)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/turn_secret is empty"
exit 1
@@ -41,4 +39,4 @@ else
fi
# start turnserver
su-exec nobody turnserver --static-auth-secret=${TURN_SECRET}"
su-exec nobody turnserver --static-auth-secret="${TURN_SECRET}"
+6 -5
View File
@@ -2,7 +2,7 @@
# set ETHERPAD_API_KEY variable
if test -f "/run/secrets/etherpad_api_key"; then
pwd=`cat /run/secrets/etherpad_api_key`
pwd=$(cat /run/secrets/etherpad_api_key)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/etherpad_api_key is empty"
exit 1
@@ -15,7 +15,8 @@ else
exit 1
fi
echo $ETHERPAD_API_KEY > /tmp/apikey
export NODE_ENV=production
node /opt/etherpad-lite/node_modules/ep_etherpad-lite/node/server.js --apikey /tmp/apikey
# echo $ETHERPAD_API_KEY > /tmp/apikey
#export NODE_ENV=production
#sleep 100
#node /opt/etherpad-lite/node_modules/ep_etherpad-lite/node/server.ts --apikey /tmp/apikey
/entrypoint.sh
+25 -1
View File
@@ -2,7 +2,7 @@
# set esl_password variable
if test -f "/run/secrets/fsesl_password"; then
pwd=`cat /run/secrets/fsesl_password`
pwd=$(cat /run/secrets/fsesl_password)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/fsesl_password is empty"
exit 1
@@ -80,6 +80,30 @@ fi
export SOUNDS_PATH=$SOUNDS_DIR/$(echo "$SOUNDS_LANGUAGE" | sed 's|-|/|g')
sed -i -e 's/10.7.7.10/0.0.0.0/g' /etc/freeswitch/vars.xml.tmpl
sed -i -e 's/:5066/0.0.0.0:5066/g' /etc/freeswitch/sip_profiles/external.xml
sed -i -e 's/:5066/0.0.0.0:5066/g' /etc/freeswitch/sip_profiles/internal.xml
# This deployment is IPv4-only (EXTERNAL_IPv6 is unset). Remove the IPv6 sofia
# profiles so they do not also bind the WebSocket audio port (5066).
rm -f /etc/freeswitch/sip_profiles/external-ipv6.xml
rm -f /etc/freeswitch/sip_profiles/internal-ipv6.xml
# Determine this container's IPv4 address on the internal overlay network.
FS_PEER_IP=$(getent hosts redis | awk '{print $1; exit}' || true)
OVERLAY_PREFIX=$(echo "$FS_PEER_IP" | cut -d. -f1,2)
OWN_IP=""
if [ -n "$OVERLAY_PREFIX" ]; then
OWN_IP=$(hostname -I | tr ' ' '\n' | grep "^${OVERLAY_PREFIX}\." | head -n1)
fi
[ -z "$OWN_IP" ] && OWN_IP=$(hostname -I | awk '{print $1}')
echo "entrypoint.freeswitch.sh: external profile binding IPv4, advertising ${OWN_IP}"
# Configure the IPv4 "external" profile for the overlay network.
sed -i -E 's#(<param name="rtp-ip" value=")[^"]*#\10.0.0.0#g' /etc/freeswitch/sip_profiles/external.xml
sed -i -E 's#(<param name="sip-ip" value=")[^"]*#\10.0.0.0#g' /etc/freeswitch/sip_profiles/external.xml
sed -i -E "s#(<param name=\"ext-rtp-ip\" value=\")[^\"]*#\1${OWN_IP}#g" /etc/freeswitch/sip_profiles/external.xml
sed -i -E "s#(<param name=\"ext-sip-ip\" value=\")[^\"]*#\1${OWN_IP}#g" /etc/freeswitch/sip_profiles/external.xml
dockerize \
-template /etc/freeswitch/vars.xml.tmpl:/etc/freeswitch/vars.xml \
+2 -2
View File
@@ -2,7 +2,7 @@
# set fsesl_password variable
if test -f "/run/secrets/fsesl_password"; then
pwd=`cat /run/secrets/fsesl_password`
pwd=$(cat /run/secrets/fsesl_password)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/fsesl_password is empty"
exit 1
@@ -18,7 +18,7 @@ fi
TARGET=/etc/bigbluebutton/bbb-fsesl-akka.conf
cp /etc/bigbluebutton/bbb-fsesl-akka.conf.tmpl $TARGET
sed -i "s/FSESL_PASSWORD/$FSESL_PASSWORD/" $TARGET
sed -i "s|FSESL_PASSWORD|$FSESL_PASSWORD|" $TARGET
cd /bbb-fsesl-akka
/bbb-fsesl-akka/bin/bbb-fsesl-akka
+4 -4
View File
@@ -3,13 +3,13 @@ set -e
# set DATABASE_URL with postgres_password
if test -f "/run/secrets/postgres_password"; then
pwd=`cat /run/secrets/postgres_password`
pwd=$(cat /run/secrets/postgres_password)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/postgres_password is empty"
exit 1
fi
echo "entrypoint.greenlight.sh setting DATABASE_URL"
export "DATABASE_URL"="postgres://postgres:${pwd}@postgres:5432/greenlight-v3"
export "DATABASE_URL"="postgres://postgres:${pwd}@postgres:5432/greenlight"
unset "pwd"
else
echo >&2 "error: /run/secrets/postgres_password does not exist"
@@ -18,7 +18,7 @@ fi
# set BIGBLUEBUTTON_SECRET from shared_secret
if test -f "/run/secrets/shared_secret"; then
pwd=`cat /run/secrets/shared_secret`
pwd=$(cat /run/secrets/shared_secret)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/shared_secret is empty"
exit 1
@@ -33,7 +33,7 @@ fi
# set SECRET_KEY_BASE from rails_secret
if test -f "/run/secrets/rails_secret"; then
pwd=`cat /run/secrets/rails_secret`
pwd=$(cat /run/secrets/rails_secret)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/rails_secret is empty"
exit 1
+24 -1
View File
@@ -2,7 +2,7 @@
# set esl_password variable
if test -f "/run/secrets/fsesl_password"; then
pwd=`cat /run/secrets/fsesl_password`
pwd=$(cat /run/secrets/fsesl_password)
if [ -z $pwd ]; then
echo >&2 "error: /run/secrets/fsesl_password is empty"
exit 1
@@ -15,5 +15,28 @@ else
exit 1
fi
# Determine this container's own IP on the internal overlay network.
OWN_IP=$(node -e '
const dgram = require("dgram");
const dns = require("dns");
dns.lookup("freeswitch", (err, addr, family) => {
if (err || !addr) { process.exit(1); }
const sock = dgram.createSocket(family === 6 ? "udp6" : "udp4");
sock.connect(9, addr, () => {
process.stdout.write(sock.address().address);
sock.close();
});
});
') || true
if [ -z "$OWN_IP" ]; then
echo >&2 "error: could not determine own container IP for mediasoup announcedIp"
exit 1
fi
echo "entrypoint.webrtc-sfu.sh using announcedIp=${OWN_IP} for the FreeSWITCH audio bridge"
export NODE_CONFIG="{\"mediasoup\":{\"plainRtp\":{\"listenIp\":{\"announcedIp\":\"${OWN_IP}\"}}}}"
# start npm in WORKDIR (should be /app ?)
npm start
+171
View File
@@ -0,0 +1,171 @@
# ====================================
# ADDITIONS to BigBlueButton
# ====================================
# (place a '#' before to disable them)
# HTTPS Proxy
# fully automated Lets Encrypt certificates
#ENABLE_HTTPS_PROXY=true
LETSENCRYPT_EMAIL=
# Greenlight Frontend
# https://docs.bigbluebutton.org/greenlight/gl-overview.html
ENABLE_GREENLIGHT=true
# Collabora
# Enable Collabora service
# Deactivate if you use an external collabora server
# https://www.collaboraonline.com/
ENABLE_COLLABORA=true
COLLABORA_URL=https://collabora:9980/cool
# Coturn
# Enable Coturn service
# Deactivate if you use an external coturn server
# https://github.com/coturn/coturn
ENABLE_COTURN=true
# Enable Webhooks
# used by some integrations
#ENABLE_WEBHOOKS=true
# Prometheus Exporter
# serves the bigbluebutton-exporter under following URL:
# https://yourdomain/bbb-exporter
ENABLE_PROMETHEUS_EXPORTER=true
ENABLE_PROMETHEUS_EXPORTER_OPTIMIZATION=true
# Recording
# IMPORTANT: this is currently a big privacy issues, because it will
# record everything which happens in the conference, even when the button
# suggets, that it does not.
# https://github.com/bigbluebutton/bigbluebutton/issues/9202
# make sure that you get peoples consent, before they join a room
ENABLE_RECORDING=true
REMOVE_OLD_RECORDING=true
RECORDING_MAX_AGE_DAYS=1
# ====================================
# SECRETS
# ====================================
# important! change these to any random values
SHARED_SECRET=aFCwuRTeKYSszkoumeucjdFrW2yvlcH9MlbyR6FG
ETHERPAD_API_KEY=ctaZWif5LumKdlzocTgBCgekyeixpl7RFruljwhR
RAILS_SECRET=c63fc30655cc2ea40888cd939bb6ac4cb23d2a25165ee2ba2d5490afd1109d5cf2b7edabf3b2cf38027101d89aa747c7c07263134af42d24b60b196716874bb9
POSTGRESQL_SECRET=ENoxKgDvu8CxNREHWia0W5LGieHzZQ0Le8P8nr6J
FSESL_PASSWORD=Nkp9O3GXoHZousvRUsNbo2DAzdw2euXF2AFiYuV9
TURN_SECRET=B1EXNS8BYNA3Ma0N2J4YUWJCL93FMbXA
# ====================================
# CONNECTION
# ====================================
DOMAIN=bbb-test.mirnet.org
EXTERNAL_IPv4=45.77.104.180
EXTERNAL_IPv6=2001:19f0:0:43f0:5400:5ff:fee1:106e
# STUN SERVER
# stun.freeswitch.org
STUN_IP=45.77.104.180
STUN_PORT=3478
# TURN SERVER
# uncomment and adjust following two lines to add an external TURN server
#TURN_EXT_SERVER=turns:example.org:443?transport=tcp
#TURN_EXT_SECRET=
# Allowed SIP IPs
# due to high traffic caused by bots, by default the SIP port is blocked.
# but you can allow access by your providers IP or IP ranges (comma seperated)
# Hint: if you want to allow requests from every IP, you can use 0.0.0.0/0
SIP_IP_ALLOWLIST=
# ====================================
# CUSTOMIZATION
# ====================================
# use following lines to replace the default welcome message and footer
WELCOME_MESSAGE="Welcome to <b>%%CONFNAME%%</b>!<br><br>For help on using BigBlueButton see these (short) <a href='https://www.bigbluebutton.org/html5' target='_blank'><u>tutorial videos</u></a>.<br><br>To join the audio bridge click the speaker button. Use a headset to avoid causing background noise for others."
WELCOME_FOOTER="This server is running <a href='https://docs.bigbluebutton.org/'' target='_blank'><u>BigBlueButton</u></a>."
# use following line for an additional SIP dial-in message
#WELCOME_FOOTER="This server is running <a href='https://docs.bigbluebutton.org/' target='_blank'><u>BigBlueButton</u></a>. <br><br>To join this meeting by phone, dial:<br> INSERT_YOUR_PHONE_NUMBER_HERE<br>Then enter %%CONFNUM%% as the conference PIN number."
# for a different default presentation, place the pdf file in ./conf/ and
# adjust the following path
DEFAULT_PRESENTATION=./mod/nginx/default.pdf
# language of sound announcements
# options:
# - en-ca-june - EN Canadian June
# - en-us-allison - US English Allison
# - en-us-callie - US English Callie (default)
# - de-de-daedalus3 - German by Daedalus3 (https://github.com/Daedalus3/freeswitch-german-soundfiles)
# - es-ar-mario - Spanish/Argentina Mario
# - fr-ca-june - FR Canadian June
# - pt-br-karina - Brazilian Portuguese Karina
# - ru-RU-elena - RU Russian Elena
# - ru-RU-kirill - RU Russian Kirill
# - ru-RU-vika - RU Russian Viktoriya
# - sv-se-jakob - Swedish (Sweden) Jakob
# - zh-cn-sinmei - Chinese/China Sinmei
# - zh-hk-sinmei - Chinese/Hong Kong Sinmei
SOUNDS_LANGUAGE=en-us-callie
# set to true to disable announcements "You are now (un-)muted"
DISABLE_SOUND_MUTED=false
# set to true to disable announcement "You are the only person in this conference"
DISABLE_SOUND_ALONE=false
# set to false to disable the learning dashboard
ENABLE_LEARNING_DASHBOARD=true
# ====================================
# GREENLIGHT CONFIGURATION
# ====================================
### SMTP CONFIGURATION
# Emails are required for the basic features of Greenlight to function.
# Please refer to your SMTP provider to get the values for the variables below
#SMTP_SENDER_EMAIL=
#SMTP_SENDER_NAME=
#SMTP_SERVER=
#SMTP_PORT=
#SMTP_DOMAIN=bbb-test.mirnet.org
#SMTP_USERNAME=
#SMTP_PASSWORD=
#SMTP_AUTH=
#SMTP_STARTTLS_AUTO=true
#SMTP_STARTTLS=false
#SMTP_TLS=false
#SMTP_SSL_VERIFY=true
### EXTERNAL AUTHENTICATION METHODS
#
#OPENID_CONNECT_CLIENT_ID=
#OPENID_CONNECT_CLIENT_SECRET=
#OPENID_CONNECT_ISSUER=
#OPENID_CONNECT_REDIRECT=
# To enable hCaptcha on the user sign up and sign in, define these 2 keys
#HCAPTCHA_SITE_KEY=
#HCAPTCHA_SECRET_KEY=
# Set these if you are using a Simple Storage Service (S3)
# Uncomment S3_ENDPOINT only if you are using a S3 OTHER than Amazon Web Service (AWS) S3.
#S3_ACCESS_KEY_ID=
#S3_SECRET_ACCESS_KEY=
#S3_REGION=
#S3_BUCKET=
#S3_ENDPOINT=
# Define the default locale language code (i.e. 'en' for English) from the fallowing list:
# [en, ar, fr, es]
#DEFAULT_LOCALE=en
+551
View File
@@ -0,0 +1,551 @@
# auto generated by ./scripts/generate-compose
# don't edit this directly.
services:
bbb-web:
build:
context: mod/bbb-web
additional_contexts:
- src-web=./repos/bigbluebutton/bigbluebutton-web
- src-common-message=./repos/bigbluebutton/bbb-common-message
- src-common-web=./repos/bigbluebutton/bbb-common-web
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-web:v3.0.19
restart: unless-stopped
depends_on:
- redis
- etherpad
- bbb-pads
- collabora
healthcheck:
test: wget --no-proxy --no-verbose --tries=1 --spider http://10.7.7.2:8090/bigbluebutton/api || exit 1
start_period: 2m
environment:
IGNORE_TLS_CERT_ERRORS: false
DOMAIN: ${DOMAIN}
ENABLE_RECORDING: ${ENABLE_RECORDING:-false}
SHARED_SECRET: ${SHARED_SECRET}
WELCOME_MESSAGE: ${WELCOME_MESSAGE:-}
WELCOME_FOOTER: ${WELCOME_FOOTER}
STUN_SERVER: stun:${STUN_IP}:${STUN_PORT}
ENABLE_HTTPS_PROXY: ${ENABLE_HTTPS_PROXY:-false}
TURN_SECRET: ${TURN_SECRET:-}
TURN_EXT_SERVER: ${TURN_EXT_SERVER:-}
TURN_EXT_SECRET: ${TURN_EXT_SECRET:-}
ENABLE_LEARNING_DASHBOARD: ${ENABLE_LEARNING_DASHBOARD:-true}
COLLABORA_URL: ${COLLABORA_URL:-https://collabora:9980/cool}
# volumes:
# - ./data/bigbluebutton:/var/bigbluebutton
# - ./data/freeswitch-meetings:/var/freeswitch/meetings
# - type: bind
# source: ./fairblue.js
# target: /var/www/bigbluebutton-default/assets/plugins/fairblue/fairblue.js
# - type: bind
# source: ./manifest.json
# target: /var/www/bigbluebutton-default/assets/plugins/fairblue/manifest.json
configs:
- source: bbb_web_plugin_config
target: /etc/bigbluebutton/bbb-web.properties.tmpl
volumes:
- ./bbb-release:/etc/bigbluebutton/bigbluebutton-release
networks:
bbb-net:
ipv4_address: 10.7.7.2
freeswitch:
container_name: bbb-freeswitch
build:
context: mod/freeswitch
additional_contexts:
- freeswitch=./repos/freeswitch/
- build-files=./repos/bigbluebutton/build/packages-template/bbb-freeswitch-core/
- fs-config=./repos/bigbluebutton/bbb-voice-conference/config/freeswitch/conf/
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-freeswitch:v1.10.12-v3.0.19
restart: unless-stopped
cap_add:
- IPC_LOCK
- NET_ADMIN
- NET_RAW
- NET_BROADCAST
- SYS_NICE
- SYS_RESOURCE
environment:
DOMAIN: ${DOMAIN}
EXTERNAL_IPv4: ${EXTERNAL_IPv4}
EXTERNAL_IPv6: ${EXTERNAL_IPv6:-::1}
SIP_IP_ALLOWLIST: ${SIP_IP_ALLOWLIST:-}
DISABLE_SOUND_MUTED: ${DISABLE_SOUND_MUTED:-false}
DISABLE_SOUND_ALONE: ${DISABLE_SOUND_ALONE:-false}
SOUNDS_LANGUAGE: ${SOUNDS_LANGUAGE:-en-us-callie}
ESL_PASSWORD: ${FSESL_PASSWORD:-ClueCon}
volumes:
- ./conf/sip_profiles:/etc/freeswitch/sip_profiles/external-dialin
- ./data/freeswitch-meetings:/var/freeswitch/meetings
networks:
bbb-net:
ipv4_address: 10.7.7.10
logging:
# reduce logs to a minimum, so `docker compose logs -f` still works
driver: "local"
options:
max-size: "10k"
max-file: "1"
compress: "false"
nginx:
build:
context: mod/nginx
additional_contexts:
- src-learning-dashboard=./repos/bigbluebutton/bbb-learning-dashboard
- src-playback=./repos/bbb-playback
- src-html5=./repos/bigbluebutton/bigbluebutton-html5
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
TAG_BBB: v3.0.19
image: alangecker/bbb-docker-nginx:v3.0.19-v5.4.3-1.29
restart: unless-stopped
configs:
- source: bbb_nginx_fairblue_config
target: /etc/nginx/conf.d/default.conf
volumes:
- ./data/bigbluebutton:/var/bigbluebutton
- ${DEFAULT_PRESENTATION:-/dev/null}:/www/default.pdf:ro
- ./fairblue.js:/www/fairblue.js:ro
- ./manifest.json:/www/manifest.json:ro
ports:
# make sure nginx ports are also still available under the
# IPs 127.0.0.1 & 10.7.7.1 for backwards compatibility with exiting setup
# Warning: deprecated! this gets removed at some point
# Use 10.7.7.34 for new setups
- "127.0.0.1:48082:48082"
- "127.0.0.1:48081:48081"
- "127.0.0.1:48087:48087"
- "10.7.7.1:48082:48082"
- "10.7.7.1:48081:48081"
- "10.7.7.1:48087:48087"
networks:
bbb-net:
ipv4_address: 10.7.7.34
tmpfs:
- /tmp
extra_hosts:
- "host.docker.internal:10.7.7.1"
- "bbb-web:10.7.7.2"
- "etherpad:10.7.7.4"
- "webrtc-sfu:10.7.7.1"
- "greenlight:10.7.7.21"
- "bbb-graphql-server:10.7.7.31"
- "bbb-graphql-middleware:10.7.7.32"
etherpad:
build:
context: mod/etherpad
additional_contexts:
- plugin=./repos/bbb-etherpad-plugin
- skin=./repos/bbb-etherpad-skin
args:
TAG_ETHERPAD: "2.4.2"
image: alangecker/bbb-docker-etherpad:2.4.2-s8328b77-p88f3f6b
restart: unless-stopped
depends_on:
- redis
- collabora
environment:
ETHERPAD_API_KEY: ${ETHERPAD_API_KEY}
COLLABORA_URL: ${COLLABORA_URL:-https://collabora:9980/cool}
networks:
bbb-net:
ipv4_address: 10.7.7.4
bbb-pads:
build:
context: mod/bbb-pads
additional_contexts:
- src=./repos/bbb-pads
image: alangecker/bbb-docker-pads:v1.5.6
restart: unless-stopped
depends_on:
- redis
- etherpad
environment:
ETHERPAD_API_KEY: ${ETHERPAD_API_KEY}
networks:
bbb-net:
ipv4_address: 10.7.7.18
bbb-export-annotations:
build:
context: mod/bbb-export-annotations
additional_contexts:
src: ./repos/bigbluebutton/bbb-export-annotations
image: alangecker/bbb-docker-bbb-export-annotations:v3.0.19
restart: unless-stopped
depends_on:
- redis
- etherpad
- bbb-pads
networks:
# need connections to:
# https://github.com/bigbluebutton/bigbluebutton/blob/v2.7.0/bbb-export-annotations/config/settings.json
# "bbbWebAPI": "http://127.0.0.1:8090", -> bbb-web
# "bbbPadsAPI": "http://127.0.0.1:9002", -> bbb-pads
bbb-net:
ipv4_address: 10.7.7.19
volumes:
- ./data/bigbluebutton:/var/bigbluebutton
tmpfs:
- /tmp
redis:
image: redis:8.4-alpine
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 1s
timeout: 3s
retries: 30
networks:
bbb-net:
ipv4_address: 10.7.7.5
volumes:
- ./data/redis:/data
webrtc-sfu:
build:
context: mod/webrtc-sfu
additional_contexts:
- source=./repos/bbb-webrtc-sfu
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-webrtc-sfu:v2.21.2
restart: unless-stopped
depends_on:
- redis
- freeswitch
environment:
ESL_PASSWORD: ${FSESL_PASSWORD:-ClueCon}
MS_WEBRTC_LISTEN_IPS: '[{"ip":"::", "announcedIp":"${EXTERNAL_IPv6}"}, {"ip":"${EXTERNAL_IPv4}", "announcedIp":"${EXTERNAL_IPv4}"}]'
volumes:
- ./data/mediasoup:/var/mediasoup
tmpfs:
- /var/log/bbb-webrtc-sfu
network_mode: host
security_opt:
- seccomp:unconfined # allow io_uring access for mediasoup
ulimits:
memlock: -1 # allow io_uring_register_buffers to allocate enough ram
fsesl-akka:
build:
context: mod/fsesl-akka
additional_contexts:
- src-common-message=./repos/bigbluebutton/bbb-common-message
- src-fsesl-client=./repos/bigbluebutton/bbb-fsesl-client
- src-fsesl-akka=./repos/bigbluebutton/akka-bbb-fsesl
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-fsesl-akka:v3.0.19
restart: unless-stopped
depends_on:
- redis
- freeswitch
environment:
FSESL_PASSWORD: ${FSESL_PASSWORD:-ClueCon}
networks:
bbb-net:
ipv4_address: 10.7.7.14
apps-akka:
build:
context: mod/apps-akka
additional_contexts:
- src-common-message=./repos/bigbluebutton/bbb-common-message
- src-apps-akka=./repos/bigbluebutton/akka-bbb-apps
- src-config=./repos/bigbluebutton/bigbluebutton-html5/private/config/
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
TAG_BBB: v3.0.19
image: alangecker/bbb-docker-apps-akka:v3.0.19
restart: unless-stopped
depends_on:
- redis
- postgres
environment:
DOMAIN: ${DOMAIN}
SHARED_SECRET: ${SHARED_SECRET}
POSTGRES_PASSWORD: ${POSTGRESQL_SECRET:-password}
volumes:
- ./data/freeswitch-meetings:/var/freeswitch/meetings
- ./conf/bbb-html5.yml:/etc/bigbluebutton/bbb-html5.yml:ro
networks:
bbb-net:
ipv4_address: 10.7.7.15
bbb-graphql-server:
build:
context: mod/bbb-graphql-server
additional_contexts:
- src=./repos/bigbluebutton/bbb-graphql-server
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
GRAPHQL_ENGINE_TAG: v2.48.1
image: alangecker/bbb-docker-graphql-server:v3.0.19
depends_on:
- postgres
- bbb-web
- apps-akka
- bbb-graphql-actions
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${POSTGRESQL_SECRET:-password}
HASURA_GRAPHQL_ADMIN_SECRET: TODO_CHANGE_ME
networks:
bbb-net:
ipv4_address: 10.7.7.31
bbb-graphql-actions:
build:
context: mod/bbb-graphql-actions
additional_contexts:
- src=./repos/bigbluebutton/bbb-graphql-actions
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-graphql-actions:v3.0.19
restart: unless-stopped
depends_on:
- redis
- apps-akka
networks:
bbb-net:
ipv4_address: 10.7.7.30
bbb-graphql-middleware:
build:
context: mod/bbb-graphql-middleware
additional_contexts:
- src=./repos/bigbluebutton/bbb-graphql-middleware
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
image: alangecker/bbb-docker-graphql-middleware:v3.0.19
restart: unless-stopped
depends_on:
- bbb-graphql-server
- bbb-graphql-actions
- bbb-web
- redis
networks:
bbb-net:
ipv4_address: 10.7.7.32
collabora:
image: collabora/code:latest
restart: unless-stopped
tmpfs:
- /tmp
networks:
bbb-net:
ipv4_address: 10.7.7.20
# disable logging (way to verbose)
logging:
driver: none
periodic:
build: mod/periodic
image: alangecker/bbb-docker-periodic:v3.0.0
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data/bigbluebutton:/var/bigbluebutton
- ./data/mediasoup:/var/mediasoup
tmpfs:
- /var/log/bigbluebutton
environment:
ENABLE_RECORDING: ${ENABLE_RECORDING}
REMOVE_OLD_RECORDING: ${REMOVE_OLD_RECORDING}
RECORDING_MAX_AGE_DAYS: ${RECORDING_MAX_AGE_DAYS}
networks:
bbb-net:
ipv4_address: 10.7.7.12
# recordings
recordings:
build:
context: mod/recordings
additional_contexts:
- record-core=./repos/bigbluebutton/record-and-playback/core
- presentation=./repos/bigbluebutton/record-and-playback/presentation
- bbb-conf=./repos/bigbluebutton/bigbluebutton-config
args:
BBB_BUILD_TAG: v3.0.x-release--2025-10-30-133835
TAG_BBB_PRESENTATION_VIDEO: "5.0.0"
image: alangecker/bbb-docker-recordings:v3.0.19
restart: unless-stopped
depends_on:
- redis
- bbb-pads
environment:
DOMAIN: ${DOMAIN}
SHARED_SECRET: ${SHARED_SECRET}
volumes:
- ./data/bigbluebutton:/var/bigbluebutton
- ./data/freeswitch-meetings:/var/freeswitch/meetings
- ./data/mediasoup:/var/mediasoup
- ./data/bbb-webrtc-recorder:/var/lib/bbb-webrtc-recorder
tmpfs:
- /var/log/bigbluebutton
- /tmp
networks:
bbb-net:
ipv4_address: 10.7.7.16
bbb-webrtc-recorder:
build:
context: mod/bbb-webrtc-recorder
additional_contexts:
- src=./repos/bbb-webrtc-recorder
image: alangecker/bbb-docker-webrtc-recorder:v0.13.1
depends_on:
- redis
volumes:
- ./data/bbb-webrtc-recorder:/var/lib/bbb-webrtc-recorder
# WebRTC connection to bbb-webrtc-sfu seem to
# only to work via the external IP
network_mode: host
extra_hosts:
- "redis:10.7.7.5"
haproxy:
build: mod/haproxy
image: alangecker/bbb-haproxy:3.0.9
restart: unless-stopped
volumes:
- ./data/haproxy/letsencrypt:/etc/letsencrypt
- ./mod/haproxy/haproxy.cfg:/etc/haproxy/haproxy.cfg
- ./mod/haproxy/protocolmap:/etc/haproxy/protocolmap
environment:
- IGNORE_TLS_CERT_ERRORS=false
- CERT1=${DOMAIN}
- EMAIL=${LETSENCRYPT_EMAIL}
ports:
- 80:80
- 443:443
networks:
bbb-net:
ipv4_address: 10.7.7.35
# coturn
coturn:
image: coturn/coturn:4.8-alpine
restart: unless-stopped
command:
- "--external-ip=${EXTERNAL_IPv4}/${EXTERNAL_IPv4}"
- "--external-ip=${EXTERNAL_IPv6:-::1}/${EXTERNAL_IPv6:-::1}"
- "--static-auth-secret=${TURN_SECRET}"
- "--allowed-peer-ip=${EXTERNAL_IPv4}"
- "--relay-ip=${EXTERNAL_IPv4}"
- "--relay-ip=${EXTERNAL_IPv6:-::1}"
volumes:
- ./mod/coturn/turnserver.conf:/etc/coturn/turnserver.conf
- ./data/coturn:/var/lib/coturn
network_mode: host
# greenlight
greenlight:
image: bigbluebutton/greenlight:v3.6.3
restart: unless-stopped
env_file: .env
depends_on:
- postgres
- redis
environment:
DATABASE_URL: postgres://postgres:${POSTGRESQL_SECRET:-password}@postgres:5432/greenlight
REDIS_URL: redis://redis:6379
BIGBLUEBUTTON_ENDPOINT: https://${DOMAIN}/bigbluebutton/api
BIGBLUEBUTTON_SECRET: ${SHARED_SECRET}
SECRET_KEY_BASE: ${RAILS_SECRET}
RELATIVE_URL_ROOT: /
volumes:
- ./data/greenlight:/usr/src/app/storage
networks:
bbb-net:
ipv4_address: 10.7.7.21
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_MULTIPLE_DATABASES: bbb_graphql,hasura_app,greenlight
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${POSTGRESQL_SECRET:-password}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- ./data/postgres:/var/lib/postgresql/data
- ./mod/postgres/initdb.sh:/docker-entrypoint-initdb.d/initdb.sh
networks:
bbb-net:
ipv4_address: 10.7.7.22
# prometheus
prometheus-exporter:
image: greenstatic/bigbluebutton-exporter:latest
restart: unless-stopped
environment:
API_BASE_URL: http://10.7.7.34:48087/bigbluebutton/api/
API_SECRET: ${SHARED_SECRET}
RECORDINGS_METRICS_READ_FROM_DISK: "${ENABLE_PROMETHEUS_EXPORTER_OPTIMIZATION:-false}"
networks:
bbb-net:
ipv4_address: 10.7.7.33
volumes:
- ./data/bigbluebutton:/var/bigbluebutton:ro
# the exporter requires /etc/bigbluebutton/bigbluebutton-release
tmpfs:
- /etc/bigbluebutton:mode=777
entrypoint: sh -c 'echo "BIGBLUEBUTTON_RELEASE=2.7.3" > /etc/bigbluebutton/bigbluebutton-release && python server.py'
interpretation-data-server:
image: registry.osalliance.com/fairblue/interpretation-data-server:1.1.0
container_name: interpretation-data-server
restart: unless-stopped
networks:
bbb-net:
ipv4_address: 10.7.7.77
networks:
bbb-net:
ipam:
driver: default
config:
- subnet: "10.7.7.0/24"
configs:
bbb_web_plugin_config:
file: ./conf/bigbluebutton.properties.tmpl
bbb_nginx_fairblue_config:
file: ./conf/nginx_default.conf
Submodule
+1
Submodule fake/docker added at d38784bc84
+56
View File
@@ -0,0 +1,56 @@
2026-07-20T01:31:09.110470872Z 2026-07-20 01:31:09.043201 86.90% [NOTICE] switch_channel.c:1142 New Channel sofia/external/GLOBAL_AUDIO_589586747@freeswitch [271856e5-e8a1-46f8-8ea9-469f32b5c2f6]
2026-07-20T01:31:09.110472989Z 2026-07-20 01:31:09.043201 86.90% [INFO] sofia.c:10460 sofia/external/GLOBAL_AUDIO_589586747@freeswitch receiving invite from 10.0.17.49:51982 version: 1.10.12-release 64bit call-id: 8ueo9kob3dpsijhuvfpc
2026-07-20T01:31:09.110477970Z 2026-07-20 01:31:09.043201 86.90% [INFO] mod_dialplan_xml.c:639 Processing GLOBAL_AUDIO_589586747 <GLOBAL_AUDIO_589586747>->589586747 in context public
2026-07-20T01:31:09.110480165Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch set(outside_call=true)
2026-07-20T01:31:09.110482238Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch export(RFC2822_DATE=Mon, 20 Jul 2026 01:31:09 +0000)
2026-07-20T01:31:09.110484507Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch set(presence_data=from_bbb-webrtc-sfu)
2026-07-20T01:31:09.110486405Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch set(bbb_authorized=true)
2026-07-20T01:31:09.110489335Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch set(rtp_manual_rtp_bugs=ACCEPT_ANY_PACKETS)
2026-07-20T01:31:09.110491251Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch set(jb_use_timestamps=true)
2026-07-20T01:31:09.110493140Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch transfer(589586747 XML default)
2026-07-20T01:31:09.110495051Z 2026-07-20 01:31:09.043201 86.90% [NOTICE] switch_ivr.c:2303 Transfer sofia/external/GLOBAL_AUDIO_589586747@freeswitch to XML[589586747@default]
2026-07-20T01:31:09.110505318Z 2026-07-20 01:31:09.043201 86.90% [INFO] mod_dialplan_xml.c:639 Processing GLOBAL_AUDIO_589586747 <GLOBAL_AUDIO_589586747>->589586747 in context default
2026-07-20T01:31:09.110507478Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch set(jitterbuffer_msec=100:250)
2026-07-20T01:31:09.110509420Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch set(rtp_jitter_buffer_plc=true)
2026-07-20T01:31:09.110511339Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch set(rtp_jitter_buffer_during_bridge=true)
2026-07-20T01:31:09.110513253Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch set(suppress_cng=true)
s2026-07-20T01:31:09.110515305Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch answer()
2026-07-20T01:31:09.110517671Z 2026-07-20 01:31:09.063199 86.90% [NOTICE] sofia_media.c:90 Pre-Answer sofia/external/GLOBAL_AUDIO_589586747@freeswitch!
2026-07-20T01:31:09.110519639Z 2026-07-20 01:31:09.063199 86.90% [NOTICE] mod_dptools.c:1406 Channel [sofia/external/GLOBAL_AUDIO_589586747@freeswitch] has been answered
2026-07-20T01:31:09.110521553Z EXECUTE [depth=0] sofia/external/GLOBAL_AUDIO_589586747@freeswitch conference(589586747@cdquality)
2026-07-20T01:31:09.110523500Z 2026-07-20 01:31:09.063199 86.90% [ERR] switch_core_video.c:3099 This function is not available, libpng not installed
2026-07-20T01:31:09.110525428Z 2026-07-20 01:31:09.063199 86.90% [INFO] switch_ivr_async.c:221 Digit parser mod_conference: Setting realm to 'conf'
2026-07-20T01:31:09.110527394Z 2026-07-20 01:31:09.103202 86.90% [NOTICE] switch_channel.c:1142 New Channel sofia/external/w_81vinciuq2xj_1@freeswitch [71a00810-51e5-4b57-a266-14a15570042c]
2026-07-20T01:31:24.691386530Z 2026-07-20 01:31:09.103202 86.90% [INFO] sofia.c:10460 sofia/external/w_81vinciuq2xj_1@freeswitch receiving invite from 10.0.17.49:51986 version: 1.10.12-release 64bit call-id: f1upd0juujerhkv8911f
2026-07-20T01:31:24.691431957Z 2026-07-20 01:31:09.103202 86.90% [INFO] mod_dialplan_xml.c:639 Processing w_81vinciuq2xj_1-bbbID-blabla <w_81vinciuq2xj_1>->589586747 in context public
{2026-07-20T01:31:24.691440644Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch set(outside_call=true)
2026-07-20T01:31:24.691447482Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch export(RFC2822_DATE=Mon, 20 Jul 2026 01:31:09 +0000)
2026-07-20T01:31:24.691454102Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch set(presence_data=from_bbb-webrtc-sfu)
}2026-07-20T01:31:24.691460852Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch set(bbb_authorized=true)
2026-07-20T01:31:24.691467405Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch set(rtp_manual_rtp_bugs=ACCEPT_ANY_PACKETS)
2026-07-20T01:31:24.691473908Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch set(jb_use_timestamps=true)
2026-07-20T01:31:24.691480834Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch set(conference_member_flags=mute)
2026-07-20T01:31:24.691488056Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch transfer(589586747 XML default)
2026-07-20T01:31:24.691494737Z 2026-07-20 01:31:09.103202 86.90% [NOTICE] switch_ivr.c:2303 Transfer sofia/external/w_81vinciuq2xj_1@freeswitch to XML[589586747@default]
2026-07-20T01:31:24.691501160Z 2026-07-20 01:31:09.103202 86.90% [INFO] mod_dialplan_xml.c:639 Processing w_81vinciuq2xj_1-bbbID-blabla <w_81vinciuq2xj_1>->589586747 in context default
2026-07-20T01:31:24.691507835Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch set(jitterbuffer_msec=100:250)
2026-07-20T01:31:24.691514326Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch set(rtp_jitter_buffer_plc=true)
2026-07-20T01:31:24.691520938Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch set(rtp_jitter_buffer_during_bridge=true)
{2026-07-20T01:31:24.691606427Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch set(suppress_cng=true)
m2026-07-20T01:31:24.691638435Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch answer()
2026-07-20T01:31:24.691649110Z 2026-07-20 01:31:09.103202 86.90% [NOTICE] sofia_media.c:90 Pre-Answer sofia/external/w_81vinciuq2xj_1@freeswitch!
2026-07-20T01:31:24.691658885Z 2026-07-20 01:31:09.103202 86.90% [NOTICE] mod_dptools.c:1406 Channel [sofia/external/w_81vinciuq2xj_1@freeswitch] has been answered
2026-07-20T01:31:24.691666241Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch log(INFO Channel is going to be HELD and MUTED on creation 71a00810-51e5-4b57-a266-14a15570042c)
2026-07-20T01:31:24.691673218Z 2026-07-20 01:31:09.103202 86.90% [INFO] mod_dptools.c:1865 Channel is going to be HELD and MUTED on creation 71a00810-51e5-4b57-a266-14a15570042c
2026-07-20T01:31:24.691681041Z 2026-07-20 01:31:09.103202 86.90% [INFO] sofia_glue.c:1659 sofia/external/w_81vinciuq2xj_1@freeswitch sending invite call-id: (null)
2026-07-20T01:31:24.691688556Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch set(api_result=+OK Success
!2026-07-20T01:31:24.691699978Z )
2026-07-20T01:31:24.691797389Z EXECUTE [depth=0] sofia/external/w_81vinciuq2xj_1@freeswitch conference(589586747@cdquality)
2026-07-20T01:31:24.691987577Z 2026-07-20 01:31:09.103202 86.90% [ERR] switch_core_video.c:3099 This function is not available, libpng not installed
2026-07-20T01:31:24.692061987Z 2026-07-20 01:31:09.103202 86.90% [INFO] switch_ivr_async.c:221 Digit parser mod_conference: Setting realm to 'conf'
2026-07-20T01:31:24.692146413Z 2026-07-20 01:31:23.583250 88.60% [NOTICE] sofia.c:1065 Hangup sofia/external/w_81vinciuq2xj_1@freeswitch [CS_EXECUTE] [NORMAL_CLEARING]
2026-07-20T01:31:24.692215690Z 2026-07-20 01:31:23.583250 88.60% [INFO] conference_loop.c:1668 Channel leaving conference, cause: NORMAL_CLEARING
2026-07-20T01:31:24.692357970Z 2026-07-20 01:31:23.583250 88.60% [NOTICE] switch_core_session.c:1762 Session 2 (sofia/external/w_81vinciuq2xj_1@freeswitch) Ended
2026-07-20T01:31:24.692366394Z 2026-07-20 01:31:23.583250 88.60% [NOTICE] switch_core_session.c:1766 Close Channel sofia/external/w_81vinciuq2xj_1@freeswitch [CS_DESTROY]
2026-07-20T01:31:24.692372777Z 2026-07-20 01:31:24.683234 88.83% [NOTICE] switch_channel.c:1142 New Channel sofia/external/w_81vinciuq2xj_2@freeswitch [79d0dc8d-a994-4382-b44d-33ee7cc8d7de]
2026-07-20T01:31:24.692377955Z 2026-07-20 01:31:24.683234 88.83% [INFO] sofia.c:10460 sofia/external/w_81vinciuq2xj_2@freeswitch receiving invite from 10.0.17.49:47770 version: 1.10.12-release 64bit call-id: 96bhge116g2u7gdeqq6f
-26
View File
@@ -1,26 +0,0 @@
#!/bin/sh
set -e
host=${HOSTNAME:-$(hostname -f)}
# shut down again
mongod --pidfilepath /tmp/docker-entrypoint-temp-mongod.pid --shutdown
# restart again binding to 0.0.0.0 to allow a replset with 10.7.7.6
mongod --oplogSize 8 --replSet rs0 --noauth \
--config /tmp/docker-entrypoint-temp-config.json \
--bind_ip 0.0.0.0 --port 27017 \
--tlsMode disabled \
--logpath /proc/1/fd/1 --logappend \
--pidfilepath /tmp/docker-entrypoint-temp-mongod.pid --fork
# init replset with defaults
mongo 10.7.7.6 --eval "rs.initiate({
_id: 'rs0',
members: [ { _id: 0, host: '10.7.7.6:27017' } ]
})"
echo "Waiting to become a master"
echo 'while (!db.isMaster().ismaster) { sleep(100); }' | mongo
echo "I'm the master!"
+43
View File
@@ -0,0 +1,43 @@
ARG BBB_BUILD_TAG
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder
COPY --from=src-common-message / /bbb-common-message
# build bbb-common-message
RUN cd /bbb-common-message && ./deploy.sh
# ===================================================
ARG TAG_APPS_AKKA
COPY --from=src-apps-akka / /source
# compile and unzip bin
RUN cd /source \
&& sbt universal:packageBin \
&& unzip /source/target/universal/bbb-apps-akka-0.0.4.zip -d /
# ===================================================
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder-settings
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.44.3/yq_linux_amd64 && chmod a+x /usr/local/bin/yq
COPY --from=src-config /settings.yml /settings.yml
ARG TAG_BBB
RUN yq e -i ".public.app.bbbServerVersion = \"$TAG_BBB\"" /settings.yml
RUN yq e -i ".public.app.html5ClientBuild = \"$TAG_BBB\"" /settings.yml
# ===================================================
FROM alangecker/bbb-docker-base-java
COPY --from=builder-settings /usr/local/bin/yq /usr/local/bin/yq
COPY --from=builder /bbb-apps-akka-0.0.4 /bbb-apps-akka
COPY bbb-apps-akka.conf /etc/bigbluebutton/bbb-apps-akka.conf.tmpl
COPY logback.xml /bbb-apps-akka/conf/logback.xml
COPY entrypoint.sh /entrypoint.sh
COPY --from=builder-settings --chown=bigbluebutton:bigbluebutton /settings.yml /usr/share/bigbluebutton/html5-client/private/config/settings.yml
USER bigbluebutton
ENTRYPOINT /entrypoint.sh
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh -e
# bbb-apps-akka.conf
TARGET=/etc/bigbluebutton/bbb-apps-akka.conf
cp /etc/bigbluebutton/bbb-apps-akka.conf.tmpl $TARGET
sed -i "s/DOMAIN/$DOMAIN/" $TARGET
sed -i "s/SHARED_SECRET/$SHARED_SECRET/" $TARGET
sed -i "s/POSTGRES_PASSWORD/$POSTGRES_PASSWORD/" $TARGET
# settings.yml
TARGET=/usr/share/bigbluebutton/html5-client/private/config/settings.yml
yq e -i ".public.kurento.wsUrl = \"wss://$DOMAIN/bbb-webrtc-sfu\"" $TARGET
yq e -i ".public.pads.url = \"https://$DOMAIN/pad\"" $TARGET
cd /bbb-apps-akka
/bbb-apps-akka/bin/bbb-apps-akka
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"} %-5level %logger{35} - %msg%n</Pattern>
</layout>
</appender>
<logger name="akka" level="INFO" />
<logger name="org.bigbluebutton" level="DEBUG" />
<logger name="io.lettuce" level="INFO" />
<logger name="slick" level="INFO" />
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
+24
View File
@@ -0,0 +1,24 @@
FROM eclipse-temurin:17-jre-jammy
RUN apt-get update && apt-get install -y \
wget unzip gosu locales \
imagemagick xpdf-utils curl \
&& sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
# add user & group
RUN groupadd -g 998 bigbluebutton \
&& useradd -m -u 998 -g bigbluebutton bigbluebutton \
&& mkdir /etc/bigbluebutton \
&& chown bigbluebutton:bigbluebutton /etc/bigbluebutton
# add dockerize
ENV DOCKERIZE_VERSION v0.7.0
RUN wget -q https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
+23
View File
@@ -0,0 +1,23 @@
// include default config from upstream
include "/bbb-apps-akka/conf/application.conf"
redis.host = "redis"
services {
bbbWebAPI="https://DOMAIN/bigbluebutton/api"
sharedSecret="SHARED_SECRET"
graphqlMiddlewareAPI = "http://bbb-graphql-middleware:8378"
}
http {
interface = "0.0.0.0"
}
postgres {
properties = {
serverName = "postgres"
portNumber = "5432"
databaseName = "bbb_graphql"
user = "postgres"
password = "POSTGRES_PASSWORD"
}
}
+23
View File
@@ -0,0 +1,23 @@
FROM node:22-bookworm-slim AS builder
COPY --from=src / /bbb-export-annotations
RUN cd /bbb-export-annotations && npm ci && npm install
# --------------------
FROM node:22-bookworm-slim
RUN groupadd -g 998 bigbluebutton \
&& useradd -m -u 998 -g bigbluebutton bigbluebutton
RUN apt update && apt install -y \
nodejs npm cairosvg ghostscript imagemagick nodejs poppler-utils
COPY --from=builder /bbb-export-annotations /bbb-export-annotations
COPY ./config/settings.json /bbb-export-annotations/config/settings.json
USER bigbluebutton
WORKDIR /bbb-export-annotations
ENV NODE_ENV=production
ENTRYPOINT npm start
@@ -0,0 +1,40 @@
{
"log": {
"level": "info",
"msgName": "PresAnnStatusMsg"
},
"shared": {
"presAnnDropboxDir": "/tmp/pres-ann-dropbox",
"cairosvg": "/usr/bin/cairosvg",
"ghostscript": "/usr/bin/gs"
},
"process": {
"maxImageWidth": 1440,
"maxImageHeight": 1080,
"pointsPerInch": 72,
"pixelsPerInch": 96,
"cairoSVGUnsafeFlag": false
},
"notifier": {
"pod_id": "DEFAULT_PRESENTATION_POD",
"is_downloadable": "false",
"msgName": "NewPresFileAvailableMsg"
},
"bbbWebAPI": "http://bbb-web:8090",
"bbbPadsAPI": "http://bbb-pads:9002",
"redis": {
"host": "redis",
"port": 6379,
"password": null,
"channels": {
"queue": "exportJobs",
"publish": "to-akka-apps-redis-channel"
}
},
"fonts": {
"draw": "/usr/local/share/fonts/Shantell_Sans-Tldrawish.woff2",
"sans": "/usr/local/share/fonts/IBMPlexSans-Medium.woff2",
"serif": "/usr/local/share/fonts/IBMPlexSerif-Medium.woff2",
"mono": "/usr/local/share/fonts/IBMPlexMono-Medium.woff2"
}
}
+4
View File
@@ -0,0 +1,4 @@
location /bbb-exporter {
proxy_pass http://prometheus-exporter:9688;
proxy_http_version 1.1;
}
+34
View File
@@ -0,0 +1,34 @@
ARG BBB_BUILD_TAG
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder
COPY --from=src ./ /src
RUN cd /src && \
npm ci --no-progress && \
npm run build
# delete node_modules (it should create a fresh one inside /src/dist/)
RUN rm -rf /src/node_modules
RUN cd /src/dist && \
mv index.js bbb-graphql-actions.js && \
cp ../package.json ../package-lock.json . && \
npm ci --no-progress --omit=dev
# ------------------------------
FROM node:22-bookworm-slim
RUN groupadd -g 2062 app \
&& useradd -m -u 2063 -g app app
USER app
WORKDIR /app
ENV SERVER_HOST 0.0.0.0
ENV BBB_REDIS_HOST redis
ENV NODE_ENV=production
COPY --from=builder /src/dist /app
CMD [ "node", "/app/bbb-graphql-actions.js" ]
+16
View File
@@ -0,0 +1,16 @@
ARG BBB_BUILD_TAG
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder
RUN apt-get update && apt-get install -y gosu
# allow any user to use node in /root/.nvm
RUN chmod 755 /root
COPY dev-entrypoint.sh /dev-entrypoint.sh
ENTRYPOINT [ "/dev-entrypoint.sh" ]
WORKDIR /app
ENV SERVER_HOST 0.0.0.0
ENV BBB_REDIS_HOST redis
CMD [ "npm install && npm start" ]
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
# get owner of /app
OWNER="$(stat -c '%u' "/app")"
GROUP="$(stat -c '%g' "/app")"
useradd --home-dir /tmp -u $OWNER user || /bin/true
# run with same user to avoid any issues
# with file permissions
. /root/.nvm/nvm.sh
gosu $OWNER:$GROUP bash -c "$@"
+12
View File
@@ -0,0 +1,12 @@
ARG BBB_BUILD_TAG
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder
COPY --from=src / /src/
RUN cd /src/ && CGO_ENABLED=0 go build -o bbb-graphql-middleware cmd/bbb-graphql-middleware/main.go
# ------------------------------
FROM alpine
COPY --from=builder /src/bbb-graphql-middleware /app/bbb-graphql-middleware
COPY --from=builder /src/config/config.yml /usr/share/bbb-graphql-middleware/config.yml
COPY config.yml /etc/bigbluebutton/bbb-graphql-middleware.yml
CMD [ "/app/bbb-graphql-middleware" ]
@@ -0,0 +1,8 @@
ARG BBB_BUILD_TAG
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder
WORKDIR /app
ENV GOPATH /gopath
CMD ["go", "run", "cmd/bbb-graphql-middleware/main.go", "--signal", "SIGTERM"]
+15
View File
@@ -0,0 +1,15 @@
server:
listen_host: 0.0.0.0
listen_port: 8378
redis:
host: redis
port: 6379
password: ""
hasura:
url: ws://nginx:8185/v1/graphql
graphql-actions:
url: http://bbb-graphql-actions:8093
auth_hook:
url: http://bbb-web:8090/bigbluebutton/connection/checkGraphqlAuthorization
session_vars_hook:
url: http://apps-akka:8901/userInfo
+25
View File
@@ -0,0 +1,25 @@
ARG BBB_BUILD_TAG
ARG GRAPHQL_ENGINE_TAG
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder
RUN curl -L https://github.com/hasura/graphql-engine/raw/stable/cli/get.sh | INSTALL_PATH=/usr/local/bin VERSION=v2.44.0 bash
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 && chmod a+x /usr/local/bin/yq
# ----------------------------
FROM hasura/graphql-engine:$GRAPHQL_ENGINE_TAG
# install netstat, required for start script
RUN apt-get update && apt-get install -y net-tools gosu
COPY --from=builder /usr/local/bin/yq /usr/local/bin/yq
COPY --from=builder /usr/local/bin/hasura /usr/local/bin/hasura
COPY --from=src /bbb_schema.sql /app/
COPY --from=src /metadata /app/metadata
COPY config.yaml /app/config.yaml
COPY entrypoint.sh /entrypoint.sh
COPY start.sh /app/start.sh
ENTRYPOINT [ "/entrypoint.sh" ]
CMD [ "/app/start.sh" ]
+7
View File
@@ -0,0 +1,7 @@
version: 3
endpoint: http://localhost:8085
admin_secret: bigbluebutton
metadata_directory: metadata
actions:
kind: synchronous
handler_webhook_baseurl: http://localhost:3000
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
# for psql
export PGHOST=postgres
export PGUSER="${POSTGRES_USER}"
export PGPASSWORD="${POSTGRES_PASSWORD}"
# for hasura
export HASURA_GRAPHQL_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/hasura_app
export HASURA_GRAPHQL_METADATA_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/hasura_app
export HASURA_GRAPHQL_LOG_LEVEL=warn
export HASURA_GRAPHQL_ENABLE_CONSOLE=false
export HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL=333
export HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_BATCH_SIZE=1000
export HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_REFETCH_INTERVAL=150
export HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_BATCH_SIZE=1000
export HASURA_GRAPHQL_SERVER_PORT=8085
export HASURA_GRAPHQL_ENABLE_TELEMETRY=false
export HASURA_GRAPHQL_WEBSOCKET_KEEPALIVE=10
export HASURA_GRAPHQL_AUTH_HOOK=http://apps-akka:8901/userInfo
export HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL=http://bbb-graphql-actions:8093
export HASURA_GRAPHQL_BBB_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/bbb_graphql
exec $@
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
set -e
cd /app/
# patch database url
# TODO: this should be possible upstream in BBB via an environment variable
yq e -i ".[1].configuration.connection_info.database_url = \"$HASURA_GRAPHQL_BBB_DATABASE_URL\"" metadata/databases/databases.yaml
sed -i "s/^admin_secret: .*/admin_secret: $HASURA_GRAPHQL_ADMIN_SECRET/g" /app/config.yaml
echo "SELECT 'CREATE DATABASE hasura_app' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'hasura_app')\gexec" | psql
echo "Restarting database bbb_graphql"
psql -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE datname = 'bbb_graphql'" > /dev/null
psql -c "drop database if exists bbb_graphql with (force)"
psql -c "create database bbb_graphql WITH TEMPLATE template0 LC_COLLATE 'C.UTF-8'"
psql -c "alter database bbb_graphql set timezone to 'UTC'"
echo "Creating tables in bbb_graphql"
psql -U postgres -d bbb_graphql -q -f bbb_schema.sql --set ON_ERROR_STOP=on
echo "Starting hasura-graphql-engine"
gosu nobody graphql-engine serve &
PID=$!
sleep 1
#Check if Hasura is ready before applying metadata
while ! netstat -tuln | grep ":$HASURA_GRAPHQL_SERVER_PORT " > /dev/null; do
echo "Waiting for Hasura's port ($HASURA_GRAPHQL_SERVER_PORT) to be ready..."
sleep 1
done
echo "Applying new metadata to Hasura"
/usr/local/bin/hasura metadata apply --skip-update-check
wait "$PID"
+23
View File
@@ -0,0 +1,23 @@
# serve locale index from prebuilt static files
location = /html5client/locales/ {
alias /usr/share/bigbluebutton/html5-client/locales/;
autoindex on;
autoindex_format json;
# Prevent browsers from caching
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
add_header Pragma "no-cache";
add_header Expires 0;
}
# running from source (npm start)
location /html5client/ {
rewrite /html5client/(.*) /$1 break;
gzip_static on;
proxy_pass http://webrtc-sfu:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
+18
View File
@@ -0,0 +1,18 @@
FROM node:22-bookworm-slim AS builder
COPY --from=src / /bbb-pads
RUN cd /bbb-pads && npm install --production
RUN chmod 777 /bbb-pads/config
# ------------------------------
FROM node:22-bookworm-slim
RUN apt update && apt install -y jq moreutils \
&& useradd --uid 2003 --create-home --user-group bbb-pads
COPY --from=builder /bbb-pads /bbb-pads
USER bbb-pads
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
set -e
TARGET=/bbb-pads/config/settings.json
cp /bbb-pads/config/settings.json.template $TARGET
sed -i "s/ETHERPAD_API_KEY/\"$ETHERPAD_API_KEY\"/g" $TARGET
jq '.etherpad.host = "etherpad"' $TARGET | sponge $TARGET
jq '.express.host = "0.0.0.0"' $TARGET | sponge $TARGET
jq '.redis.host = "redis"' $TARGET | sponge $TARGET
cd /bbb-pads
export NODE_ENV=production
npm start
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
# https://github.com/bigbluebutton/bigbluebutton/pull/9597/files
docker exec -it bbb-freeswitch fs_cli -H webrtc-sfu -P 8021 -x 'fsctl sync_clock_when_idle'
+60
View File
@@ -0,0 +1,60 @@
ARG BBB_BUILD_TAG
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder
COPY --from=src-common-message / /bbb-common-message
# build bbb-common-message
RUN cd /bbb-common-message && ./deploy.sh
# ===================================================
COPY --from=src-common-web / /bbb-common-web
# build bbb-common-web
RUN cd /bbb-common-web && ./deploy.sh
COPY --from=src-web / /bbb-web
# compile bbb-web
RUN cd /bbb-web && sh ./gradlew assemble
# compile pres-checker
RUN cd /bbb-web/pres-checker && gradle jar
RUN mkdir -p /bbb-web/pres-checker/lib && find /bbb-web/pres-checker && \
cp /bbb-web/pres-checker/build/libs/bbb-pres-check-0.0.1.jar /bbb-web/pres-checker/lib
# extract .war
RUN unzip -q /bbb-web/build/libs/bigbluebutton-0.10.0.war -d /dist
# ===================================================
FROM alangecker/bbb-docker-base-java
# add blank presentation files and allow conversion to pdf/svg
RUN mkdir -p /usr/share/bigbluebutton/blank \
&& cd /usr/share/bigbluebutton/blank \
&& wget \
https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/v3.0.19/bigbluebutton-config/slides/blank-svg.svg \
https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/v3.0.19/bigbluebutton-config/slides/blank-thumb.png \
https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/v3.0.19/bigbluebutton-config/slides/blank-presentation.pdf \
https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/v3.0.19/bigbluebutton-config/slides/blank-png.png \
&& sed -i 's/<policy domain="coder" rights="none" pattern="PDF" \/>/<policy domain="coder" rights="write" pattern="PDF" \/>/g' /etc/ImageMagick-6/policy.xml \
&& sed -i '/potrace/d' /etc/ImageMagick-6/delegates.xml
# get bbb-web
COPY --from=builder /dist /usr/share/bbb-web
# get pres-checker
COPY --from=builder /bbb-web/pres-checker/lib /usr/share/prescheck/lib
COPY --from=builder /bbb-web/pres-checker/run.sh /usr/share/prescheck/prescheck.sh
# add entrypoint and templates
COPY entrypoint.sh /entrypoint.sh
COPY bbb-web.properties /etc/bigbluebutton/bbb-web.properties.tmpl
COPY turn-stun-servers.xml /etc/bigbluebutton/turn-stun-servers.xml.tmpl
COPY logback.xml /usr/share/bbb-web/WEB-INF/classes/logback.xml
COPY office-convert.sh /usr/share/bbb-libreoffice-conversion/convert.sh
COPY run-in-systemd.sh /usr/share/bbb-web/run-in-systemd.sh
ENTRYPOINT ["/entrypoint.sh"]
+24
View File
@@ -0,0 +1,24 @@
defaultWelcomeMessage={{ .Env.WELCOME_MESSAGE }}
defaultWelcomeMessageFooter={{ .Env.WELCOME_FOOTER }}
{{ if isTrue .Env.ENABLE_RECORDING }}
disableRecordingDefault=false
{{ else }}
disableRecordingDefault=true
{{ end }}
bigbluebutton.web.serverURL=https://{{ .Env.DOMAIN }}
securitySalt={{ .Env.SHARED_SECRET }}
redisHost=redis
{{ if isTrue .Env.IGNORE_TLS_CERT_ERRORS }}
beans.presentationService.defaultUploadedPresentation=https://raw.githubusercontent.com/bigbluebutton/bigbluebutton/v3.0.19/bigbluebutton-config/assets/default.pdf
{{else}}
beans.presentationService.defaultUploadedPresentation=${bigbluebutton.web.serverURL}/default.pdf
{{end}}
learningDashboardEnabled={{ .Env.ENABLE_LEARNING_DASHBOARD }}
defaultNumDigitsForTelVoice=9
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
set -e
# create recording directory structure if it doesn't exist yet
mkdir -p /var/bigbluebutton/recording/status
mkdir -p /var/bigbluebutton/events
mkdir -p /var/bigbluebutton/recording
mkdir -p /var/bigbluebutton/recording/raw
mkdir -p /var/bigbluebutton/recording/process
mkdir -p /var/bigbluebutton/recording/publish
mkdir -p /var/bigbluebutton/recording/status/recorded
mkdir -p /var/bigbluebutton/recording/status/archived
mkdir -p /var/bigbluebutton/recording/status/processed
mkdir -p /var/bigbluebutton/recording/status/ended
mkdir -p /var/bigbluebutton/recording/status/sanity
mkdir -p /var/bigbluebutton/recording/status/published
mkdir -p /var/bigbluebutton/captions
mkdir -p /var/bigbluebutton/captions/inbox
mkdir -p /var/bigbluebutton/published
mkdir -p /var/bigbluebutton/deleted
mkdir -p /var/bigbluebutton/unpublished
mkdir -p /var/bigbluebutton/basic_stats
chown -R bigbluebutton:bigbluebutton /var/bigbluebutton
cd /usr/share/bbb-web/
dockerize \
-template /etc/bigbluebutton/bbb-web.properties.tmpl:/etc/bigbluebutton/bbb-web.properties \
-template /etc/bigbluebutton/turn-stun-servers.xml.tmpl:/etc/bigbluebutton/turn-stun-servers.xml \
gosu bigbluebutton java -Dgrails.env=prod -Dserver.address=0.0.0.0 -Dserver.port=8090 -Dspring.main.allow-circular-references=true -Xms384m -Xmx384m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/bigbluebutton/diagnostics -cp WEB-INF/lib/*:/:WEB-INF/classes/:. org.springframework.boot.loader.launch.WarLauncher
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"} %-5level %logger{35} - %msg%n</Pattern>
</layout>
</appender>
<logger name="akka" level="INFO" />
<logger name="io.lettuce" level="INFO" />
<logger name="org.bigbluebutton" level="DEBUG" />
<logger name="grails.app.controllers" level="DEBUG" />
<logger name="grails.app.services" level="DEBUG" />
<logger name="org.grails.web.servlet" level="ERROR" />
<logger name="org.grails.web.pages" level="ERROR" />
<logger name="org.grails.web.sitemesh" level="ERROR" />
<logger name="org.grails.web.mapping.filter" level="ERROR" />
<logger name="org.grails.web.mapping" level="ERROR" />
<logger name="org.grails.commons" level="ERROR" />
<logger name="org.springframework" level="ERROR" />
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
set -e
set -u
PATH="/bin/:/usr/bin/"
# This script receives three params
# Param 1: Input office file path (e.g. "/tmp/test.odt")
# Param 2: Output pdf file path (e.g. "/tmp/test.pdf")
# Param 3: Destination Format (pdf default)
# Param 4: Timeout (secs) (optional)
if (( $# == 0 )); then
echo "Missing parameter 1 (Input office file path)";
exit 1
elif (( $# == 1 )); then
echo "Missing parameter 2 (Output pdf file path)";
exit 1
fi;
source="$1"
dest="$2"
# If output format is missing, define PDF
convertTo="${3:-pdf}"
# If timeout is missing, define 60
timeoutSecs="${4:-60}"
# Truncate timeout to max 3 digits (as expected by sudoers)
timeoutSecs="${timeoutSecs:0:3}"
# The timeout is important.
timeout $(printf %03d $timeoutSecs)s curl -F "data=@${source}" -k $COLLABORA_URL/convert-to/$convertTo > "${dest}"
exit 0
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh -e
# bbb-web requires a script under /usr/share/bbb-web/run-in-systemd.sh to run certain tasks
# this is used for sandboxing, which is in our case a bit more difficult, because
# we run it without systemd in an unprivileged container, with currently no extra sandboxing capabilities
# TODO: exploring better ways! (e. g. firejail)
timeout_secs="$1"; shift
exec timeout "${timeout_secs}" "$@"
+59
View File
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="stun1" class="org.bigbluebutton.web.services.turn.StunServer">
<constructor-arg index="0" value="{{ .Env.STUN_SERVER }}"/>
</bean>
<bean id="turn0" class="org.bigbluebutton.web.services.turn.TurnServer">
<constructor-arg index="0" value="{{ .Env.TURN_SECRET }}"/>
<constructor-arg index="1" value="turn:{{ .Env.DOMAIN }}:3478"/>
<constructor-arg index="2" value="86400"/>
</bean>
{{if and (isTrue .Env.ENABLE_HTTPS_PROXY) (not (isTrue .Env.IGNORE_TLS_CERT_ERRORS)) }}
{{/* ignore when using a self signed certificate in dev mode */}}
<bean id="turn1" class="org.bigbluebutton.web.services.turn.TurnServer">
<constructor-arg index="0" value="{{ .Env.TURN_SECRET }}"/>
<constructor-arg index="1" value="turns:{{ .Env.DOMAIN }}:443?transport=tcp"/>
<constructor-arg index="2" value="86400"/>
</bean>
{{end}}
{{if .Env.TURN_EXT_SERVER }}
<bean id="turn2" class="org.bigbluebutton.web.services.turn.TurnServer">
<constructor-arg index="0" value="{{ .Env.TURN_EXT_SECRET }}"/>
<constructor-arg index="1" value="{{ .Env.TURN_EXT_SERVER }}"/>
<constructor-arg index="2" value="86400"/>
</bean>
{{end}}
<bean id="stunTurnService" class="org.bigbluebutton.web.services.turn.StunTurnService">
<property name="stunServers">
<set>
<ref bean="stun1" />
</set>
</property>
<property name="turnServers">
<set>
<ref bean="turn0" />
{{if and (isTrue .Env.ENABLE_HTTPS_PROXY) (not (isTrue .Env.IGNORE_TLS_CERT_ERRORS)) }}
<ref bean="turn1" />
{{end}}
{{if .Env.TURN_EXT_SERVER }}
<ref bean="turn2" />
{{end}}
</set>
</property>
<property name="remoteIceCandidates">
<set>
</set>
</property>
</bean>
</beans>
+40
View File
@@ -0,0 +1,40 @@
# Build stage
FROM golang:1.25 as builder
ARG APP_VERSION=devel
ARG GOMOD=github.com/bigbluebutton/bbb-webrtc-recorder
WORKDIR /app
COPY --from=src go.* ./
RUN go mod tidy
COPY --from=src . ./
RUN APP_VERSION=$(cat ./VERSION | sed 's/ /-/g') \
go build -o ./build/bbb-webrtc-recorder \
-ldflags="-X '$GOMOD/internal.AppVersion=v${APP_VERSION1}'" \
./cmd/bbb-webrtc-recorder
RUN mv /app/build/bbb-webrtc-recorder /usr/bin/bbb-webrtc-recorder
# Running stage
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y gosu
# use same UID as in the recordings container
RUN groupadd -g 998 bigbluebutton && useradd -m -u 998 -g bigbluebutton bigbluebutton
# config
ENV BBBRECORDER_PUBSUB_ADAPTERS_REDIS_ADDRESS=redis:6379
ENV BBBRECORDER_PUBSUB_ADAPTERS_REDIS_NETWORK=tcp
ENV BBBRECORDER_DEBUG=true
# Copy the binary to the production image from the builder stage.
COPY --from=builder /usr/bin/bbb-webrtc-recorder /usr/bin/bbb-webrtc-recorder
COPY --from=builder /app/config/bbb-webrtc-recorder.yml /etc/bbb-webrtc-recorder/bbb-webrtc-recorder.yml
CMD ["/bin/sh", "-c", "chown -R bigbluebutton:bigbluebutton /var/lib/bbb-webrtc-recorder && gosu bigbluebutton /usr/bin/bbb-webrtc-recorder"]
+28
View File
@@ -0,0 +1,28 @@
listening-port=3478
# listening-ip=${INTERNAL_IP:-$IP}
# relay-ip=${INTERNAL_IP:-$IP}
min-port=32769
max-port=65535
# verbose
fingerprint
lt-cred-mech
use-auth-secret
realm=bbb-docker
keep-address-family
no-cli
no-tlsv1
no-tlsv1_1
# Block connections to IP ranges which shouldn't be reachable
no-loopback-peers
no-multicast-peers
# we only need to allow peer connections from the machine itself (from mediasoup or freeswitch).
denied-peer-ip=0.0.0.0-255.255.255.255
denied-peer-ip=::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+29
View File
@@ -0,0 +1,29 @@
ARG TAG_ETHERPAD
FROM etherpad/etherpad:$TAG_ETHERPAD
USER root
RUN apk add git curl
USER etherpad
RUN pnpm run plugins i \
ep_disable_chat@0.0.13 \
ep_auth_session@1.1.1 \
--github \
mconf/ep_cursortrace#56fb8c2b211cdda4fc8715ec99e1cb7b7d9eb851 \
mconf/ep_pad_ttl#360136cd38493dd698435631f2373cbb7089082d \
mconf/ep_redis_publisher#2b6e47c1c59362916a0b2961a29b259f2977b694
# add skin from git submodule
COPY --chown=etherpad:0 --from=skin / /opt/etherpad-lite/src/static/skins/bigbluebutton
# add plugin from git submodule
COPY --chown=etherpad:0 --from=plugin / /ep_bigbluebutton_patches
RUN pnpm run plugins i --path /ep_bigbluebutton_patches
COPY settings.json /opt/etherpad-lite/settings.json
COPY etherpad-export.sh /etherpad-export.sh
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
echo $ETHERPAD_API_KEY > /tmp/apikey
pnpm run prod --apikey /tmp/apikey
+9
View File
@@ -0,0 +1,9 @@
#!/bin/sh
src="$8"
dest="$(echo $8 | sed -E -e 's/html|odt/'$7'/')"
convertTo="$7"
curl -v -F "data=@${src}" -k $COLLABORA_URL/convert-to/$convertTo > "${dest}"
exit 0
+723
View File
@@ -0,0 +1,723 @@
/*
* This file must be valid JSON. But comments are allowed
*
* Please edit settings.json, not settings.json.template
*
* Please note that starting from Etherpad 1.6.0 you can store DB credentials in
* a separate file (credentials.json).
*
*
* ENVIRONMENT VARIABLE SUBSTITUTION
* =================================
*
* All the configuration values can be read from environment variables using the
* syntax "${ENV_VAR}" or "${ENV_VAR:default_value}".
*
* This is useful, for example, when running in a Docker container.
*
* DETAILED RULES:
* - If the environment variable is set to the string "true" or "false", the
* value becomes Boolean true or false.
* - If the environment variable is set to the string "null", the value
* becomes null.
* - If the environment variable is set to the string "undefined", the setting
* is removed entirely, except when used as the member of an array in which
* case it becomes null.
* - If the environment variable is set to a string representation of a finite
* number, the string is converted to that number.
* - If the environment variable is set to any other string, including the
* empty string, the value is that string.
* - If the environment variable is unset and a default value is provided, the
* value is as if the environment variable was set to the provided default:
* - "${UNSET_VAR:}" becomes the empty string.
* - "${UNSET_VAR:foo}" becomes the string "foo".
* - "${UNSET_VAR:true}" and "${UNSET_VAR:false}" become true and false.
* - "${UNSET_VAR:null}" becomes null.
* - "${UNSET_VAR:undefined}" causes the setting to be removed (or be set
* to null, if used as a member of an array).
* - If the environment variable is unset and no default value is provided,
* the value becomes null. THIS BEHAVIOR MAY CHANGE IN A FUTURE VERSION OF
* ETHERPAD; if you want the default value to be null, you should explicitly
* specify "null" as the default value.
*
* EXAMPLE:
* "port": "${PORT:9001}"
* "minify": "${MINIFY}"
* "skinName": "${SKIN_NAME:colibris}"
*
* Would read the configuration values for those items from the environment
* variables PORT, MINIFY and SKIN_NAME.
*
* If PORT and SKIN_NAME variables were not defined, the default values 9001 and
* "colibris" would be used.
* The configuration value "minify", on the other hand, does not have a
* designated default value. Thus, if the environment variable MINIFY were
* undefined, "minify" would be null.
*
* REMARKS:
* 1) please note that variable substitution always needs to be quoted.
*
* "port": 9001, <-- Literal values. When not using
* "minify": false substitution, only strings must be
* "skinName": "colibris" quoted. Booleans and numbers must not.
*
* "port": "${PORT:9001}" <-- CORRECT: if you want to use a variable
* "minify": "${MINIFY:true}" substitution, put quotes around its name,
* "skinName": "${SKIN_NAME}" even if the required value is a number or
* a boolean.
* Etherpad will take care of rewriting it
* to the proper type if necessary.
*
* "port": ${PORT:9001} <-- ERROR: this is not valid json. Quotes
* "minify": ${MINIFY} around variable names are missing.
* "skinName": ${SKIN_NAME}
*
* 2) Beware of undefined variables and default values: nulls and empty strings
* are different!
*
* This is particularly important for user's passwords (see the relevant
* section):
*
* "password": "${PASSW}" // if PASSW is not defined would result in password === null
* "password": "${PASSW:}" // if PASSW is not defined would result in password === ''
*
* If you want to use an empty value (null) as default value for a variable,
* simply do not set it, without putting any colons: "${ABIWORD}".
*
* 3) if you want to use newlines in the default value of a string parameter,
* use "\n" as usual.
*
* "defaultPadText" : "${DEFAULT_PAD_TEXT}Line 1\nLine 2"
*/
{
/*
* Name your instance!
*/
"title": "Etherpad",
/*
* Pathname of the favicon you want to use. If null, the skin's favicon is
* used if one is provided by the skin, otherwise the default Etherpad favicon
* is used. If this is a relative path it is interpreted as relative to the
* Etherpad root directory.
*/
"favicon": null,
/*
* Skin name.
*
* Its value has to be an existing directory under src/static/skins.
* You can write your own, or use one of the included ones:
*
* - "no-skin": an empty skin (default). This yields the unmodified,
* traditional Etherpad theme.
* - "colibris": the new experimental skin (since Etherpad 1.8), candidate to
* become the default in Etherpad 2.0
*/
"skinName": "bigbluebutton",
/*
* Skin Variants
*
* Use the UI skin variants builder at /p/test#skinvariantsbuilder
*
* For the colibris skin only, you can choose how to render the three main
* containers:
* - toolbar (top menu with icons)
* - editor (containing the text of the pad)
* - background (area outside of editor, mostly visible when using page style)
*
* For each of the 3 containers you can choose 4 color combinations:
* super-light, light, dark, super-dark.
*
* For example, to make the toolbar dark, you will include "dark-toolbar" into
* skinVariants.
*
* You can provide multiple skin variants separated by spaces. Default
* skinVariant is "super-light-toolbar super-light-editor light-background".
*
* For the editor container, you can also make it full width by adding
* "full-width-editor" variant (by default editor is rendered as a page, with
* a max-width of 900px).
*/
"skinVariants": "",
/*
* IP and port which Etherpad should bind at.
*
* Binding to a Unix socket is also supported: just use an empty string for
* the ip, and put the full path to the socket in the port parameter.
*
* EXAMPLE USING UNIX SOCKET:
* "ip": "", // <-- has to be an empty string
* "port" : "/somepath/etherpad.socket", // <-- path to a Unix socket
*/
"ip": "0.0.0.0",
"port": 9001,
/*
* Option to hide/show the settings.json in admin page.
*
* Default option is set to true
*/
"showSettingsInAdminPage": true,
/*
* Settings for cleanup of pads
*/
"cleanup": {
"enabled": false,
"keepRevisions": 5
},
/*
* Node native SSL support
*
* This is disabled by default.
* Make sure to have the minimum and correct file access permissions set so
* that the Etherpad server can access them
*/
/*
"ssl" : {
"key" : "/path-to-your/epl-server.key",
"cert" : "/path-to-your/epl-server.crt",
"ca": ["/path-to-your/epl-intermediate-cert1.crt", "/path-to-your/epl-intermediate-cert2.crt"]
},
*/
/*
* The type of the database.
*
* You can choose between many DB drivers, for example: dirty, postgres,
* sqlite, mysql.
*
* You shouldn't use "dirty" for for anything else than testing or
* development.
*
*
* Database specific settings are dependent on dbType, and go in dbSettings.
* Remember that since Etherpad 1.6.0 you can also store this information in
* credentials.json.
*
* For a complete list of the supported drivers, please refer to:
* https://www.npmjs.com/package/ueberdb2
*/
"dbType": "redis",
"dbSettings": {
"url": "redis://redis:6379"
},
/*
* An Example of MySQL Configuration (commented out).
*
* See: https://github.com/ether/etherpad-lite/wiki/How-to-use-Etherpad-Lite-with-MySQL
*/
/*
"dbType" : "redis",
"dbSettings" : {
"host": "127.0.0.1",
"port": 6379,
"client_options": {
"password": "PASSWORD"
}
},
*/
/*
* The default text of a pad: A zero-width-space is used to work around an issue with Etherpad 1.9.1 where empty pads are not being created.
* See: https://github.com/ether/etherpad-lite/issues/5787
*/
"defaultPadText" : "\u200b",
/*
* Default Pad behavior.
*
* Change them if you want to override.
*/
"padOptions": {
"noColors": true,
"showControls": true,
"showChat": false,
"showLineNumbers": false,
"useMonospaceFont": false,
"userName": false,
"userColor": false,
"rtl": false,
"alwaysShowChat": false,
"chatAndUsers": false,
"lang": "en"
},
/*
* Pad Shortcut Keys
*/
"padShortcutEnabled" : {
"altF9": true, /* focus on the File Menu and/or editbar */
"altC": false, /* focus on the Chat window */
"cmdShift2": true, /* shows a gritter popup showing a line author */
"delete": true,
"return": true,
"esc": true, /* in mozilla versions 14-19 avoid reconnecting pad */
"cmdS": true, /* save a revision */
"tab": true, /* indent */
"cmdZ": true, /* undo/redo */
"cmdY": true, /* redo */
"cmdI": true, /* italic */
"cmdB": true, /* bold */
"cmdU": true, /* underline */
"cmd5": true, /* strike through */
"cmdShiftL": true, /* unordered list */
"cmdShiftN": true, /* ordered list */
"cmdShift1": true, /* ordered list */
"cmdShiftC": true, /* clear authorship */
"cmdH": true, /* backspace */
"ctrlHome": true, /* scroll to top of pad */
"pageUp": true,
"pageDown": true
},
/*
* Enables the use of a different server. We have a different one that syncs changes from the original server.
* It is hosted on GitHub and should not be blocked by many firewalls.
* https://etherpad.org/ep_infos
*/
"updateServer": "https://etherpad.org/ep_infos",
/*
* Should we suppress errors from being visible in the default Pad Text?
*/
"suppressErrorsInPadText": true,
/*
* If this option is enabled, a user must have a session to access pads.
* This effectively allows only group pads to be accessed.
*/
"requireSession": true,
/*
* Users may edit pads but not create new ones.
*
* Pad creation is only via the API.
* This applies both to group pads and regular pads.
*/
"editOnly": true,
/*
* If true, all css & js will be minified before sending to the client.
*
* This will improve the loading performance massively, but makes it difficult
* to debug the javascript/css
*/
"minify": true,
/*
* How long may clients use served javascript code (in seconds)?
*
* Not setting this may cause problems during deployment.
* Set to 0 to disable caching.
*/
"maxAge": 21600, // 60 * 60 * 6 = 6 hours
/*
* Absolute path to the Abiword executable.
*
* Abiword is needed to get advanced import/export features of pads. Setting
* it to null disables Abiword and will only allow plain text and HTML
* import/exports.
*/
"abiword": null,
/*
* This is the absolute path to the soffice executable.
*
* LibreOffice can be used in lieu of Abiword to export pads.
* Setting it to null disables LibreOffice exporting.
*/
"soffice": "/etherpad-export.sh",
/*
* Allow import of file types other than the supported ones:
* txt, doc, docx, rtf, odt, html & htm
*/
"allowUnknownFileEnds": false,
/*
* This setting is used if you require authentication of all users.
*
* Note: "/admin" always requires authentication.
*/
"requireAuthentication": false,
/*
* Require authorization by a module, or a user with is_admin set, see below.
*/
"requireAuthorization": false,
/*
* When you use NGINX or another proxy/load-balancer set this to true.
*
* This is especially necessary when the reverse proxy performs SSL
* termination, otherwise the cookies will not have the "secure" flag.
*
* The other effect will be that the logs will contain the real client's IP,
* instead of the reverse proxy's IP.
*/
"trustProxy": true,
/*
* Settings controlling the session cookie issued by Etherpad.
*/
"cookie": {
/*
* How often (in milliseconds) the key used to sign the express_sid cookie
* should be rotated. Long rotation intervals reduce signature verification
* overhead (because there are fewer historical keys to check) and database
* load (fewer historical keys to store, and less frequent queries to
* get/update the keys). Short rotation intervals are slightly more secure.
*
* Multiple Etherpad processes sharing the same database (table) is
* supported as long as the clock sync error is significantly less than this
* value.
*
* Key rotation can be disabled (not recommended) by setting this to 0 or
* null, or by disabling session expiration (see sessionLifetime).
*/
"keyRotationInterval": 86400000, // = 1d * 24h/d * 60m/h * 60s/m * 1000ms/s
/*
* Value of the SameSite cookie property. "Lax" is recommended unless
* Etherpad will be embedded in an iframe from another site, in which case
* this must be set to "None". Note: "None" will not work (the browser will
* not send the cookie to Etherpad) unless https is used to access Etherpad
* (either directly or via a reverse proxy with "trustProxy" set to true).
*
* "Strict" is not recommended because it has few security benefits but
* significant usability drawbacks vs. "Lax". See
* https://stackoverflow.com/q/41841880 for discussion.
*/
"sameSite": "None",
/*
* How long (in milliseconds) after navigating away from Etherpad before the
* user is required to log in again. (The express_sid cookie is set to
* expire at time now + sessionLifetime when first created, and its
* expiration time is periodically refreshed to a new now + sessionLifetime
* value.) If requireAuthentication is false then this value does not really
* matter.
*
* The "best" value depends on your users' usage patterns and the amount of
* convenience you desire. A long lifetime is more convenient (users won't
* have to log back in as often) but has some drawbacks:
* - It increases the amount of state kept in the database.
* - It might weaken security somewhat: The cookie expiration is refreshed
* indefinitely without consulting authentication or authorization
* hooks, so once a user has accessed a pad, the user can continue to
* use the pad until the user leaves for longer than sessionLifetime.
* - More historical keys (sessionLifetime / keyRotationInterval) must be
* checked when verifying signatures.
*
* Session lifetime can be set to infinity (not recommended) by setting this
* to null or 0. Note that if the session does not expire, most browsers
* will delete the cookie when the browser exits, but a session record is
* kept in the database forever.
*/
"sessionLifetime": 864000000, // = 10d * 24h/d * 60m/h * 60s/m * 1000ms/s
/*
* How long (in milliseconds) before the expiration time of an active user's
* session is refreshed (to now + sessionLifetime). This setting affects the
* following:
* - How often a new session expiration time will be written to the
* database.
* - How often each user's browser will ping the Etherpad server to
* refresh the expiration time of the session cookie.
*
* High values reduce the load on the database and the load from browsers,
* but can shorten the effective session lifetime if Etherpad is restarted
* or the user navigates away.
*
* Automatic session refreshes can be disabled (not recommended) by setting
* this to null.
*/
"sessionRefreshInterval": 86400000 // = 1d * 24h/d * 60m/h * 60s/m * 1000ms/s
},
/*
* Privacy: disable IP logging
*/
"disableIPlogging": true,
/*
* Time (in seconds) to automatically reconnect pad when a "Force reconnect"
* message is shown to user.
*
* Set to 0 to disable automatic reconnection.
*/
"automaticReconnectionTimeout": 0,
/*
* By default, when caret is moved out of viewport, it scrolls the minimum
* height needed to make this line visible.
*/
"scrollWhenFocusLineIsOutOfViewport": {
/*
* Percentage of viewport height to be additionally scrolled.
*
* E.g.: use "percentage.editionAboveViewport": 0.5, to place caret line in
* the middle of viewport, when user edits a line above of the
* viewport
*
* Set to 0 to disable extra scrolling
*/
"percentage": {
"editionAboveViewport": 0,
"editionBelowViewport": 0
},
/*
* Time (in milliseconds) used to animate the scroll transition.
* Set to 0 to disable animation
*/
"duration": 0,
/*
* Flag to control if it should scroll when user places the caret in the
* last line of the viewport
*/
"scrollWhenCaretIsInTheLastLineOfViewport": false,
/*
* Percentage of viewport height to be additionally scrolled when user
* presses arrow up in the line of the top of the viewport.
*
* Set to 0 to let the scroll to be handled as default by Etherpad
*/
"percentageToScrollWhenUserPressesArrowUp": 0
},
/*
* User accounts. These accounts are used by:
* - default HTTP basic authentication if no plugin handles authentication
* - some but not all authentication plugins
* - some but not all authorization plugins
*
* User properties:
* - password: The user's password. Some authentication plugins will ignore
* this.
* - is_admin: true gives access to /admin. Defaults to false. If you do not
* uncomment this, /admin will not be available!
* - readOnly: If true, this user will not be able to create new pads or
* modify existing pads. Defaults to false.
* - canCreate: If this is true and readOnly is false, this user can create
* new pads. Defaults to true.
*
* Authentication and authorization plugins may define additional properties.
*
* WARNING: passwords should not be stored in plaintext in this file.
* If you want to mitigate this, please install ep_hash_auth and
* follow the section "secure your installation" in README.md
*/
/*
"users": {
"admin": {
// 1) "password" can be replaced with "hash" if you install ep_hash_auth
// 2) please note that if password is null, the user will not be created
"password": "changeme1",
"is_admin": true
},
"user": {
// 1) "password" can be replaced with "hash" if you install ep_hash_auth
// 2) please note that if password is null, the user will not be created
"password": "changeme1",
"is_admin": false
}
},
*/
/*
* Restrict socket.io transport methods
*/
"socketTransportProtocols" : ["websocket", "polling"],
"socketIo": {
/*
* Maximum permitted client message size (in bytes). All messages from
* clients that are larger than this will be rejected. Large values make it
* possible to paste large amounts of text, and plugins may require a larger
* value to work properly, but increasing the value increases susceptibility
* to denial of service attacks (malicious clients can exhaust memory).
*/
"maxHttpBufferSize": 50000
},
/*
* Allow Load Testing tools to hit the Etherpad Instance.
*
* WARNING: this will disable security on the instance.
*/
"loadTest": false,
/**
* Disable dump of objects preventing a clean exit
*/
"dumpOnUncleanExit": false,
/*
* Disable indentation on new line when previous line ends with some special
* chars (':', '[', '(', '{')
*/
/*
"indentationOnNewLine": false,
*/
"ep_pad_ttl": {
"ttl": 86400, // 24 hours
"timeout": 30,
"interval": 21600 // 6 hours
},
/*
* Redis publisher plugin configuration.
* npm i git+https://git@github.com/mconf/ep_redis_publisher.git
*/
"ep_redis_publisher": {
"host": "redis",
"port": 6379
},
/*
* From Etherpad 1.8.3 onwards, import and export of pads is always rate
* limited.
*
* The default is to allow at most 10 requests per IP in a 90 seconds window.
* After that the import/export request is rejected.
*
* See https://github.com/nfriedly/express-rate-limit for more options
*/
"importExportRateLimiting": {
// duration of the rate limit window (milliseconds)
"windowMs": 90000,
// maximum number of requests per IP to allow during the rate limit window
"max": 32
},
/*
* From Etherpad 1.8.3 onwards, the maximum allowed size for a single imported
* file is always bounded.
*
* File size is specified in bytes. Default is 50 MB.
*/
"importMaxFileSize": 52428800, // 50 * 1024 * 1024
/*
The authentication method used by the server.
The default value is sso
If you want to use the old authentication system, change this to apikey
*/
"authenticationMethod": "apikey",
/*
* From Etherpad 1.8.5 onwards, when Etherpad is in production mode commits from individual users are rate limited
*
* The default is to allow at most 10 changes per IP in a 1 second window.
* After that the change is rejected.
*
* See https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#websocket-single-connection-prevent-flooding for more options
*/
"commitRateLimiting": {
// duration of the rate limit window (seconds)
"duration": 1,
// maximum number of changes per IP to allow during the rate limit window
"points": 100
},
/*
* Toolbar buttons configuration.
*
* Uncomment to customize.
*/
"toolbar": {
"left": [
["bold", "italic", "underline", "strikethrough"],
["orderedlist", "unorderedlist", "undo", "redo"],
["importexport"]
],
"right": [[]]
},
/*
* Expose Etherpad version in the web interface and in the Server http header.
*
* Do not enable on production machines.
*/
"exposeVersion": false,
/*
* The log level we are using.
*
* Valid values: DEBUG, INFO, WARN, ERROR
*/
"loglevel": "INFO",
/*
* The log layout type to use.
*
* Valid values: basic, colored
*/
"logLayoutType": "colored",
/* Override any strings found in locale directories */
"customLocaleStrings": {
"de": {
"pad.importExport.import_export": "Export",
"pad.toolbar.import_export.title": "Export zu verschiedenen Dateiformaten"
},
"en-gb": {
"pad.importExport.import_export": "Export",
"pad.toolbar.import_export.title": "Export to different file formats"
},
"en": {
"pad.importExport.import_export": "Export",
"pad.toolbar.import_export.title": "Export to different file formats"
},
"es": {
"pad.importExport.import_export": "Exportar",
"pad.toolbar.import_export.title": "Exportar a diferentes formatos de archivos"
},
"fr": {
"pad.importExport.import_export": "Exporter",
"pad.toolbar.import_export.title": "Exporter vers un format de fichier différent"
},
"it": {
"pad.importExport.import_export": "Esportazione",
"pad.toolbar.import_export.title": "Esporta a diversi formati di file"
},
"pt-br": {
"pad.importExport.import_export": "Exportar",
"pad.toolbar.import_export.title": "Exportar para diferentes formatos de arquivo"
},
"pt": {
"pad.importExport.import_export": "Exportar",
"pad.toolbar.import_export.title": "Exportar para diferentes formatos de ficheiro"
}
},
/* Disable Admin UI tests */
"enableAdminUITests": false,
/*
* Enable/Disable case-insensitive pad names.
*/
"lowerCasePadIds": false
}
+71
View File
@@ -0,0 +1,71 @@
ARG BBB_BUILD_TAG
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder
COPY --from=freeswitch / /build/freeswitch
# install most recent git version for proper sparse-checkout support
# https://stackoverflow.com/questions/72223738/failed-to-initialize-sparse-checkout
RUN echo 'deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu focal main' > /etc/apt/sources.list.d/git-core-ppa.list && \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys A1715D88E1DF1F24 && \
apt-get update && \
apt-get install -y git
# get build files for bbb-freeswitch (build/packages-template/bbb-freeswitch-core/)
COPY --from=build-files / /build/
# mock files expected by build.sh
RUN mkdir -p /build/bbb-voice-conference/config/freeswitch/conf/ && \
touch \
/build/opts-build.sh \
/build/freeswitch.service.build \
/build/bbb-voice-conference/config/freeswitch/conf/a \
&& \
echo "" > /usr/local/bin/fpm
# build freeswitch
RUN cd /build && ./build.sh
# add english sounds
RUN mkdir -p /build/staging/opt/freeswitch/share/freeswitch && \
wget https://ubuntu.bigbluebutton.org/sounds.tar.gz -O sounds.tar.gz && \
tar xvfz sounds.tar.gz -C /build/staging/opt/freeswitch/share/freeswitch && \
wget https://gitlab.senfcall.de/senfcall-public/mute-and-unmute-sounds/-/archive/master/mute-and-unmute-sounds-master.zip && \
unzip mute-and-unmute-sounds-master.zip && \
cd mute-and-unmute-sounds-master/sounds && \
find . -name "*.wav" -exec /bin/bash -c "sox -v 0.3 {} /tmp/tmp.wav; cp /tmp/tmp.wav /build/staging/opt/freeswitch/share/freeswitch/sounds/en/us/callie/conference/{}" \;
# add bigblugbutton config
ARG TAG_FS_CONFIG
COPY --from=fs-config / /build/staging/opt/freeswitch/etc/freeswitch/
# ===============================================
# we are using ubuntu here, because libjpeg8 is required, but not available in debian
FROM ubuntu:22.04
RUN apt-get update && \
apt-get install -y \
xmlstarlet wget iptables curl \
libfreetype6 libcurl4 libspeex1 libspeexdsp1 libopus0 libsndfile1 libopusfile0 liblua5.2-0 libjbig0 libldns3 libedit2 libtiff5 libpng16-16 libsqlite3-0 \
&& \
# install libopusenc0
wget -O /tmp/libopusenc0_0.2.1-1bbb2_amd64.deb https://launchpad.net/~bigbluebutton/+archive/ubuntu/support/+files/libopusenc0_0.2.1-1bbb2_amd64.deb \
&& dpkg -i /tmp/libopusenc0_0.2.1-1bbb2_amd64.deb \
&& rm /tmp/libopusenc0_0.2.1-1bbb2_amd64.deb
# add dockerize
COPY --from=alangecker/bbb-docker-base-java /usr/local/bin/dockerize /usr/local/bin/dockerize
# copy over built freeswitch & config
COPY --from=builder /build/staging/opt /opt
COPY --from=builder /build/staging/etc /etc
RUN ldconfig && \
ln -s /opt/freeswitch/conf /etc/freeswitch && \
groupadd freeswitch && \
useradd --home-dir /opt/freeswitch --shell /usr/sbin/nologin -g freeswitch freeswitch
COPY ./entrypoint.sh /entrypoint.sh
COPY ./conf /etc/freeswitch/
ENTRYPOINT /entrypoint.sh
@@ -0,0 +1,285 @@
<!-- http://wiki.freeswitch.org/wiki/Mod_conference -->
<!-- None of these paths are real if you want any of these options you need to really set them up -->
<configuration name="conference.conf" description="Audio Conference">
<!-- Advertise certain presence on startup . -->
<advertise>
<room name="3001@$${domain}" status="FreeSWITCH"/>
</advertise>
<!-- These are the default keys that map when you do not specify a caller control group -->
<!-- Note: none and default are reserved names for group names. Disabled if dist-dtmf member flag is set. -->
<caller-controls>
<group name="default">
<control action="mute" digits="0"/>
<control action="deaf mute" digits="*"/>
<control action="energy up" digits="9"/>
<control action="energy equ" digits="8"/>
<control action="energy dn" digits="7"/>
<control action="vol talk up" digits="3"/>
<control action="vol talk zero" digits="2"/>
<control action="vol talk dn" digits="1"/>
<control action="vol listen up" digits="6"/>
<control action="vol listen zero" digits="5"/>
<control action="vol listen dn" digits="4"/>
<!--control action="hangup" digits="#"/ -->
</group>
</caller-controls>
<!-- Profiles are collections of settings you can reference by name. -->
<profiles>
<!--If no profile is specified it will default to "default"-->
<profile name="default">
<!-- Directory to drop CDR's
'auto' means $PREFIX/logs/conference_cdr/<confernece_uuid>.cdr.xml
a non-absolute path means $PREFIX/logs/<value>/<confernece_uuid>.cdr.xml
absolute path means <value>/<confernece_uuid>.cdr.xml
-->
<!-- <param name="cdr-log-dir" value="auto"/> -->
<!-- Domain (for presence) -->
<param name="domain" value="$${domain}"/>
<!-- Sample Rate-->
<param name="rate" value="48000"/>
<!-- Number of milliseconds per frame -->
<param name="interval" value="20"/>
<!-- Energy level required for audio to be sent to the other users -->
<param name="energy-level" value="100"/>
<!--Can be | delim of waste|mute|deaf|dist-dtmf waste will always transmit data to each channel
even during silence. dist-dtmf propagates dtmfs to all other members, but channel controls
via dtmf will be disabled. -->
<!-- <param name="member-flags" value="waste"/> -->
<!-- Name of the caller control group to use for this profile -->
<!-- <param name="caller-controls" value="some name"/> -->
<!-- Name of the caller control group to use for the moderator in this profile -->
<!-- <param name="moderator-controls" value="some name"/> -->
<!-- TTS Engine to use -->
<!-- <param name="tts-engine" value="cepstral"/> -->
<!-- TTS Voice to use -->
<!-- <param name="tts-voice" value="david"/> -->
<!-- If TTS is enabled all audio-file params beginning with -->
<!-- 'say:' will be considered text to say with TTS -->
<!-- Override the default path here, after which you use relative paths in the other sound params -->
<!-- Note: The default path is the conference's first caller's sound_prefix -->
<!-- <param name="sound-prefix" value="$${sounds_dir}/en/us/callie"/> -->
<!-- File to play to acknowledge succees -->
<!-- <param name="ack-sound" value="beep.wav"/> -->
<!-- File to play to acknowledge failure -->
<!-- <param name="nack-sound" value="beeperr.wav"/> -->
<!-- File to play to acknowledge muted -->
<param name="muted-sound" value="conference/conf-muted.wav"/>
<!-- File to play to acknowledge unmuted -->
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
<!-- File to play if you are alone in the conference -->
<param name="alone-sound" value="conference/conf-alone.wav"/>
<!-- File to play endlessly (nobody will ever be able to talk) -->
<!-- <param name="perpetual-sound" value="perpetual.wav"/> -->
<!-- File to play when you're alone (music on hold)-->
<param name="moh-sound" value="$${hold_music}"/>
<!-- File to play when you join the conference -->
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<!-- File to play when you leave the conference -->
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
<!-- File to play when you are ejected from the conference -->
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
<!-- File to play when the conference is locked -->
<param name="locked-sound" value="conference/conf-locked.wav"/>
<!-- File to play when the conference is locked during the call-->
<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
<!-- File to play when the conference is unlocked during the call-->
<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>
<!-- File to play to prompt for a pin -->
<param name="pin-sound" value="conference/conf-pin.wav"/>
<!-- File to play to when the pin is invalid -->
<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>
<!-- Conference pin -->
<!-- <param name="pin" value="12345"/> -->
<!-- <param name="moderator-pin" value="54321"/> -->
<!-- Max number of times the user can be prompted for PIN -->
<!-- <param name="pin-retries" value="3"/> -->
<!-- Default Caller ID Name for outbound calls -->
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<!-- Default Caller ID Number for outbound calls -->
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<!-- Suppress start and stop talking events -->
<!-- <param name="suppress-events" value="start-talking,stop-talking"/> -->
<!-- enable comfort noise generation -->
<param name="comfort-noise" value="true"/>
<!-- Uncomment auto-record to toggle recording every conference call. -->
<!-- Another valid value is shout://user:pass@server.com/live.mp3 -->
<!--
<param name="auto-record" value="$${recordings_dir}/${conference_name}_${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
-->
<!-- IVR digit machine timeouts -->
<!-- How much to wait between DTMF digits to match caller-controls -->
<!-- <param name="ivr-dtmf-timeout" value="500"/> -->
<!-- How much to wait for the first DTMF, 0 forever -->
<!-- <param name="ivr-input-timeout" value="0" /> -->
<!-- Delay before a conference is asked to be terminated -->
<!-- <param name="endconf-grace-time" value="120" /> -->
<!-- Can be | delim of wait-mod|audio-always|video-bridge|video-floor-only
wait_mod will wait until the moderator in,
audio-always will always mix audio from all members regardless they are talking or not -->
<!-- <param name="conference-flags" value="audio-always"/> -->
<!-- Allow live array sync for Verto -->
<!-- <param name="conference-flags" value="livearray-sync"/> -->
</profile>
<profile name="wideband">
<param name="domain" value="$${domain}"/>
<param name="rate" value="16000"/>
<param name="interval" value="20"/>
<param name="energy-level" value="100"/>
<!-- <param name="sound-prefix" value="$${sounds_dir}/en/us/callie"/> -->
<param name="muted-sound" value="conference/conf-muted.wav"/>
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
<param name="alone-sound" value="conference/conf-alone.wav"/>
<param name="moh-sound" value="$${hold_music}"/>
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
<param name="locked-sound" value="conference/conf-locked.wav"/>
<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>
<param name="pin-sound" value="conference/conf-pin.wav"/>
<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<param name="comfort-noise" value="true"/>
<!-- <param name="tts-engine" value="flite"/> -->
<!-- <param name="tts-voice" value="kal16"/> -->
</profile>
<profile name="ultrawideband">
<param name="domain" value="$${domain}"/>
<param name="rate" value="32000"/>
<param name="interval" value="20"/>
<param name="energy-level" value="100"/>
<!-- <param name="sound-prefix" value="$${sounds_dir}/en/us/callie"/> -->
<param name="muted-sound" value="conference/conf-muted.wav"/>
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
<param name="alone-sound" value="conference/conf-alone.wav"/>
<param name="moh-sound" value="$${hold_music}"/>
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
<param name="locked-sound" value="conference/conf-locked.wav"/>
<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>
<param name="pin-sound" value="conference/conf-pin.wav"/>
<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<param name="comfort-noise" value="true"/>
<!-- <param name="conference-flags" value="video-floor-only|rfc-4579|livearray-sync|auto-3d-position|transcode-video|minimize-video-encoding"/> -->
<!-- <param name="video-mode" value="mux"/> -->
<!-- <param name="video-layout-name" value="3x3"/> -->
<!-- <param name="video-layout-name" value="group:grid"/> -->
<!-- <param name="video-canvas-size" value="1280x720"/> -->
<!-- <param name="video-canvas-bgcolor" value="#333333"/> -->
<!-- <param name="video-layout-bgcolor" value="#000000"/> -->
<!-- <param name="video-codec-bandwidth" value="2mb"/> -->
<!-- <param name="video-fps" value="15"/> -->
<!-- <param name="video-auto-floor-msec" value="100"/> -->
<!-- <param name="tts-engine" value="flite"/> -->
<!-- <param name="tts-voice" value="kal16"/> -->
</profile>
<profile name="cdquality">
<param name="domain" value="$${domain}"/>
<param name="rate" value="48000"/>
<param name="interval" value="20"/>
<param name="energy-level" value="100"/>
<!-- <param name="sound-prefix" value="$${sounds_dir}/en/us/callie"/> -->
{{if not (isTrue .Env.DISABLE_SOUND_MUTED) }}
<param name="muted-sound" value="conference/conf-muted.wav"/>
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
{{end}}
{{if not (isTrue .Env.DISABLE_SOUND_ALONE) }}
<param name="alone-sound" value="conference/conf-alone.wav"/>
{{end}}
<!--
<param name="moh-sound" value="$${hold_music}"/>
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
-->
<param name="locked-sound" value="conference/conf-locked.wav"/>
<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>
<param name="pin-sound" value="conference/conf-pin.wav"/>
<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<!-- param name="comfort-noise" value="true"/ -->
<param name="comfort-noise" value="1400"/>
<param name="video-auto-floor-msec" value="2000"/>
<!-- <param name="conference-flags" value="video-floor-only|rfc-4579|livearray-sync|auto-3d-position|minimize-video-encoding"/> -->
<!-- <param name="video-mode" value="mux"/> -->
<!-- <param name="video-layout-name" value="3x3"/> -->
<!-- <param name="video-layout-name" value="group:grid"/> -->
<!-- <param name="video-canvas-size" value="1920x1080"/> -->
<!-- <param name="video-canvas-bgcolor" value="#333333"/> -->
<!-- <param name="video-layout-bgcolor" value="#000000"/> -->
<!-- <param name="video-codec-bandwidth" value="2mb"/> -->
<!-- <param name="video-fps" value="15"/> -->
</profile>
<profile name="video-mcu-stereo">
<param name="domain" value="$${domain}"/>
<param name="rate" value="48000"/>
<param name="channels" value="2"/>
<param name="interval" value="20"/>
<param name="energy-level" value="100"/>
<!-- <param name="tts-engine" value="flite"/> -->
<!-- <param name="tts-voice" value="kal16"/> -->
<param name="muted-sound" value="conference/conf-muted.wav"/>
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
<param name="alone-sound" value="conference/conf-alone.wav"/>
<param name="moh-sound" value="local_stream://stereo"/>
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
<param name="locked-sound" value="conference/conf-locked.wav"/>
<param name="is-locked-sound" value="conference/conf-is-locked.wav"/>
<param name="is-unlocked-sound" value="conference/conf-is-unlocked.wav"/>
<param name="pin-sound" value="conference/conf-pin.wav"/>
<param name="bad-pin-sound" value="conference/conf-bad-pin.wav"/>
<param name="caller-id-name" value="$${outbound_caller_name}"/>
<param name="caller-id-number" value="$${outbound_caller_id}"/>
<param name="comfort-noise" value="false"/>
<param name="conference-flags" value="video-floor-only|rfc-4579|livearray-sync|minimize-video-encoding"/>
<param name="video-mode" value="mux"/>
<param name="video-layout-name" value="3x3"/>
<param name="video-layout-name" value="group:grid"/>
<param name="video-canvas-size" value="1920x1080"/>
<param name="video-canvas-bgcolor" value="#333333"/>
<param name="video-layout-bgcolor" value="#000000"/>
<param name="video-codec-bandwidth" value="1mb"/>
<param name="video-fps" value="15"/>
</profile>
<profile name="sla">
<param name="domain" value="$${domain}"/>
<param name="rate" value="16000"/>
<param name="interval" value="20"/>
<param name="caller-controls" value="none"/>
<param name="energy-level" value="200"/>
<param name="moh-sound" value="silence"/>
<param name="comfort-noise" value="true"/>
</profile>
</profiles>
</configuration>
@@ -0,0 +1,10 @@
<configuration name="event_socket.conf" description="Socket Client">
<settings>
<param name="nat-map" value="false"/>
<param name="listen-ip" value="$${local_ip_v4}"/>
<param name="listen-port" value="8021"/>
<param name="password" value="$${esl_password}"/>
<param name="apply-inbound-acl" value="rfc1918.auto"/>
<!--<param name="stop-on-bind-error" value="true"/>-->
</settings>
</configuration>
@@ -0,0 +1,32 @@
<configuration name="modules.conf" description="Modules">
<modules>
<!-- Loggers (I'd load these first) -->
<load module="mod_console"/>
<!-- <load module="mod_logfile"/> -->
<!-- Event Handlers -->
<load module="mod_event_socket"/>
<!-- Endpoints -->
<load module="mod_sofia"/>
<!-- Applications -->
<load module="mod_commands"/>
<load module="mod_conference"/>
<load module="mod_dptools"/>
<load module="mod_audio_fork"/>
<!-- Dialplan Interfaces -->
<load module="mod_dialplan_xml"/>
<!-- Codec Interfaces -->
<load module="mod_spandsp"/>
<load module="mod_opus"/>
<load module="mod_opusfile"/>
<!-- File Format Interfaces -->
<load module="mod_sndfile"/>
<load module="mod_native_file"/>
</modules>
</configuration>
@@ -0,0 +1,31 @@
<include>
<extension name="from_my_provider">
<!-- match only calls from dial-in which haven't got transfered yet -->
<condition field="destination_number" expression="^(?!SEND_TO_CONFERENCE).*$"/>
<condition field="${sofia_profile_name}" expression="^external-dialin$">
<action application="start_dtmf" />
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="play_and_get_digits" data="9 9 3 30000 # conference/conf-pin.wav ivr/ivr-that_was_an_invalid_entry.wav pin \d+"/>
<action application="set_profile_var" data="caller_id_name=${regex(${caller_id_name}|^.*(.{4})$|xxx-xxx-%1)}"/>
<action application="transfer" data="SEND_TO_CONFERENCE XML public"/>
</condition>
</extension>
<extension name="check_if_conference_active">
<condition field="${conference ${pin} list}" expression="/sofia/g" />
<condition field="destination_number" expression="^SEND_TO_CONFERENCE$">
<action application="set" data="bbb_authorized=true"/>
<action application="transfer" data="${pin} XML default"/>
</condition>
</extension>
<extension name="conf_bad_pin">
<condition field="${pin}" expression="^\d{5}$">
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="play_and_get_digits" data="9 9 3 30000 # conference/conf-bad-pin.wav ivr/ivr-that_was_an_invalid_entry.wav pin \d+"/>
<action application="transfer" data="SEND_TO_CONFERENCE XML public"/>
</condition>
</extension>
</include>
@@ -0,0 +1,86 @@
<profile name="external-dialin">
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<!-- This profile is only for outbound registrations to providers -->
<gateways>
<X-PRE-PROCESS cmd="include" data="external-dialin/*.xml"/>
</gateways>
<aliases>
<!--
<alias name="outbound"/>
<alias name="nat"/>
-->
</aliases>
<domains>
<domain name="all" alias="false" parse="true"/>
</domains>
<settings>
<param name="debug" value="1"/>
<!-- If you want FreeSWITCH to shutdown if this profile fails to load, uncomment the next line. -->
<!-- <param name="shutdown-on-fail" value="true"/> -->
<param name="sip-trace" value="no"/>
<param name="sip-capture" value="no"/>
<param name="rfc2833-pt" value="101"/>
<!-- RFC 5626 : Send reg-id and sip.instance -->
<!--<param name="enable-rfc-5626" value="true"/> -->
<param name="sip-port" value="5060"/>
<param name="dialplan" value="XML"/>
<param name="context" value="public"/>
<param name="dtmf-duration" value="2000"/>
<param name="inbound-codec-prefs" value="$${global_codec_prefs}"/>
<param name="outbound-codec-prefs" value="$${outbound_codec_prefs}"/>
<param name="hold-music" value="$${hold_music}"/>
<param name="rtp-timer-name" value="soft"/>
<!--<param name="enable-100rel" value="true"/>-->
<!--<param name="disable-srv503" value="true"/>-->
<!-- This could be set to "passive" -->
<param name="local-network-acl" value="localnet.auto"/>
<param name="manage-presence" value="false"/>
<!-- Added for Microsoft Edge browser -->
<param name="apply-candidate-acl" value="localnet.auto"/>
<param name="apply-candidate-acl" value="wan_v4.auto"/>
<param name="apply-candidate-acl" value="rfc1918.auto"/>
<param name="apply-candidate-acl" value="any_v4.auto"/>
<!-- used to share presence info across sofia profiles
manage-presence needs to be set to passive on this profile
if you want it to behave as if it were the internal profile
for presence.
-->
<!-- Name of the db to use for this profile -->
<param name="dbname" value="sqlite://memory://file:external_dialin?mode=memory&amp;cache=shared"/>
<!--<param name="presence-hosts" value="$${domain}"/>-->
<!--<param name="force-register-domain" value="$${domain}"/>-->
<!--all inbound reg will stored in the db using this domain -->
<!--<param name="force-register-db-domain" value="$${domain}"/>-->
<!-- ************************************************* -->
<!--<param name="aggressive-nat-detection" value="true"/>-->
<param name="inbound-codec-negotiation" value="generous"/>
<param name="nonce-ttl" value="60"/>
<param name="auth-calls" value="false"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="true"/> <!-- (also enables late negotiation) -->
<param name="rtp-ip" value="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>
<param name="ext-rtp-ip" value="$${external_ip_v4}"/>
<param name="ext-sip-ip" value="$${external_ip_v4}"/>
<param name="rtp-timeout-sec" value="300"/>
<param name="rtp-hold-timeout-sec" value="1800"/>
<param name="enable-3pcc" value="proxy"/>
<!-- enable rtcp on every channel also can be done per leg basis with rtcp_audio_interval_msec variable set to passthru to pass it across a call-->
<param name="rtcp-audio-interval-msec" value="5000"/>
<param name="rtcp-video-interval-msec" value="5000"/>
<!-- Cut down in the join time -->
<param name="dtmf-type" value="info"/>
<param name="liberal-dtmf" value="true"/>
</settings>
</profile>
@@ -0,0 +1,115 @@
<profile name="external">
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<!-- This profile is only for outbound registrations to providers -->
<domains>
<domain name="all" alias="false" parse="true"/>
</domains>
<settings>
<param name="debug" value="0"/>
<!-- If you want FreeSWITCH to shutdown if this profile fails to load, uncomment the next line. -->
<!-- <param name="shutdown-on-fail" value="true"/> -->
<param name="sip-trace" value="no"/>
<param name="sip-capture" value="no"/>
<param name="rfc2833-pt" value="101"/>
<!-- RFC 5626 : Send reg-id and sip.instance -->
<!--<param name="enable-rfc-5626" value="true"/> -->
<!--
SIP port is not rquired, since we are using WS for the
internal connection and a seperate profile (external-dialin-xml)
for SIP dial in
-->
<param name="sip-port" value="15060"/>
<param name="dialplan" value="XML"/>
<param name="context" value="public"/>
<param name="dtmf-duration" value="2000"/>
<param name="inbound-codec-prefs" value="$${global_codec_prefs}"/>
<param name="outbound-codec-prefs" value="$${outbound_codec_prefs}"/>
<param name="hold-music" value="$${hold_music}"/>
<param name="rtp-timer-name" value="soft"/>
<!--<param name="enable-100rel" value="true"/>-->
<!--<param name="disable-srv503" value="true"/>-->
<!-- This could be set to "passive" -->
<param name="local-network-acl" value="localnet.auto"/>
<param name="manage-presence" value="false"/>
<!-- Added for Microsoft Edge browser -->
<param name="apply-candidate-acl" value="localnet.auto"/>
<param name="apply-candidate-acl" value="wan_v4.auto"/>
<param name="apply-candidate-acl" value="rfc1918.auto"/>
<param name="apply-candidate-acl" value="any_v4.auto"/>
<!-- used to share presence info across sofia profiles
manage-presence needs to be set to passive on this profile
if you want it to behave as if it were the internal profile
for presence.
-->
<!-- Name of the db to use for this profile -->
<param name="dbname" value="sqlite://memory://file:external?mode=memory&amp;cache=shared"/>
<!--<param name="presence-hosts" value="$${domain}"/>-->
<!--<param name="force-register-domain" value="$${domain}"/>-->
<!--all inbound reg will stored in the db using this domain -->
<!--<param name="force-register-db-domain" value="$${domain}"/>-->
<!-- ************************************************* -->
<!--<param name="aggressive-nat-detection" value="true"/>-->
<param name="inbound-codec-negotiation" value="generous"/>
<param name="nonce-ttl" value="60"/>
<param name="auth-calls" value="false"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="true"/> <!-- (also enables late negotiation) -->
<!--
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
<param name="rtp-ip" value="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>
<param name="ext-rtp-ip" value="auto-nat"/>
<param name="ext-sip-ip" value="auto-nat"/>
-->
<param name="rtp-ip" value="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>
<param name="ext-rtp-ip" value="$${local_ip_v4}"/>
<param name="ext-sip-ip" value="$${local_ip_v4}"/>
<param name="rtp-timeout-sec" value="300"/>
<param name="rtp-hold-timeout-sec" value="1800"/>
<param name="enable-3pcc" value="proxy"/>
<!-- TLS: disabled by default, set to "true" to enable -->
<param name="tls" value="$${external_ssl_enable}"/>
<!-- Set to true to not bind on the normal sip-port but only on the TLS port -->
<param name="tls-only" value="false"/>
<!-- additional bind parameters for TLS -->
<param name="tls-bind-params" value="transport=tls"/>
<!-- Port to listen on for TLS requests. (5081 will be used if unspecified) -->
<param name="tls-sip-port" value="$${external_tls_port}"/>
<!-- Location of the agent.pem and cafile.pem ssl certificates (needed for TLS server) -->
<!--<param name="tls-cert-dir" value=""/>-->
<!-- Optionally set the passphrase password used by openSSL to encrypt/decrypt TLS private key files -->
<param name="tls-passphrase" value=""/>
<!-- Verify the date on TLS certificates -->
<param name="tls-verify-date" value="true"/>
<!-- TLS verify policy, when registering/inviting gateways with other servers (outbound) or handling inbound registration/invite requests how should we verify their certificate -->
<!-- set to 'in' to only verify incoming connections, 'out' to only verify outgoing connections, 'all' to verify all connections, also 'in_subjects', 'out_subjects' and 'all_subjects' for subject validation. Multiple policies can be split with a '|' pipe -->
<param name="tls-verify-policy" value="none"/>
<!-- Certificate max verify depth to use for validating peer TLS certificates when the verify policy is not none -->
<param name="tls-verify-depth" value="2"/>
<!-- If the tls-verify-policy is set to subjects_all or subjects_in this sets which subjects are allowed, multiple subjects can be split with a '|' pipe -->
<param name="tls-verify-in-subjects" value=""/>
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
<param name="ws-binding" value="0.0.0.0:5066"/>
<param name="wss-binding" value="0.0.0.0:7443"/>
<!-- enable rtcp on every channel also can be done per leg basis with rtcp_audio_interval_msec variable set to passthru to pass it across a call-->
<param name="rtcp-audio-interval-msec" value="5000"/>
<param name="rtcp-video-interval-msec" value="5000"/>
<!-- Cut down in the join time -->
<param name="dtmf-type" value="info"/>
<param name="liberal-dtmf" value="true"/>
</settings>
</profile>
+453
View File
@@ -0,0 +1,453 @@
<include>
<!-- Preprocessor Variables
These are introduced when configuration strings must be consistent across modules.
NOTICE: YOU CAN NOT COMMENT OUT AN X-PRE-PROCESS line, Remove the line instead.
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
YOU SHOULD CHANGE THIS default_password value if you don't want to be subject to any
toll fraud in the future. It's your responsibility to secure your own system.
This default config is used to demonstrate the feature set of FreeSWITCH.
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-->
<X-PRE-PROCESS cmd="set" data="default_password=1234"/>
<!-- Did you change it yet? -->
<!--
The following variables are set dynamically - calculated if possible by freeswitch - and
are available to the config as $${variable}. You can see their calculated value via fs_cli
by entering eval $${variable}
hostname
local_ip_v4
local_mask_v4
local_ip_v6
switch_serial
base_dir
recordings_dir
sound_prefix
sounds_dir
conf_dir
log_dir
run_dir
db_dir
mod_dir
htdocs_dir
script_dir
temp_dir
grammar_dir
certs_dir
storage_dir
cache_dir
core_uuid
zrtp_enabled
nat_public_addr
nat_private_addr
nat_type
-->
<X-PRE-PROCESS cmd="set" data="sound_prefix={{ .Env.SOUNDS_PATH }}"/>
<X-PRE-PROCESS cmd="set" data="esl_password={{ .Env.ESL_PASSWORD }}"/>
<!--
This setting is what sets the default domain FreeSWITCH will use if all else fails.
FreeSWICH will default to $${local_ip_v4} unless changed. Changing this setting does
affect the sip authentication. Please review conf/directory/default.xml for more
information on this topic.
-->
<X-PRE-PROCESS cmd="set" data="local_ip_v4=0.0.0.0"/>
<X-PRE-PROCESS cmd="set" data="external_ip_v4={{ .Env.EXTERNAL_IPv4 }}"/>
<X-PRE-PROCESS cmd="set" data="domain={{ .Env.DOMAIN }}"/>
<X-PRE-PROCESS cmd="set" data="domain_name=$${domain}"/>
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://moh"/>
<X-PRE-PROCESS cmd="set" data="use_profile=external"/>
<X-PRE-PROCESS cmd="set" data="rtp_sdes_suites=AEAD_AES_256_GCM_8|AEAD_AES_128_GCM_8|AES_CM_256_HMAC_SHA1_80|AES_CM_192_HMAC_SHA1_80|AES_CM_128_HMAC_SHA1_80|AES_CM_256_HMAC_SHA1_32|AES_CM_192_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_32|AES_CM_128_NULL_AUTH"/>
<!--
Enable ZRTP globally you can override this on a per channel basis
http://wiki.freeswitch.org/wiki/ZRTP (on how to enable zrtp)
-->
<X-PRE-PROCESS cmd="set" data="zrtp_secure_media=true"/>
<!--
NOTICE: When using SRTP it's critical that you do not offer or accept
variable bit rate codecs, doing so would leak information and possibly
compromise your SRTP stream. (FS-6404)
Supported SRTP Crypto Suites:
AEAD_AES_256_GCM_8
____________________________________________________________________________
This algorithm is identical to AEAD_AES_256_GCM (see Section 5.2 of
[RFC5116]), except that the tag length, t, is 8, and an
authentication tag with a length of 8 octets (64 bits) is used.
An AEAD_AES_256_GCM_8 ciphertext is exactly 8 octets longer than its
corresponding plaintext.
AEAD_AES_128_GCM_8
____________________________________________________________________________
This algorithm is identical to AEAD_AES_128_GCM (see Section 5.1 of
[RFC5116]), except that the tag length, t, is 8, and an
authentication tag with a length of 8 octets (64 bits) is used.
An AEAD_AES_128_GCM_8 ciphertext is exactly 8 octets longer than its
corresponding plaintext.
AES_CM_256_HMAC_SHA1_80 | AES_CM_192_HMAC_SHA1_80 | AES_CM_128_HMAC_SHA1_80
____________________________________________________________________________
AES_CM_128_HMAC_SHA1_80 is the SRTP default AES Counter Mode cipher
and HMAC-SHA1 message authentication with an 80-bit authentication
tag. The master-key length is 128 bits and has a default lifetime of
a maximum of 2^48 SRTP packets or 2^31 SRTCP packets, whichever comes
first.
AES_CM_256_HMAC_SHA1_32 | AES_CM_192_HMAC_SHA1_32 | AES_CM_128_HMAC_SHA1_32
____________________________________________________________________________
This crypto-suite is identical to AES_CM_128_HMAC_SHA1_80 except that
the authentication tag is 32 bits. The length of the base64-decoded key and
salt value for this crypto-suite MUST be 30 octets i.e., 240 bits; otherwise,
the crypto attribute is considered invalid.
AES_CM_128_NULL_AUTH
____________________________________________________________________________
The SRTP default cipher (AES-128 Counter Mode), but to use no authentication
method. This policy is NOT RECOMMENDED unless it is unavoidable; see
Section 7.5 of [RFC3711].
SRTP variables that modify behaviors based on direction/leg:
rtp_secure_media
____________________________________________________________________________
possible values:
mandatory - Accept/Offer SAVP negotiation ONLY
optional - Accept/Offer SAVP/AVP with SAVP preferred
forbidden - More useful for inbound to deny SAVP negotiation
false - implies forbidden
true - implies mandatory
default if not set is accept SAVP inbound if offered.
rtp_secure_media_inbound | rtp_secure_media_outbound
____________________________________________________________________________
This is the same as rtp_secure_media, but would apply to either inbound
or outbound offers specifically.
How to specify crypto suites:
____________________________________________________________________________
By default without specifying any crypto suites FreeSWITCH will offer
crypto suites from strongest to weakest accepting the strongest each
endpoint has in common. If you wish to force specific crypto suites you
can do so by appending the suites in a comma separated list in the order
that you wish to offer them in.
Examples:
rtp_secure_media=mandatory:AES_CM_256_HMAC_SHA1_80,AES_CM_256_HMAC_SHA1_32
rtp_secure_media=true:AES_CM_256_HMAC_SHA1_80,AES_CM_256_HMAC_SHA1_32
rtp_secure_media=optional:AES_CM_256_HMAC_SHA1_80
rtp_secure_media=true:AES_CM_256_HMAC_SHA1_80
Additionally you can narrow this down on either inbound or outbound by
specifying as so:
rtp_secure_media_inbound=true:AEAD_AES_256_GCM_8
rtp_secure_media_inbound=mandatory:AEAD_AES_256_GCM_8
rtp_secure_media_outbound=true:AEAD_AES_128_GCM_8
rtp_secure_media_outbound=optional:AEAD_AES_128_GCM_8
rtp_secure_media_suites
____________________________________________________________________________
Optionally you can use rtp_secure_media_suites to dictate the suite list
and only use rtp_secure_media=[optional|mandatory|false|true] without having
to dictate the suite list with the rtp_secure_media* variables.
-->
<!--
Examples of codec options: (module must be compiled and loaded)
codecname[@8000h|16000h|32000h[@XXi]]
XX is the frame size must be multiples allowed for the codec
FreeSWITCH can support 10-120ms on some codecs.
We do not support exceeding the MTU of the RTP packet.
iLBC@30i - iLBC using mode=30 which will win in all cases.
DVI4@8000h@20i - IMA ADPCM 8kHz using 20ms ptime. (multiples of 10)
DVI4@16000h@40i - IMA ADPCM 16kHz using 40ms ptime. (multiples of 10)
speex@8000h@20i - Speex 8kHz using 20ms ptime.
speex@16000h@20i - Speex 16kHz using 20ms ptime.
speex@32000h@20i - Speex 32kHz using 20ms ptime.
BV16 - BroadVoice 16kb/s narrowband, 8kHz
BV32 - BroadVoice 32kb/s wideband, 16kHz
G7221@16000h - G722.1 16kHz (aka Siren 7)
G7221@32000h - G722.1C 32kHz (aka Siren 14)
CELT@32000h - CELT 32kHz, only 10ms supported
CELT@48000h - CELT 48kHz, only 10ms supported
GSM@40i - GSM 8kHz using 40ms ptime. (GSM is done in multiples of 20, Default is 20ms)
G722 - G722 16kHz using default 20ms ptime. (multiples of 10)
PCMU - G711 8kHz ulaw using default 20ms ptime. (multiples of 10)
PCMA - G711 8kHz alaw using default 20ms ptime. (multiples of 10)
G726-16 - G726 16kbit adpcm using default 20ms ptime. (multiples of 10)
G726-24 - G726 24kbit adpcm using default 20ms ptime. (multiples of 10)
G726-32 - G726 32kbit adpcm using default 20ms ptime. (multiples of 10)
G726-40 - G726 40kbit adpcm using default 20ms ptime. (multiples of 10)
AAL2-G726-16 - Same as G726-16 but using AAL2 packing. (multiples of 10)
AAL2-G726-24 - Same as G726-24 but using AAL2 packing. (multiples of 10)
AAL2-G726-32 - Same as G726-32 but using AAL2 packing. (multiples of 10)
AAL2-G726-40 - Same as G726-40 but using AAL2 packing. (multiples of 10)
LPC - LPC10 using 90ms ptime (only supports 90ms at this time in FreeSWITCH)
L16 - L16 isn't recommended for VoIP but you can do it. L16 can exceed the MTU rather quickly.
These are the passthru audio codecs:
G729 - G729 in passthru mode. (mod_g729)
G723 - G723.1 in passthru mode. (mod_g723_1)
AMR - AMR in passthru mode. (mod_amr)
These are the passthru video codecs: (mod_h26x)
H261 - H.261 Video
H263 - H.263 Video
H263-1998 - H.263-1998 Video
H263-2000 - H.263-2000 Video
H264 - H.264 Video
RTP Dynamic Payload Numbers currently used in FreeSWITCH and what for.
96 - AMR
97 - iLBC (30)
98 - iLBC (20)
99 - Speex 8kHz, 16kHz, 32kHz
100 -
101 - telephone-event
102 -
103 -
104 -
105 -
106 - BV16
107 - G722.1 (16kHz)
108 -
109 -
110 -
111 -
112 -
113 -
114 - CELT 32kHz, 48kHz
115 - G722.1C (32kHz)
116 -
117 - SILK 8kHz
118 - SILK 12kHz
119 - SILK 16kHz
120 - SILK 24kHz
121 - AAL2-G726-40 && G726-40
122 - AAL2-G726-32 && G726-32
123 - AAL2-G726-24 && G726-24
124 - AAL2-G726-16 && G726-16
125 -
126 -
127 - BV32
-->
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,speex@16000h@20i,speex@8000h@20i,G722,PCMU,PCMA"/>
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=OPUS,speex@16000h@20i,G722,PCMU,PCMA"/>
<!--
xmpp_client_profile and xmpp_server_profile
xmpp_client_profile can be any string.
xmpp_server_profile is appended to "dingaling_" to form the database name
containing the "subscriptions" table.
used by: dingaling.conf.xml enum.conf.xml
-->
<X-PRE-PROCESS cmd="set" data="xmpp_client_profile=xmppc"/>
<X-PRE-PROCESS cmd="set" data="xmpp_server_profile=xmpps"/>
<!--
THIS IS ONLY USED FOR DINGALING
bind_server_ip
Can be an ip address, a dns name, or "auto".
This determines an ip address available on this host to bind.
If you are separating RTP and SIP traffic, you will want to have
use different addresses where this variable appears.
Used by: dingaling.conf.xml
-->
<X-PRE-PROCESS cmd="set" data="bind_server_ip=auto"/>
<!-- NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
If you're going to load test FreeSWITCH please input real IP addresses
for external_rtp_ip and external_sip_ip
-->
<!-- external_rtp_ip
Can be an one of:
ip address: "12.34.56.78"
a stun server lookup: "stun:stun.server.com"
a DNS name: "host:host.server.com"
where fs.mydomain.com is a DNS A record-useful when fs is on
a dynamic IP address, and uses a dynamic DNS updater.
If unspecified, the bind_server_ip value is used.
Used by: sofia.conf.xml dingaling.conf.xml
-->
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=stun:stun.l.google.com:19302"/>
<!-- external_sip_ip
Used as the public IP address for SDP.
Can be an one of:
ip address: "12.34.56.78"
a stun server lookup: "stun:stun.server.com"
a DNS name: "host:host.server.com"
where fs.mydomain.com is a DNS A record-useful when fs is on
a dynamic IP address, and uses a dynamic DNS updater.
If unspecified, the bind_server_ip value is used.
Used by: sofia.conf.xml dingaling.conf.xml
-->
<X-PRE-PROCESS cmd="set" data="external_sip_ip=stun:stun.l.google.com:19302"/>
<!-- unroll-loops
Used to turn on sip loopback unrolling.
-->
<X-PRE-PROCESS cmd="set" data="unroll_loops=true"/>
<!-- outbound_caller_id and outbound_caller_name
The caller ID telephone number we should use when calling out.
Used by: conference.conf.xml and user directory for default
outbound callerid name and number.
-->
<X-PRE-PROCESS cmd="set" data="outbound_caller_name=FreeSWITCH"/>
<X-PRE-PROCESS cmd="set" data="outbound_caller_id=0000000000"/>
<!-- various debug and defaults -->
<X-PRE-PROCESS cmd="set" data="call_debug=false"/>
<X-PRE-PROCESS cmd="set" data="console_loglevel=info"/>
<X-PRE-PROCESS cmd="set" data="default_areacode=918"/>
<X-PRE-PROCESS cmd="set" data="default_country=US"/>
<!-- if false or undefined, the destination number is included in presence NOTIFY dm:note.
if true, the destination number is not included -->
<X-PRE-PROCESS cmd="set" data="presence_privacy=false"/>
<X-PRE-PROCESS cmd="set" data="au-ring=%(400,200,383,417);%(400,2000,383,417)"/>
<X-PRE-PROCESS cmd="set" data="be-ring=%(1000,3000,425)"/>
<X-PRE-PROCESS cmd="set" data="ca-ring=%(2000,4000,440,480)"/>
<X-PRE-PROCESS cmd="set" data="cn-ring=%(1000,4000,450)"/>
<X-PRE-PROCESS cmd="set" data="cy-ring=%(1500,3000,425)"/>
<X-PRE-PROCESS cmd="set" data="cz-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="de-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="dk-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="dz-ring=%(1500,3500,425)"/>
<X-PRE-PROCESS cmd="set" data="eg-ring=%(2000,1000,475,375)"/>
<X-PRE-PROCESS cmd="set" data="es-ring=%(1500,3000,425)"/>
<X-PRE-PROCESS cmd="set" data="fi-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="fr-ring=%(1500,3500,440)"/>
<X-PRE-PROCESS cmd="set" data="hk-ring=%(400,200,440,480);%(400,3000,440,480)"/>
<X-PRE-PROCESS cmd="set" data="hu-ring=%(1250,3750,425)"/>
<X-PRE-PROCESS cmd="set" data="il-ring=%(1000,3000,400)"/>
<X-PRE-PROCESS cmd="set" data="in-ring=%(400,200,425,375);%(400,2000,425,375)"/>
<X-PRE-PROCESS cmd="set" data="jp-ring=%(1000,2000,420,380)"/>
<X-PRE-PROCESS cmd="set" data="ko-ring=%(1000,2000,440,480)"/>
<X-PRE-PROCESS cmd="set" data="pk-ring=%(1000,2000,400)"/>
<X-PRE-PROCESS cmd="set" data="pl-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="ro-ring=%(1850,4150,475,425)"/>
<X-PRE-PROCESS cmd="set" data="rs-ring=%(1000,4000,425)"/>
<X-PRE-PROCESS cmd="set" data="ru-ring=%(800,3200,425)"/>
<X-PRE-PROCESS cmd="set" data="sa-ring=%(1200,4600,425)"/>
<X-PRE-PROCESS cmd="set" data="tr-ring=%(2000,4000,450)"/>
<X-PRE-PROCESS cmd="set" data="uk-ring=%(400,200,400,450);%(400,2000,400,450)"/>
<X-PRE-PROCESS cmd="set" data="us-ring=%(2000,4000,440,480)"/>
<X-PRE-PROCESS cmd="set" data="bong-ring=v=-7;%(100,0,941.0,1477.0);v=-7;>=2;+=.1;%(1400,0,350,440)"/>
<X-PRE-PROCESS cmd="set" data="beep=%(1000,0,640)"/>
<X-PRE-PROCESS cmd="set" data="sit=%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)"/>
<!--
Digits Dialed filter: (FS-6940)
The digits stream may contain valid credit card numbers or social security numbers, These digit
filters will allow you to make a valant effort to stamp out sensitive information for
PCI/HIPPA compliance. (see xml_cdr dialed_digits)
df_us_ssn = US Social Security Number pattern
df_us_luhn = Visa, MasterCard, American Express, Diners Club, Discover and JCB
-->
<X-PRE-PROCESS cmd="set" data="df_us_ssn=(?!219099999|078051120)(?!666|000|9\d{2})\d{3}(?!00)\d{2}(?!0{4})\d{4}"/>
<X-PRE-PROCESS cmd="set" data="df_luhn=?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11}"/>
<!-- change XX to X below to enable -->
<XX-PRE-PROCESS cmd="set" data="digits_dialed_filter=(($${df_luhn})|($${df_us_ssn}))"/>
<!--
Setting up your default sip provider is easy.
Below are some values that should work in most cases.
These are for conf/directory/default/example.com.xml
-->
<X-PRE-PROCESS cmd="set" data="default_provider=example.com"/>
<X-PRE-PROCESS cmd="set" data="default_provider_username=joeuser"/>
<X-PRE-PROCESS cmd="set" data="default_provider_password=password"/>
<X-PRE-PROCESS cmd="set" data="default_provider_from_domain=example.com"/>
<!-- true or false -->
<X-PRE-PROCESS cmd="set" data="default_provider_register=false"/>
<X-PRE-PROCESS cmd="set" data="default_provider_contact=5000"/>
<!--
SIP and TLS settings. http://wiki.freeswitch.org/wiki/Tls
valid options: sslv2,sslv3,sslv23,tlsv1,tlsv1.1,tlsv1.2
default: tlsv1,tlsv1.1,tlsv1.2
-->
<X-PRE-PROCESS cmd="set" data="sip_tls_version=tlsv1,tlsv1.1,tlsv1.2"/>
<!--
TLS cipher suite: default ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH
The actual ciphers supported will change per platform.
openssl ciphers -v 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH'
Will show you what is available in your version of openssl.
-->
<X-PRE-PROCESS cmd="set" data="sip_tls_ciphers=ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"/>
<!-- Internal SIP Profile -->
<X-PRE-PROCESS cmd="set" data="internal_auth_calls=true"/>
<X-PRE-PROCESS cmd="set" data="internal_sip_port=5090"/>
<X-PRE-PROCESS cmd="set" data="internal_tls_port=5061"/>
<X-PRE-PROCESS cmd="set" data="internal_ssl_enable=false"/>
<!-- External SIP Profile -->
<X-PRE-PROCESS cmd="set" data="external_auth_calls=false"/>
<X-PRE-PROCESS cmd="set" data="external_sip_port=5060"/>
<X-PRE-PROCESS cmd="set" data="external_tls_port=5081"/>
<X-PRE-PROCESS cmd="set" data="external_ssl_enable=false"/>
<!-- Video Settings -->
<!-- Setting the max bandwidth -->
<X-PRE-PROCESS cmd="set" data="rtp_video_max_bandwidth_in=1mb"/>
<X-PRE-PROCESS cmd="set" data="rtp_video_max_bandwidth_out=1mb"/>
<!-- WebRTC Video -->
<!-- Suppress CNG for WebRTC Audio -->
<X-PRE-PROCESS cmd="set" data="suppress_cng=true"/>
<!-- Enable liberal DTMF for those that can't get it right -->
<X-PRE-PROCESS cmd="set" data="rtp_liberal_dtmf=true"/>
<!-- Helps with WebRTC Audio -->
<!-- Stock Video Avatars -->
<X-PRE-PROCESS cmd="set" data="video_mute_png=$${images_dir}/default-mute.png"/>
<X-PRE-PROCESS cmd="set" data="video_no_avatar_png=$${images_dir}/default-avatar.png"/>
</include>
+72
View File
@@ -0,0 +1,72 @@
#!/bin/bash -e
# remove all SIP (port 5060) iptable rules
iptables -S INPUT | grep "\-\-dport 5060 " | cut -d " " -f 2- | xargs -rL1 iptables -D
# block requests to 5060 (tcp/udp)
iptables -A INPUT -p tcp --dport 5060 -s 0.0.0.0/0 -j REJECT
iptables -A INPUT -p udp --dport 5060 -s 0.0.0.0/0 -j REJECT
# allow some IPs
IFS=',' read -ra ADDR <<< "$SIP_IP_ALLOWLIST"
for IP in "${ADDR[@]}"; do
# process "$i"
echo "allow port 5060/udp for $IP"
iptables -I INPUT -p udp --dport 5060 -s $IP -j ACCEPT
done
mkdir -p /var/freeswitch/meetings
chown -R freeswitch:daemon /var/freeswitch/meetings
chmod 777 /var/freeswitch/meetings
chown -R freeswitch:daemon /opt/freeswitch/var
chown -R freeswitch:daemon /opt/freeswitch/etc
chmod -R g-rwx,o-rwx /opt/freeswitch/etc
# install freeswitch sounds if missing
SOUNDS_DIR=/opt/freeswitch/share/freeswitch/sounds
if [ "$SOUNDS_LANGUAGE" == "en-us-callie" ]; then
# default, is already installed
echo ""
elif [ "$SOUNDS_LANGUAGE" == "de-de-daedalus3" ]; then
if [ ! -d "$SOUNDS_DIR/de/de/daedalus3" ]; then
echo "sounds package for de-de-daedalus3 not installed yet"
wget -O /tmp/freeswitch-german-soundfiles.zip https://github.com/Daedalus3/freeswitch-german-soundfiles/archive/master.zip
mkdir -p $SOUNDS_DIR/de/de/daedalus3
unzip /tmp/freeswitch-german-soundfiles.zip -d /tmp/
mv /tmp/freeswitch-german-soundfiles-master $SOUNDS_DIR/de/de/daedalus3/conference
# symlink other folders
for folder in "digits" "ivr" "misc"; do
ln -s $SOUNDS_DIR/en/us/callie/$folder $SOUNDS_DIR/de/de/daedalus3/$folder
done
fi
else
if [ ! -f $SOUNDS_DIR/$SOUNDS_LANGUAGE.installed ]; then
echo "sounds package for $SOUNDS_LANGUAGE not installed yet"
# get filename of latest release for this sound package
FILENAME=$(curl -s https://files.freeswitch.org/releases/sounds/ | grep -i $SOUNDS_LANGUAGE 2> /dev/null | awk -F'\"' '{print $8}' | grep -E '\-48000-.*\.gz$' | sort -V | tail -n 1)
if [ "$FILENAME" = "" ]; then
echo "Error: could not find sounds for language '$SOUNDS_LANGUAGE'"
echo "make sure to specify a value for SOUNDS_LANGUAGE which exists on https://files.freeswitch.org/releases/sounds/"
exit 1
fi
for bitrate in 8000 16000 32000 48000; do
URL=https://files.freeswitch.org/releases/sounds/$(echo $FILENAME | sed "s/48000/$bitrate/")
wget -O /tmp/sounds.tar.gz $URL
tar xvfz /tmp/sounds.tar.gz -C $SOUNDS_DIR
done
touch $SOUNDS_DIR/$SOUNDS_LANGUAGE.installed
fi
fi
export SOUNDS_PATH=$SOUNDS_DIR/$(echo "$SOUNDS_LANGUAGE" | sed 's|-|/|g')
dockerize \
-template /etc/freeswitch/vars.xml.tmpl:/etc/freeswitch/vars.xml \
-template /etc/freeswitch/autoload_configs/conference.conf.xml.tmpl:/etc/freeswitch/autoload_configs/conference.conf.xml \
/opt/freeswitch/bin/freeswitch -u freeswitch -g daemon -nonat -nf
+30
View File
@@ -0,0 +1,30 @@
ARG BBB_BUILD_TAG
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder
COPY --from=src-common-message / /bbb-common-message
# build bbb-common-message
RUN cd /bbb-common-message && ./deploy.sh
# ===================================================
COPY --from=src-fsesl-client / /bbb-fsesl-client
RUN cd /bbb-fsesl-client && ./deploy.sh
COPY --from=src-fsesl-akka / /source
# compile and unzip bin
RUN cd /source \
&& sbt universal:packageBin
RUN unzip /source/target/universal/bbb-fsesl-akka-0.0.2.zip -d /
# # ===================================================
FROM alangecker/bbb-docker-base-java
COPY --from=builder /bbb-fsesl-akka-0.0.2 /bbb-fsesl-akka
COPY bbb-fsesl-akka.conf /etc/bigbluebutton/bbb-fsesl-akka.conf.tmpl
COPY logback.xml /bbb-fsesl-akka/conf/logback.xml
COPY entrypoint.sh /entrypoint.sh
USER bigbluebutton
ENTRYPOINT /entrypoint.sh
+18
View File
@@ -0,0 +1,18 @@
// include default config from upstream
include "/bbb-fsesl-akka/conf/application.conf"
freeswitch {
esl {
host="freeswitch"
password="FSESL_PASSWORD"
}
}
redis {
host="redis"
}
http {
interface = "0.0.0.0"
}
+9
View File
@@ -0,0 +1,9 @@
#!/bin/sh -e
TARGET=/etc/bigbluebutton/bbb-fsesl-akka.conf
cp /etc/bigbluebutton/bbb-fsesl-akka.conf.tmpl $TARGET
sed -i "s/FSESL_PASSWORD/$FSESL_PASSWORD/" $TARGET
cd /bbb-fsesl-akka
/bbb-fsesl-akka/bin/bbb-fsesl-akka
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"} %-5level %logger{35} - %msg%n</Pattern>
</layout>
</appender>
<logger name="akka" level="INFO" />
<logger name="org.bigbluebutton" level="DEBUG" />
<logger name="org.freeswitch.esl" level="WARN" />
<logger name="io.lettuce" level="INFO" />
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
+80
View File
@@ -0,0 +1,80 @@
global
log stdout format raw local0 debug
maxconn 20480
############# IMPORTANT #################################
## DO NOT SET CHROOT OTHERWISE YOU HAVE TO CHANGE THE ##
## acme-http01-webroot.lua file ##
# chroot /jail ##
#########################################################
lua-load /etc/haproxy/acme-http01-webroot.lua
#
# SSL options
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
ssl-default-bind-options ssl-min-ver TLSv1.2
tune.ssl.default-dh-param 4096
# workaround for bug #14 (Cert renewal blocks HAProxy indefinitely with Websocket connections)
hard-stop-after 3s
# DNS runt-time resolution on backend hosts
resolvers docker
nameserver dns "127.0.0.11:53"
defaults
log global
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
# option forwardfor
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
# never fail on address resolution
default-server init-addr last,libc,none
frontend http
bind *:80,[::]:80
mode http
acl url_acme_http01 path_beg /.well-known/acme-challenge/
http-request use-service lua.acme-http01 if METH_GET url_acme_http01
redirect scheme https code 301 if !{ ssl_fc }
frontend nginx_or_turn
bind *:443,:::443 ssl crt /etc/haproxy/certs/ ssl-min-ver TLSv1.2 alpn h2,http/1.1,stun.turn
mode tcp
option tcplog
tcp-request content capture req.payload(0,1) len 1
log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq captured_user:%{+X}[capture.req.hdr(0)]"
tcp-request inspect-delay 30s
# We terminate SSL on haproxy. HTTP2 is a binary protocol. haproxy has to
# decide which protocol is spoken. This is negotiated by ALPN.
#
# Depending on the ALPN value traffic is redirected to either port 82 (HTTP2,
# ALPN value h2) or 81 (HTTP 1.0 or HTTP 1.1, ALPN value http/1.1 or no value)
# If no ALPN value is set, the first byte is inspected and depending on the
# value traffic is sent to either port 81 or coturn.
use_backend nginx-http2 if { ssl_fc_alpn h2 }
use_backend nginx if { ssl_fc_alpn http/1.1 }
use_backend turn if { ssl_fc_alpn stun.turn }
use_backend %[capture.req.hdr(0),map_str(/etc/haproxy/protocolmap,turn)]
default_backend turn
backend turn
mode tcp
server localhost webrtc-sfu:3478 check
backend nginx
mode tcp
server localhost nginx:48081 send-proxy check
backend nginx-http2
mode tcp
server localhost nginx:48082 send-proxy check
+4
View File
@@ -0,0 +1,4 @@
FROM ghcr.io/tomdess/docker-haproxy-certbot:2.8.10
# overwrite bootstrap.sh
COPY bootstrap.sh /bootstrap.sh
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -e
# save container environment variables to use it
# in cron scripts
declare -p | grep -Ev '^declare -[[:alpha:]]*r' > /container.env
# when used with an IP, we'll also disable certbot
if [[ "$CERT1" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
IGNORE_TLS_CERT_ERRORS=true
fi
if [ "$IGNORE_TLS_CERT_ERRORS" ] && [ "$IGNORE_TLS_CERT_ERRORS" != "false" ]; then
# use self signed certificate
if [ ! -f /etc/haproxy/certs/haproxy-10.7.7.1.pem ]; then
mkdir -p /etc/haproxy/certs
# generate self signed certificate
openssl req -x509 -nodes -days 700 -newkey rsa:2048 \
-keyout /tmp/domain.key -out /tmp/domain.crt \
-subj "/C=CA/ST=Quebec/L=Montreal/O=BigBlueButton Development/OU=bbb-docker/CN=10.7.7.1"
cat /tmp/domain.key /tmp/domain.crt | tee /etc/haproxy/certs/haproxy-10.7.7.1.pem >/dev/null
fi
else
# obtain certificates from lets encrypt
/certs.sh
fi
supervisord -c /etc/supervisord.conf -n
+52
View File
@@ -0,0 +1,52 @@
a nginx
b nginx
c nginx
d nginx
e nginx
f nginx
g nginx
h nginx
i nginx
j nginx
k nginx
l nginx
m nginx
n nginx
o nginx
p nginx
q nginx
r nginx
s nginx
t nginx
u nginx
v nginx
w nginx
x nginx
y nginx
z nginx
A nginx
B nginx
C nginx
D nginx
E nginx
F nginx
G nginx
H nginx
I nginx
J nginx
K nginx
L nginx
M nginx
N nginx
O nginx
P nginx
Q nginx
R nginx
S nginx
T nginx
U nginx
V nginx
W nginx
X nginx
Y nginx
Z nginx
+13
View File
@@ -0,0 +1,13 @@
ARG BBB_BUILD_TAG
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG
# use /tmp as home dir as writeable directory for whatever UID we get
ENV HOME /tmp
# allow all user to access .nvm in root
RUN chmod 755 /root
WORKDIR /app
COPY /entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh
+11
View File
@@ -0,0 +1,11 @@
set -e
# enable nvm
. /root/.nvm/nvm.sh
if [ -n "$1" ]; then
exec "$@"
else
npm install
npm start -- --host 0.0.0.0
fi
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
set -e
set -u
function create_user_and_database() {
local database=$1
echo " Creating user and database '$database'"
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
CREATE DATABASE $database;
GRANT ALL PRIVILEGES ON DATABASE $database TO $POSTGRES_USER;
EOSQL
}
if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then
echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES"
for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do
create_user_and_database $db
done
echo "Multiple databases created"
fi
+15
View File
@@ -0,0 +1,15 @@
port: 7880
log_level: debug
# when enabled, LiveKit will expose prometheus metrics on :6789/metrics
#prometheus_port: 6789
rtc:
port_range_start: 16384
port_range_end: 32768
use_external_ip: false
redis:
# redis is recommended for production deploys
address: redis:6379
keys:
# TODO: change keys
TEST: TEST
+33
View File
@@ -0,0 +1,33 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_rlimit_nofile 20000;
events {
worker_connections 10000;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
+49
View File
@@ -0,0 +1,49 @@
ARG BBB_BUILD_TAG
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder-learning-dashboard
COPY --from=src-learning-dashboard / /bbb-learning-dashboard
RUN cd /bbb-learning-dashboard && npm ci && npm run build
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder-playback
COPY --from=src-playback / /bbb-playback
RUN cd /bbb-playback && npm install && npm run-script build
FROM bigbluebutton/bbb-build:$BBB_BUILD_TAG AS builder-html5
COPY --from=src-html5 / /source
RUN cd /source && CI=true npm ci
RUN cd /source && DISABLE_ESLINT_PLUGIN=true npm run build-safari && npm run build
RUN cd /source/dist && \
HASH=$(ls | grep -Eo 'bundle\.[a-f0-9]{20}\.js' | head -n 1 | grep -Eo '[a-f0-9]{20}') && \
if [ -z "$HASH" ]; then \
echo "Bundle hash not found."; \
else \
for FILE in *.safari.js *.safari.js.map; do \
if [[ "$FILE" == *"$HASH"* ]]; then \
continue; \
fi; \
PREFIX="${FILE%%.safari.js*}"; \
SUFFIX="${FILE#*.safari.js}"; \
NEW_NAME="${PREFIX}.${HASH}.safari.js${SUFFIX}"; \
echo "Renaming $FILE$NEW_NAME"; \
mv "$FILE" "$NEW_NAME"; \
done; \
fi
RUN find /source/dist -name '*.js' -exec gzip -k -f -9 '{}' \; \
&& find /source/dist -name '*.css' -exec gzip -k -f -9 '{}' \; \
&& find /source/dist -name '*.wasm' -exec gzip -k -f -9 '{}' \;
RUN sed -i "s/?v=VERSION/?v=$BBB_BUILD_TAG/g" /source/dist/index.html && \
sed -i "s/?v=VERSION/?v=$BBB_BUILD_TAG/g" /source/dist/stylesheets/fonts.css
# --------------------
FROM nginx:1.29-alpine
COPY --from=builder-learning-dashboard /bbb-learning-dashboard/build /www/learning-analytics-dashboard/
COPY --from=builder-playback /bbb-playback/build /www/playback/presentation/2.3
COPY --from=builder-html5 /source/dist /usr/share/bigbluebutton/html5-client/
COPY ./bbb /etc/nginx/bbb
COPY ./bigbluebutton /etc/nginx/conf.d/default.conf
COPY ./bbb-graphql-client-settings-cache.conf /etc/nginx/conf.d/bbb-graphql-client-settings-cache.conf
COPY ./nginx.conf /etc/nginx/nginx.conf
@@ -0,0 +1 @@
proxy_cache_path /tmp/hasura-client-settings-cache levels=1:2 keys_zone=client_settings_cache:64m inactive=2880m use_temp_path=off;
+21
View File
@@ -0,0 +1,21 @@
# running in production (static assets)
location /html5client {
gzip_static on;
alias /usr/share/bigbluebutton/html5-client/;
index index.html;
try_files $uri $uri/ =404;
}
location /html5client/locales {
alias /usr/share/bigbluebutton/html5-client/locales;
autoindex on;
autoindex_format json;
}
location /html5client/wasm {
types {
application/wasm wasm;
}
gzip_static on;
alias /usr/share/bigbluebutton/html5-client/wasm;
}
+10
View File
@@ -0,0 +1,10 @@
# Forward request to /demo to tomcat. This is for
# the BigBlueButton api demos.
location = /demo/ {
return 301 /demo/demo1.jsp;
}
# temporarily since the original used host networking
location /demo {
return 404;
}
+71
View File
@@ -0,0 +1,71 @@
# Websocket connection
location /graphql {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
#proxy_pass http://bbb-graphql-server:8085; #Hasura (it requires to change the location to /v1/graphql)
proxy_pass http://bbb-graphql-middleware:8378; #Graphql Middleware
}
#DEPRECATED:
#This endpoint is being replaced by /api/rest/meetingStaticData (which contain clientSettings and more)
#It will be removed in BBB 3.1
location /api/rest/clientSettings {
auth_request /bigbluebutton/connection/checkGraphqlAuthorization;
auth_request_set $meeting_id $sent_http_meeting_id;
proxy_cache client_settings_cache;
proxy_cache_key "$uri|$meeting_id";
proxy_cache_use_stale updating;
proxy_cache_valid 24h;
proxy_cache_lock on;
proxy_cache_lock_timeout 5s; # how long other requests may wait for the first one holding the cache lock
proxy_cache_lock_age 10s; # consider the lock stale after this time (prevents a stuck lock if upstream hangs)
# proxy_cache_background_update on; # optional: serve stale while refreshing the cache in background
add_header X-Cached $upstream_cache_status;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 3s; # max time to establish TCP connection to Hasura
proxy_send_timeout 15s; # max time to send the request to Hasura
proxy_read_timeout 30s; # max time to wait for Hasuras response
proxy_set_header Host $host;
proxy_pass http://bbb-graphql-server:8085; #Hasura
}
#Set cache system for meeting static data
location /api/rest/meetingStaticData {
auth_request /bigbluebutton/connection/checkGraphqlAuthorization;
auth_request_set $meeting_id $sent_http_meeting_id;
proxy_cache client_settings_cache;
proxy_cache_key "$uri|$meeting_id";
proxy_cache_use_stale updating;
proxy_cache_valid 24h;
proxy_cache_lock on;
proxy_cache_lock_timeout 5s; # how long other requests may wait for the first one holding the cache lock
proxy_cache_lock_age 10s; # consider the lock stale after this time (prevents a stuck lock if upstream hangs)
# proxy_cache_background_update on; # optional: serve stale while refreshing the cache in background
add_header X-Cached $upstream_cache_status;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 3s; # max time to establish TCP connection to Hasura
proxy_send_timeout 15s; # max time to send the request to Hasura
proxy_read_timeout 30s; # max time to wait for Hasuras response
proxy_set_header Host $host;
proxy_pass http://bbb-graphql-server:8085; #Hasura
}
location /api/rest/userMetadata {
auth_request /bigbluebutton/connection/checkGraphqlAuthorization;
auth_request_set $meeting_id $sent_http_meeting_id;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_pass http://bbb-graphql-server:8085; #Hasura
}
+4
View File
@@ -0,0 +1,4 @@
location /learning-analytics-dashboard/ {
alias /www/learning-analytics-dashboard/;
autoindex off;
}
+11
View File
@@ -0,0 +1,11 @@
location /livekit/ {
proxy_pass http://127.0.0.1:7880/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_read_timeout 60s;
proxy_send_timeout 60s;
client_body_timeout 60s;
send_timeout 60s;
}
+4
View File
@@ -0,0 +1,4 @@
# If you run this BBB node behind a proxy loadbalancer set the hostname of
# the loadbalancer here. This will be used to add CORS headers so requesting
# slides and API calls won't fail
set $bbb_loadbalancer_node '';
+4
View File
@@ -0,0 +1,4 @@
location /notes {
root /var/bigbluebutton/published;
index index.html index.htm;
}
+77
View File
@@ -0,0 +1,77 @@
# https://github.com/ether/etherpad-lite/wiki/How-to-put-Etherpad-Lite-behind-a-reverse-Proxy
location /pad/p/ {
# Avoid setting the user name from the embedded URL
if ($arg_userName) {
return 401;
}
rewrite /pad/p/(.*) /p/$1 break;
rewrite ^/pad/p$ /pad/p/ permanent;
proxy_pass http://etherpad:9001/p;
proxy_pass_header Server;
proxy_redirect /p /pad/p;
proxy_set_header Host $host;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr; # http://wiki.nginx.org/HttpProxyModule
proxy_set_header X-Forwarded-For $remote_addr; # EP logs to show the actual remote IP
proxy_set_header X-Forwarded-Proto $real_scheme; # for EP to set secure cookie flag when https is used
proxy_http_version 1.1;
auth_request /bigbluebutton/connection/checkAuthorization;
auth_request_set $auth_status $upstream_status;
}
location /pad/auth_session {
rewrite /pad/auth_session(.*) /auth_session$1 break;
proxy_pass http://etherpad:9001/;
proxy_pass_header Server;
proxy_set_header Host $host;
proxy_buffering off;
auth_request /bigbluebutton/connection/checkAuthorization;
auth_request_set $auth_status $upstream_status;
}
location /pad {
rewrite /pad/(.*) /$1 break;
rewrite ^/pad$ /pad/ permanent;
proxy_pass http://etherpad:9001/;
proxy_pass_header Server;
proxy_redirect / /pad/;
proxy_set_header Host $host;
proxy_buffering off;
}
location /pad/socket.io/socket.io.js {
rewrite /pad/socket.io/socket.io.js /socket.io/socket.io.js break;
proxy_pass http://etherpad:9001/;
proxy_set_header Host $host;
proxy_buffering off;
}
location /pad/socket.io {
rewrite /pad/socket.io/(.*) /socket.io/$1 break;
proxy_pass http://etherpad:9001/;
proxy_redirect / /pad/;
proxy_set_header Host $host;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr; # http://wiki.nginx.org/HttpProxyModule
proxy_set_header X-Forwarded-For $remote_addr; # EP logs to show the actual remote IP
proxy_set_header X-Forwarded-Proto $real_scheme; # for EP to set secure cookie flag when https is used
proxy_set_header Host $host; # pass the host header
proxy_http_version 1.1; # recommended with keepalive connections
# WebSocket proxying - from http://nginx.org/en/docs/http/websocket.html
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
auth_request /bigbluebutton/connection/checkAuthorization;
auth_request_set $auth_status $upstream_status;
}
location /static {
rewrite /static/(.*) /static/$1 break;
proxy_pass http://etherpad:9001/;
proxy_set_header Host $host;
proxy_buffering off;
}
+21
View File
@@ -0,0 +1,21 @@
# This file is part of BigBlueButton.
#
# Copyright © BigBlueButton Inc. and by respective authors.
#
# BigBlueButton is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3.0 of the License, or (at your
# option) any later version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with BigBlueButton. If not, see <https://www.gnu.org/licenses>.
location /playback/video/ {
alias /var/bigbluebutton/published/video/;
index index.html index.htm;
}
+22
View File
@@ -0,0 +1,22 @@
#
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
#
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
#
location /podcast {
root /var/bigbluebutton/published;
index index.html index.htm;
}
+46
View File
@@ -0,0 +1,46 @@
#
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
#
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
#
# Have nginx serve the presentation slides instead of tomcat as large files
# causes tomcat to OOM. (ralam sept 20, 2018)
location ~^\/bigbluebutton\/presentation\/(?<meeting_id_1>[A-Za-z0-9\-]+)\/(?<meeting_id_2>[A-Za-z0-9\-]+)\/(?<pres_id>[A-Za-z0-9\-]+)\/svg\/(?<page_num>\d+)$ {
default_type image/svg+xml;
alias /var/bigbluebutton/$meeting_id_2/$meeting_id_2/$pres_id/svgs/slide$page_num.svg;
add_header 'Access-Control-Allow-Origin' '*' always;
}
location ~^\/bigbluebutton\/presentation\/(?<meeting_id_1>[A-Za-z0-9\-]+)\/(?<meeting_id_2>[A-Za-z0-9\-]+)\/(?<pres_id>[A-Za-z0-9\-]+)\/pdf\/(?<job_id>[A-Za-z0-9]+)\/annotated_slides.pdf$ {
default_type application/pdf;
alias /var/bigbluebutton/$meeting_id_2/$meeting_id_2/$pres_id/pdfs/$job_id/annotated_slides.pdf;
add_header 'Access-Control-Allow-Origin' '*' always;
}
location ~^\/bigbluebutton\/presentation\/(?<meeting_id_1>[A-Za-z0-9\-]+)\/(?<meeting_id_2>[A-Za-z0-9\-]+)\/(?<pres_id>[A-Za-z0-9\-]+)\/thumbnail\/(?<page_num>\d+)$ {
default_type image/png;
alias /var/bigbluebutton/$meeting_id_2/$meeting_id_2/$pres_id/thumbnails/thumb-$page_num.png;
add_header 'Access-Control-Allow-Origin' '*' always;
}
location ~^\/bigbluebutton\/presentation\/(?<meeting_id_1>[A-Za-z0-9\-]+)\/(?<meeting_id_2>[A-Za-z0-9\-]+)\/(?<pres_id>[A-Za-z0-9\-]+)\/textfiles\/(?<page_num>\d+)$ {
default_type text/plain;
alias /var/bigbluebutton/$meeting_id_2/$meeting_id_2/$pres_id/textfiles/slide-$page_num.txt;
add_header 'Access-Control-Allow-Origin' '*' always;
}
+28
View File
@@ -0,0 +1,28 @@
#
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
#
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
#
location /playback/presentation/2.0/playback.html {
return 301 /playback/presentation/2.3/$arg_meetingId?$query_string;
}
location /playback/presentation/2.3 {
try_files $uri /playback/presentation/2.3/index.html;
}
location /presentation {
root /var/bigbluebutton/published;
index index.html index.htm;
}
+22
View File
@@ -0,0 +1,22 @@
#
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
#
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
#
location /recording/screenshare {
alias /var/bigbluebutton/published/screenshare;
index index.html index.htm;
}
+28
View File
@@ -0,0 +1,28 @@
#
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
#
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
#
location /playback/slides {
root /var/bigbluebutton;
index index.html index.htm;
}
location /slides {
root /var/bigbluebutton/published;
index index.html index.htm;
}

Some files were not shown because too many files have changed in this diff Show More