Compare commits

..

255 commits
master ... main

Author SHA1 Message Date
ab6db28ada add Adrien@Lille to ifconfig 2023-03-15 18:19:58 +01:00
46e29828b1 add missing iptables rules 2023-02-12 16:40:14 +01:00
a6742bcf53
fix io 2023-02-02 07:45:38 +01:00
653e170fb2
remove outdated info 2022-12-24 23:00:33 +01:00
b449e83870
Notice that repo is obsolete 2022-12-22 17:59:51 +01:00
b575b2b486
Remove all files from op_guide, now migrated to guide.deuxfleurs.fr 2022-12-22 17:46:19 +01:00
015c372532
Add allowed ipv6 prefix 2022-09-09 17:25:34 +02:00
ec597541c8
Fix create db doc 2022-08-25 02:02:40 +02:00
ed82071223
Upgrade Stolon doc 2022-08-24 17:09:40 +02:00
18610f9a9a
Add Quentin@Lyon (orion) to iptables v6 rules 2022-08-24 16:29:02 +02:00
11a2ffa89d
Upgrade Stolon to Posgtgres 14 2022-08-24 15:58:21 +02:00
ae91f66fac
Disable guichet on old cluster 2022-08-24 15:51:29 +02:00
145f3a8499
Matrix is so weird... 2022-08-19 18:27:43 +02:00
638f775742
Hot fix 2022-08-19 18:01:19 +02:00
38a0feffe0
Add zorun 2022-08-18 22:31:34 +02:00
1e003461bd
Add the net target to io 2022-08-17 12:26:23 +02:00
2e872eb87f
Update max@bruxelles IP addresses 2022-08-17 11:50:48 +02:00
ef265b87de
Update doc 2022-07-28 17:34:49 +02:00
64172fc999
update runners' doc 2022-07-25 15:20:21 +02:00
ceae80d87c
Use Tricot certificates instead of self-signed ones 2022-07-06 13:16:50 +02:00
0e81c9f23b
Upgrade Matrix 2022-07-01 14:17:33 +02:00
39e3ecce64
Upgrade Synapse + Element Web 2022-07-01 13:59:50 +02:00
51482e16e4
Drop allow unsafe locale 2022-06-06 10:52:18 +02:00
6c31560c7b
Forced to allow unsafe local 2022-06-06 09:08:51 +02:00
72b41408ef
Upgrade synapse+element web in Nomad 2022-06-06 09:03:51 +02:00
7dd2aeb63b
Upgrade matrix+riot 2022-06-06 08:42:57 +02:00
a17640d606
update bottin config 2022-06-01 12:41:38 +02:00
241dd1e175
Drone update 2022-05-31 11:53:42 +02:00
d712c08dbc
Update the doc 2022-05-10 15:42:41 +02:00
415075b010
Garage v0.7.1 2022-05-09 16:25:15 +02:00
2021b7d08c
New ipv6 prefix for lx@orsay 2022-05-09 00:10:21 +02:00
99a4f51166
Simplify the build 2022-05-06 10:49:28 +02:00
653e45f192
Packaging try on Cryptpad 2022-05-06 10:32:41 +02:00
f0ead6efed
WIP Cryptpad packaging 2022-05-05 17:45:15 +02:00
f27636dd14
Add headers in Garage 2022-05-05 08:50:33 +02:00
d7164c7d90
remove obsolete admin_port 2022-05-04 17:33:43 +02:00
5b861cd652
Remove unused Traefik config 2022-05-04 17:28:39 +02:00
79d68c4aa3
Update tricot 2022-05-04 17:27:54 +02:00
4cb1dbe663
Add a security HTTPS header to Garage web 2022-05-04 09:20:07 +02:00
d21c010da1
Set plume log verbosity to info 2022-04-24 13:45:32 +02:00
60ad398c44
Upgrade Plume + debug info 2022-04-23 22:04:14 +02:00
2695a79e8a
Add garage backup info 2022-04-23 13:27:52 +02:00
1e9a538be9
add concrete examples 2022-04-19 14:41:03 +02:00
c69923f104
Add missing doc 2022-04-19 14:38:29 +02:00
d62f87fa71
Update guide 2022-04-19 14:32:44 +02:00
501fbb5553
Add doc for secrets 2022-04-19 13:46:12 +02:00
b2b26879cb replace os.system with subprocess.run 2022-04-15 14:57:54 +02:00
83745f737a Deployment on Nomad 2022-04-15 14:24:41 +02:00
8cf1b0c3e4 Build image via Nix 2022-04-15 12:36:49 +02:00
9701b863fd Create a backup script 2022-04-14 17:50:17 +02:00
1183583fdf
make adrien admin 2022-04-06 12:17:15 +02:00
1e5e4af35c Ajout de Publii dans le postmortem 2022-03-30 10:04:54 +02:00
ce36e7e09b Ajout coupure élec + SSD lent 2022-03-28 11:59:37 +02:00
68607d567c Ajout de matrix 2022-03-28 11:55:25 +02:00
b5137f6665 Ajout de GlusterFS 2022-03-28 11:51:49 +02:00
3f73721ad5
documentation de petits incidents techniques plus ou moins évitables 2022-03-28 11:43:47 +02:00
0e6aa95754
Update Garage to 0.7.0-rc1 2022-03-28 10:59:24 +02:00
306974a163 Change Plume restart policy 2022-03-18 11:37:14 +01:00
9883d85c2a Small postfix modifications 2022-03-14 10:02:22 +01:00
a1c6c33d73 Maintenance du 2022-03-09 2022-03-09 16:54:19 +01:00
1322dae8da Upgrade Matrix 2022-03-09 11:52:36 +01:00
e7329a0202 Add zstd 2022-03-09 11:32:43 +01:00
b359601d2d Documentation for Drone 2022-03-07 11:02:37 +01:00
8ce62ddca1
Close drone registrations 2022-02-21 14:54:42 +01:00
0b16fd1c08
Update Garage and change a few config parameters 2022-02-10 14:34:18 +01:00
41e1a31bb9
fix typo 2022-02-09 16:06:23 +01:00
1410f2f8d8
Add LX@Orsay to trusted net 2022-02-09 15:53:45 +01:00
f74651a0c3
Upgrade garage to 0.6 RC1 2022-02-01 15:33:33 +01:00
5ecab67379 Use a list to organize ref 2022-01-28 19:14:39 +01:00
f3dbf47547 Ajout de pg_verifybackup 2022-01-28 19:11:58 +01:00
37bea48d45 Finalize manual backup 2022-01-28 18:44:07 +01:00
89937f2107 Update guide 2022-01-28 17:00:50 +01:00
2775eeb0fe WIP manual backup 2022-01-27 18:26:02 +01:00
715c3d3a9f Use ampersand in backup instead of semi colon 2022-01-27 16:58:22 +01:00
84b26f347d Add consul backup with restic 2022-01-27 16:56:02 +01:00
3baa511fce Plume backup + WIP consul 2022-01-27 16:32:57 +01:00
00d7106a18 Redeploy plume 2022-01-27 13:31:25 +01:00
831ddd3055 Some fixes 2022-01-27 09:57:49 +01:00
a13a02c45c Add a backup script for emails 2022-01-26 21:48:48 +01:00
453b633268 Update guide 2022-01-26 19:31:44 +01:00
a68a1e1da7 Migrate jitsi + WIP backup doc 2022-01-26 19:09:26 +01:00
3563fb5994 Change how email is stored 2022-01-26 17:20:20 +01:00
7cede37e6d Mises à jour du cluster 2022-01-25 12:12:58 +01:00
f229d58467
Update tricot and increase RAM allocation 2022-01-11 15:07:33 +01:00
87986ff3cf
Move out .hcl files specific to Neptune cluster 2021-12-25 19:40:30 +01:00
85eb4d5b82
Revert garage to 0.5.0 temporarily to fix winscp bug 2021-12-15 11:18:04 +01:00
59ce079a52
Update tricot 2021-12-14 11:43:18 +01:00
582882286e
latest s3 provider version is required 2021-12-14 11:19:09 +01:00
fa75e0012c
Also upgrade async upload 2021-12-14 11:12:40 +01:00
e9ba2243e7
Update Matrix 2021-12-14 11:05:41 +01:00
3df786a5f5
Don't use ipv6 in garage staging cluster 2021-12-13 11:44:27 +01:00
50a09980c5 Update jitsi's nomad service 2021-12-12 13:21:49 +01:00
f73d8dab93 log4shell mitigation 2021-12-12 13:03:45 +01:00
c00f0fefe7 Update bagage 2021-12-12 12:49:48 +01:00
2fc9276be2
fixed tricot with compression now 2021-12-10 00:26:51 +01:00
c6819c8d4a
Revert for now 2021-12-09 16:52:16 +01:00
d64fe28143
upgrade tricot to enable compression 2021-12-09 16:14:17 +01:00
783894b60d
Tricot 19 2021-12-09 12:24:18 +01:00
854da5b984
Different tricot config for neptune dc 2021-12-09 11:04:56 +01:00
8d178815d6
Only one frontend 2021-12-09 10:51:58 +01:00
2d2e7bb5c6
fix tricot 2021-12-08 23:48:08 +01:00
ea55c9b12b
synapse on dummy infrastructure for tricot test 2021-12-08 18:05:17 +01:00
3693d9f36b
Traefik on all servers 2021-12-08 13:32:47 +01:00
a4982c6cd6
last tricot version 2021-12-08 13:28:22 +01:00
7f08d5f324
Add tricot tags to everything 2021-12-08 12:42:48 +01:00
2c2ee6c903
Rename tricot+traefik to frontend 2021-12-08 12:21:50 +01:00
3297135a58
Add tricot to replace traefik 2021-12-08 12:19:08 +01:00
8846421cc4
Deploy core on neptune as well 2021-12-08 11:41:07 +01:00
fff6f1db20
garage with new s3_router 2021-12-06 22:10:26 +01:00
ef2fa848f1
single region staging cluster 2021-12-04 21:56:15 +01:00
4cc6a0182c
Bump synapse to 1.47.1 to fix CVE 2021-11-23 13:48:12 +01:00
7113a3ae56 Add secrets 2021-11-20 14:58:09 +01:00
5df7058c84 Working SFTP deployment of Garage 2021-11-20 14:56:56 +01:00
9ce6c7ad6e
Add config files for garage staging cluster 2021-11-18 17:14:30 +01:00
0268f63f66
Upgrade garage to 0.5 2021-11-17 16:42:13 +01:00
948a916c2f
Add missing options for discord bridge 2021-11-16 12:57:15 +01:00
289359cedc
Prepare to add Discord bridge 2021-11-16 12:05:28 +01:00
627c89b545
make config file clearer 2021-11-15 23:05:01 +01:00
e20b903bc0
Add matterbridge to bridge RFID channel 2021-11-15 17:53:59 +01:00
489cc492d5
Deploy garage v0.4.0 2021-11-10 14:19:23 +01:00
779aea8f11 Merge pull request 'ajout machine Spoutnik, lien vers cluster de test dans readme' (#55) from machine/spoutnik into main
Reviewed-on: Deuxfleurs/infrastructure#55
2021-11-06 19:41:59 +01:00
76d160f9af ajout machine Spoutnik, lien vers cluster de test dans readme 2021-11-06 19:39:06 +01:00
f362d57965
Update garage to v0.4-rc2 2021-11-05 11:41:16 +01:00
2734f79c0d
Updated Garage version that eats less RAM under load 2021-11-04 10:55:37 +01:00
b8420756b4
Updated garage definition 2021-11-02 13:48:00 +01:00
6c90a00f04 Merge pull request 'Migration to garage 0.4' (#53) from garage04 into main
Reviewed-on: Deuxfleurs/infrastructure#53
2021-10-26 16:17:59 +02:00
7fc001a92f
Migration to garage 0.4 2021-10-26 16:14:29 +02:00
c51b654dd6
Add a docker compose for runners 2021-10-19 12:55:51 +02:00
6093ec74f2
Drone 2.0.4 -> 2.4.0 2021-10-12 10:21:18 +02:00
7ee2f8aa2c
Update garage (ListObjects fix) 2021-10-11 13:48:00 +02:00
83bd5f2cdd Increase RAM for Plume 2021-09-30 22:23:17 +02:00
6d4be5fb83 Migrate to riot web 1.9.0 2021-09-28 22:17:24 +02:00
e8474d52a2
Alps build: add missing plugin directory for html and js files 2021-09-28 17:53:49 +02:00
1f15cfa420 Update io parameters 2021-09-28 17:26:27 +02:00
5b1f775513 Change IP address 2021-09-28 16:51:58 +02:00
39f1e983bf Merge pull request 'os/users: Add kokakiwi (jill) user and keys' (#52) from KokaKiwi/infrastructure:add-jill-keys into main
Reviewed-on: Deuxfleurs/infrastructure#52
2021-09-28 16:50:37 +02:00
bebd6eaab6
os/users: Add kokakiwi (jill) user and keys
Signed-off-by: Jill <kokakiwi@deuxfleurs.fr>
2021-09-28 15:36:59 +02:00
88a7c04cee
media-async-upload must be in the matrix group
note: the group stanza is not mandatory
2021-09-20 09:52:13 +02:00
136d176176
Synapse does not use GlusterFS anymore 2021-09-17 18:49:45 +02:00
2a0610658d Upgrade synapse+riot web 2021-09-17 18:24:00 +02:00
6db8495bbf
Remove fb2nx that never worked 2021-09-17 17:42:16 +02:00
4ea2494bd5
Update bottin 2021-09-17 17:41:57 +02:00
acd46fde80
Remove connection limit dovecot 2021-09-14 17:46:06 +02:00
6716687fd7
Finally fix dovecot 2021-09-14 14:02:50 +02:00
a2a25e2ea4
Use cn instead of mail to store emails 2021-09-14 11:33:29 +02:00
e74bda617c
Merge branch 'main' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2021-09-10 18:33:07 +02:00
2dfd006dc5
Upgrade bagage and fix mem leak 2021-09-10 18:32:50 +02:00
9c4f78619d
Update guichet config: remove useless default groups nextcloud and seafile 2021-09-10 15:32:17 +02:00
8fe0a78b0c
Upgrade Bagage 2021-09-03 11:02:22 +02:00
e66b1c2c54
Upgrade Plume 2021-09-02 15:35:59 +02:00
d40c41004d Add bagage deployment 2021-08-20 17:39:07 +02:00
09269e8497 Merge pull request 'bump diplonat version 2->3' (#39) from bump-diplonat into main
Reviewed-on: Deuxfleurs/infrastructure#39
2021-08-19 11:43:28 +02:00
e26f57c8eb bump diplonat version 2->3 2021-08-19 11:33:36 +02:00
d25f4d18aa
update guichet 2021-08-18 14:17:31 +02:00
b8470be123
Update guichet 2021-08-16 16:45:04 +02:00
9d5b490fd9
add restart with mode "delay" stance to diplonat 2021-07-26 22:58:51 +02:00
9304997d84
Upgrade guichet & postgres 2021-07-22 11:03:36 +02:00
2f37aaaf76
update drone server to 2.0.4 2021-07-08 11:12:05 +02:00
69f063e406
Update garage to handle ed25519 keys for TLS 2021-07-08 11:07:45 +02:00
8302595f65
Merge branch 'main' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2021-07-02 17:07:19 +02:00
4fdc4a5144
Add pv for psql + upgrade postgres to 13.3 2021-07-02 17:06:58 +02:00
2b39a896a7 Postgres can not be run as root 2021-07-02 14:45:59 +02:00
e97496e09d fix entrypoint 2021-07-02 14:16:33 +02:00
2670c8f8f1 libc is needed fos stolon 2021-07-02 14:08:22 +02:00
0a6ffcacd2 Merge branch 'main' of git.deuxfleurs.fr:Deuxfleurs/infrastructure into main 2021-07-02 13:11:29 +02:00
2d61f1449d Upgrade postgresql 2021-07-02 13:10:49 +02:00
80c2f1f701
Merge branch 'main' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2021-07-01 23:49:08 +02:00
e640f82eb8
Add 500Mo x3 more RAM to postgres and 2Go less RAM to Matrix 2021-07-01 23:48:11 +02:00
455e4db784
update guichet 2021-07-01 16:30:21 +02:00
576ac2772e
Update config to add more time to pull images 2021-07-01 15:53:41 +02:00
1277d94bec
Remove easybridge + increase nomad docker timeout when pulling images 2021-07-01 15:36:54 +02:00
b9f0f012bd
Update synapse configuration 2021-07-01 14:25:04 +02:00
4b68522721
Add locales 2021-07-01 14:23:33 +02:00
3c8cd4ca1c
Deactivate guests + expose _synapse api 2021-06-30 16:24:03 +02:00
784efbcc9b
Add a restart policy 2021-06-30 12:57:13 +02:00
2d30e1a9c7
Log to journald 2021-06-29 13:57:01 +02:00
42c020e00b
Fix typo 2021-06-04 21:39:44 +02:00
7e82b0d94d Add git 2021-06-04 21:32:45 +02:00
efcdef7856
Matrix 1.35.1 + S3 backend 2021-06-04 19:48:50 +02:00
62fa15390b
Update easybridge 2021-06-01 23:44:57 +02:00
a26d41259a
Update garage to v0.3.0 2021-05-28 15:55:52 +02:00
73d30b9aa5
Disable syslog as it is not present in the container 2021-05-19 09:44:36 +02:00
8c213bc7ba
Update garage 2021-05-19 09:44:17 +02:00
1edc5f37a2
Upgrade Matrix configuration 2021-05-19 09:43:45 +02:00
4f506422e3 Upgrade matrix 2021-05-18 15:26:41 +02:00
3bb2cf9e93 Allow only cipher suites recommended by Mozilla
Check https://ssl-config.mozilla.org/#server=traefik&version=1.7&config=intermediate&guideline=5.6
2021-05-07 20:01:31 +02:00
1f15d29eab
Update garage to v0.2.1.6 2021-05-04 13:28:04 +02:00
6754cfef81 Merge branch 'main' of git.deuxfleurs.fr:Deuxfleurs/infrastructure into main 2021-05-03 19:10:16 +02:00
3df53eaa94 Upgrade plume build scripts 2021-05-03 19:09:50 +02:00
51b5295ba8 Allow Garage to use 800MB of RAM instead of 500MB 2021-05-03 17:27:06 +02:00
925639b678
update garage 2021-04-28 01:16:35 +02:00
68575d2654
Migrate from Plume from v0.6.0 to v0.7.0RC 2021-04-19 10:50:38 +02:00
338a8ec7da
Try to migrate to pg_basebackup 2021-04-17 12:21:13 +02:00
3135c38505
Upgrade stolon 2021-04-15 13:05:21 +02:00
87303033d1
Debug stolon backup 2021-04-15 12:38:31 +02:00
9dfff86cd2
Target a replicated server and not the main one 2021-04-14 19:10:46 +02:00
b851ca0c95
Update matrix HCL + document stolon conf change 2021-04-14 18:15:45 +02:00
fae36c7ef6 Upgrade synapse+riot images 2021-04-09 14:11:26 +02:00
4ecda8cc8d
Updated version of Drone 2021-04-07 14:06:02 +02:00
2ef1a9df5d
Update garage 2021-04-05 20:48:33 +02:00
1df83c6064
Add iptables rules allowing new IPv6 2021-04-05 18:28:45 +02:00
0b4c61dfe1 Try to optimize Consul 2021-04-04 20:04:25 +02:00
e979434970 Fix Jitsi's IP address 2021-04-04 19:15:29 +02:00
474c4575f4 Rename postgres 2021-04-01 19:04:50 +02:00
5126868e30 update garage to v0.2.1 2021-03-19 14:00:48 +01:00
4ad6376aa8 Document how to repair Traefik/ACME 2021-03-18 10:17:05 +01:00
e197429531 Update bottin; remove drone runner 2021-03-16 14:59:10 +01:00
mricher
d67a6c363a
Set prometheus node_exporter version to v1.1.2 2021-03-09 00:15:55 +01:00
573a86b87c Change resource allocation 2021-03-08 23:01:11 +01:00
c586633613 Add node-exporter for metrics collection 2021-03-08 22:55:55 +01:00
e806e24fea Add SSL certificates in ALPS image 2021-03-08 17:49:22 +01:00
a84f4c8f87 Use patched Alps from git.deuxfleurs.fr/Deuxfleurs/alps 2021-03-08 17:32:05 +01:00
b42e42faaa Improve resource allocation 2021-03-08 16:34:41 +01:00
d6bdfbed5f Expose prometheus metrics on Consul 2021-03-07 21:36:27 +01:00
255e3fd2d7 Debug stolon proxy 2021-03-07 18:29:56 +01:00
eb3f64df41 Merge branch 'master' of git.deuxfleurs.fr:Deuxfleurs/infrastructure 2021-03-07 17:07:52 +01:00
35ddbd9f20 Upgrade Stolon 2021-03-07 17:07:35 +01:00
4f296808e8 Refactor stolon Dockerfile 2021-03-07 12:54:03 +01:00
4d7470b2fd Draft stolon update 2021-03-07 12:18:08 +01:00
b608567648 Add a new parameter to stolon 2021-03-07 11:43:46 +01:00
a69efd9b31 Add gzip compression 2021-03-06 21:43:55 +01:00
96f2978a7f Change target image 2021-03-06 20:09:16 +01:00
224c0a23a3 Increment image 2021-03-06 20:08:17 +01:00
c0d86cb0a1 Mount backup directory + export PGPASSWORD 2021-03-06 20:06:57 +01:00
d1a4ed0f79 Matrix backup draft 2021-03-06 19:52:13 +01:00
27963ca089 Upgraded matrix/element to 1.28.0/1.7.22 2021-03-05 17:44:05 +01:00
1c5b1f2e5b Upgrade matrix image 2021-03-05 17:40:40 +01:00
fada3f6ed1 Don't always restart stolon keeper if it is failed (let stolon do its job) 2021-02-24 14:54:18 +01:00
987cefeba0 bump garage 2021-02-24 14:54:10 +01:00
71971143c4 Fix drone DB (why did it work before???) 2021-02-24 14:53:58 +01:00
89133ddbea Change l'adresse d'expéditeur pour les invites 2021-02-18 14:02:18 +01:00
59623243c8 Deactivate test endpoint 2021-02-11 11:57:23 +01:00
2958fbae1b Port nginx's configuration from integration to deployment 2021-02-11 11:56:30 +01:00
c2d3c543b9 Jitsi add missing mimetypes 2021-02-11 11:54:06 +01:00
9c2232cebc Add Drone CI 2021-02-08 14:52:13 +01:00
9c060b3c28 Add tools 2021-02-01 19:56:16 +01:00
b6b812c011 Upgrade jitsi nginx conf to make ADRN happy! 2021-02-01 18:19:43 +01:00
5fb05f0b7e Add CORS for our load testing frontend 2021-02-01 12:42:29 +01:00
5babe6fad1 Fix port binding 2021-02-01 11:22:16 +01:00
34c5544ef5 Fix prosody listening 2021-02-01 11:06:45 +01:00
847540f7b7 Add trimSpace to secrets to prevent a parsing bug 2021-02-01 10:29:13 +01:00
9337129336 Fix typos in the service file 2021-02-01 10:26:26 +01:00
088c9df20c Prepare Nomad deployment 2021-02-01 09:50:38 +01:00
0a87d26e47 Polish configuration 2021-02-01 08:40:59 +01:00
cb69a1123c Stabilize build scripts 2021-02-01 07:48:50 +01:00
c2960f75b7 Add curl to the dockerfile 2021-01-31 18:17:37 +01:00
56cf9c1e55 Videobridge doc + debug 2021-01-31 18:03:55 +01:00
a3f62d1f30 Overide logging + some doc to debug java processes 2021-01-31 15:47:01 +01:00
09e1e641a7 Working on meet frontend 2021-01-30 12:06:14 +01:00
9ea066d6df Only old configuration can be used for ice4 harvester 2021-01-29 19:22:16 +01:00
59ca97e2a9 Migrate JVB to the new packaging 2021-01-29 18:59:19 +01:00
83d8668a59 Jicofo might work as intended! 2021-01-29 17:47:09 +01:00
952d7c0510 Improve jitsi config 2021-01-29 17:30:43 +01:00
7bdea77811 WIP debugging jitsi 2021-01-29 17:17:28 +01:00
cee95ad061 Merge pull request 'Upgrade Synapse & Element-web, réécriture de l'OP guide, et ajout du secret turn.zinz.dev' (#33) from adrien/infrastructure:master into master
Reviewed-on: Deuxfleurs/infrastructure#33
2021-01-29 15:53:37 +01:00
190 changed files with 4717 additions and 2780 deletions

3
.gitmodules vendored
View file

@ -1,6 +1,3 @@
[submodule "docker/static/goStatic"] [submodule "docker/static/goStatic"]
path = app/build/static/goStatic path = app/build/static/goStatic
url = https://github.com/PierreZ/goStatic url = https://github.com/PierreZ/goStatic
[submodule "docker/blog/quentin.dufour.io"]
path = docker/blog-quentin/quentin.dufour.io
url = git@gitlab.com:superboum/quentin.dufour.io.git

View file

@ -1,31 +1,8 @@
deuxfleurs.fr deuxfleurs.fr
============= =============
*Many things are still missing here, including a proper documentation. Please stay nice, it is a volunter project. Feel free to open pull/merge requests to improve it. Thanks.* **OBSOLETION NOTICE:** We are progressively migrating our stack to NixOS, to replace Ansible. Most of the files present in this repository are outdated or obsolete,
the current code for our infrastructure is at: <https://git.deuxfleurs.fr/Deuxfleurs/nixcfg>.
## Our abstraction stack
We try to build a generic abstraction stack between our different resources (CPU, RAM, disk, etc.) and our services (Chat, Storage, etc.), we develop our own tools when needed:
* **[garage](https://git.deuxfleurs.fr/Deuxfleurs/garage/):** S3-compatible lightweight object store for self-hosted geo-distributed deployments (we also have a legacy glusterfs cluster)
* **[diplonat](https://git.deuxfleurs.fr/Deuxfleurs/diplonat):** network automation (firewalling, upnp igd)
* **[bottin](https://git.deuxfleurs.fr/Deuxfleurs/bottin):** authentication and authorization (LDAP protocol, consul backend)
* **[guichet](https://git.deuxfleurs.fr/Deuxfleurs/guichet):** a dashboard for our users and administrators
* **ansible:** physical node configuration
* **nomad:** schedule containers and handle their lifecycle
* **consul:** distributed key value store + lock + service discovery
* **stolon + postgresql:** distributed relational database
* **docker:** package, distribute and isolate applications
Some services we provide:
* **Websites:** garage (static) + fediverse blog (plume)
* **Chat:** Synapse + Element Web (Matrix protocol)
* **Email:** Postfix SMTP + Dovecot IMAP + opendkim DKIM + Sogo webmail (legacy) | Alps webmail (experimental)
* **Storage:** Seafile (legacy) | Nextcloud (experimental)
* **Visio:** Jitsi
As a generic abstraction is provided, deploying new services should be easy.
## I am lost, how this repo works? ## I am lost, how this repo works?
@ -42,69 +19,3 @@ To ease the development, we make the choice of a fully integrated environment
3. `op_guide`: Guides to explain you operations you can do cluster wide (like configuring postgres) 3. `op_guide`: Guides to explain you operations you can do cluster wide (like configuring postgres)
## Start hacking
### Deploying/Updating new services is done from your machine
*The following instructions are provided for ops that already have access to the servers (meaning: their SSH public key is known by the cluster).*
Deploy Nomad on your machine:
```bash
export NOMAD_VER=1.0.1
wget https://releases.hashicorp.com/nomad/${NOMAD_VER}/nomad_${NOMAD_VER}_linux_amd64.zip
unzip nomad_${NOMAD_VER}_linux_amd64.zip
sudo mv nomad /usr/local/bin
rm nomad_${NOMAD_VER}_linux_amd64.zip
```
Deploy Consul on your machine:
```bash
export CONSUL_VER=1.9.0
wget https://releases.hashicorp.com/consul/${CONSUL_VER}/consul_${CONSUL_VER}_linux_amd64.zip
unzip consul_${CONSUL_VER}_linux_amd64.zip
sudo mv consul /usr/local/bin
rm consul_${CONSUL_VER}_linux_amd64.zip
```
Create an alias (and put it in your `.bashrc`) to bind APIs on your machine:
```
alias bind_df="ssh \
-p110 \
-N \
-L 1389:bottin2.service.2.cluster.deuxfleurs.fr:389 \
-L 4646:127.0.0.1:4646 \
-L 5432:psql-proxy.service.2.cluster.deuxfleurs.fr:5432 \
-L 8082:traefik-admin.service.2.cluster.deuxfleurs.fr:8082 \
-L 8500:127.0.0.1:8500 \
<a server from the cluster>"
```
and run:
bind_df
Adrien uses `.ssh/config` configuration instead. I works basically the same. Here it goes:
```
# in ~/.ssh/config
Host deuxfleurs
User adrien
Hostname deuxfleurs.fr
# If you don't use the default ~/.ssh/id_rsa to connect to Deuxfleurs
IdentityFile <some_key_path>
PubKeyAuthentication yes
ForwardAgent No
LocalForward 1389 bottin2.service.2.cluster.deuxfleurs.fr:389
LocalForward 4646 127.0.0.1:4646
LocalForward 5432 psql-proxy.service.2.cluster.deuxfleurs.fr:5432
LocalForward 8082 traefik-admin.service.2.cluster.deuxfleurs.fr:8082
LocalForward 8500 127.0.0.1:8500
```
Now, to connect, do the following:
ssh deuxfleurs -N

View file

@ -0,0 +1 @@
result

View file

@ -0,0 +1,8 @@
## Build
```bash
docker load < $(nix-build docker.nix)
docker push superboum/backup-psql:???
```

View file

@ -0,0 +1,106 @@
#!/usr/bin/env python3
import shutil,sys,os,datetime,minio,subprocess
working_directory = "."
if 'CACHE_DIR' in os.environ: working_directory = os.environ['CACHE_DIR']
required_space_in_bytes = 20 * 1024 * 1024 * 1024
bucket = os.environ['AWS_BUCKET']
key = os.environ['AWS_ACCESS_KEY_ID']
secret = os.environ['AWS_SECRET_ACCESS_KEY']
endpoint = os.environ['AWS_ENDPOINT']
pubkey = os.environ['CRYPT_PUBLIC_KEY']
psql_host = os.environ['PSQL_HOST']
psql_user = os.environ['PSQL_USER']
s3_prefix = str(datetime.datetime.now())
files = [ "backup_manifest", "base.tar.gz", "pg_wal.tar.gz" ]
clear_paths = [ os.path.join(working_directory, f) for f in files ]
crypt_paths = [ os.path.join(working_directory, f) + ".age" for f in files ]
s3_keys = [ s3_prefix + "/" + f for f in files ]
def abort(msg):
for p in clear_paths + crypt_paths:
if os.path.exists(p):
print(f"Remove {p}")
os.remove(p)
if msg: sys.exit(msg)
else: print("success")
# Check we have enough space on disk
if shutil.disk_usage(working_directory).free < required_space_in_bytes:
abort(f"Not enough space on disk at path {working_directory} to perform a backup, aborting")
# Check postgres password is set
if 'PGPASSWORD' not in os.environ:
abort(f"You must pass postgres' password through the environment variable PGPASSWORD")
# Check our working directory is empty
if len(os.listdir(working_directory)) != 0:
abort(f"Working directory {working_directory} is not empty, aborting")
# Check Minio
client = minio.Minio(endpoint, key, secret)
if not client.bucket_exists(bucket):
abort(f"Bucket {bucket} does not exist or its access is forbidden, aborting")
# Perform the backup locally
try:
ret = subprocess.run(["pg_basebackup",
f"--host={psql_host}",
f"--username={psql_user}",
f"--pgdata={working_directory}",
f"--format=tar",
"--wal-method=stream",
"--gzip",
"--compress=6",
"--progress",
"--max-rate=5M",
])
if ret.returncode != 0:
abort(f"pg_basebackup exited, expected return code 0, got {ret.returncode}. aborting")
except Exception as e:
abort(f"pg_basebackup raised exception {e}. aborting")
# Check that the expected files are here
for p in clear_paths:
print(f"Checking that {p} exists locally")
if not os.path.exists(p):
abort(f"File {p} expected but not found, aborting")
# Cipher them
for c, e in zip(clear_paths, crypt_paths):
print(f"Ciphering {c} to {e}")
try:
ret = subprocess.run(["age", "-r", pubkey, "-o", e, c])
if ret.returncode != 0:
abort(f"age exit code is {ret}, 0 expected. aborting")
except Exception as e:
abort(f"aged raised an exception. {e}. aborting")
# Upload the backup to S3
for p, k in zip(crypt_paths, s3_keys):
try:
print(f"Uploading {p} to {k}")
result = client.fput_object(bucket, k, p)
print(
"created {0} object; etag: {1}, version-id: {2}".format(
result.object_name, result.etag, result.version_id,
),
)
except Exception as e:
abort(f"Exception {e} occured while upload {p}. aborting")
# Check that the files have been uploaded
for k in s3_keys:
try:
print(f"Checking that {k} exists remotely")
result = client.stat_object(bucket, k)
print(
"last-modified: {0}, size: {1}".format(
result.last_modified, result.size,
),
)
except Exception as e:
abort(f"{k} not found on S3. {e}. aborting")
abort(None)

View file

@ -0,0 +1,8 @@
{
pkgsSrc = fetchTarball {
# Latest commit on https://github.com/NixOS/nixpkgs/tree/nixos-21.11
# As of 2022-04-15
url ="https://github.com/NixOS/nixpkgs/archive/2f06b87f64bc06229e05045853e0876666e1b023.tar.gz";
sha256 = "sha256:1d7zg96xw4qsqh7c89pgha9wkq3rbi9as3k3d88jlxy2z0ns0cy2";
};
}

View file

@ -0,0 +1,37 @@
let
common = import ./common.nix;
pkgs = import common.pkgsSrc {};
python-with-my-packages = pkgs.python3.withPackages (p: with p; [
minio
]);
in
pkgs.stdenv.mkDerivation {
name = "backup-psql";
src = pkgs.lib.sourceFilesBySuffices ./. [ ".py" ];
buildInputs = [
python-with-my-packages
pkgs.age
pkgs.postgresql_14
];
buildPhase = ''
cat > backup-psql <<EOF
#!${pkgs.bash}/bin/bash
export PYTHONPATH=${python-with-my-packages}/${python-with-my-packages.sitePackages}
export PATH=${python-with-my-packages}/bin:${pkgs.age}/bin:${pkgs.postgresql_14}/bin
${python-with-my-packages}/bin/python3 $out/lib/backup-psql.py
EOF
chmod +x backup-psql
'';
installPhase = ''
mkdir -p $out/{bin,lib}
cp *.py $out/lib/backup-psql.py
cp backup-psql $out/bin/backup-psql
'';
}

View file

@ -0,0 +1,11 @@
let
common = import ./common.nix;
app = import ./default.nix;
pkgs = import common.pkgsSrc {};
in
pkgs.dockerTools.buildImage {
name = "superboum/backup-psql-docker";
config = {
Cmd = [ "${app}/bin/backup-psql" ];
};
}

View file

@ -0,0 +1,171 @@
job "backup_daily" {
datacenters = ["dc1"]
type = "batch"
priority = "60"
periodic {
cron = "@daily"
// Do not allow overlapping runs.
prohibit_overlap = true
}
group "backup-dovecot" {
constraint {
attribute = "${attr.unique.hostname}"
operator = "="
value = "digitale"
}
task "main" {
driver = "docker"
config {
image = "restic/restic:0.12.1"
entrypoint = [ "/bin/sh", "-c" ]
args = [ "restic backup /mail && restic forget --keep-within 1m1d --keep-within-weekly 3m --keep-within-monthly 1y && restic prune --max-unused 50% --max-repack-size 2G && restic check" ]
volumes = [
"/mnt/ssd/mail:/mail"
]
}
template {
data = <<EOH
AWS_ACCESS_KEY_ID={{ key "secrets/email/dovecot/backup_aws_access_key_id" }}
AWS_SECRET_ACCESS_KEY={{ key "secrets/email/dovecot/backup_aws_secret_access_key" }}
RESTIC_REPOSITORY={{ key "secrets/email/dovecot/backup_restic_repository" }}
RESTIC_PASSWORD={{ key "secrets/email/dovecot/backup_restic_password" }}
EOH
destination = "secrets/env_vars"
env = true
}
resources {
cpu = 500
memory = 200
}
restart {
attempts = 2
interval = "30m"
delay = "15s"
mode = "fail"
}
}
}
group "backup-plume" {
constraint {
attribute = "${attr.unique.hostname}"
operator = "="
value = "digitale"
}
task "main" {
driver = "docker"
config {
image = "restic/restic:0.12.1"
entrypoint = [ "/bin/sh", "-c" ]
args = [ "restic backup /plume && restic forget --keep-within 1m1d --keep-within-weekly 3m --keep-within-monthly 1y && restic prune --max-unused 50% --max-repack-size 2G && restic check" ]
volumes = [
"/mnt/ssd/plume/media:/plume"
]
}
template {
data = <<EOH
AWS_ACCESS_KEY_ID={{ key "secrets/plume/backup_aws_access_key_id" }}
AWS_SECRET_ACCESS_KEY={{ key "secrets/plume/backup_aws_secret_access_key" }}
RESTIC_REPOSITORY={{ key "secrets/plume/backup_restic_repository" }}
RESTIC_PASSWORD={{ key "secrets/plume/backup_restic_password" }}
EOH
destination = "secrets/env_vars"
env = true
}
resources {
cpu = 500
memory = 200
}
restart {
attempts = 2
interval = "30m"
delay = "15s"
mode = "fail"
}
}
}
group "backup-consul" {
task "consul-kv-export" {
driver = "docker"
lifecycle {
hook = "prestart"
sidecar = false
}
config {
image = "consul:1.11.2"
network_mode = "host"
entrypoint = [ "/bin/sh", "-c" ]
args = [ "/bin/consul kv export > $NOMAD_ALLOC_DIR/consul.json" ]
}
env {
CONSUL_HTTP_ADDR = "http://consul.service.2.cluster.deuxfleurs.fr:8500"
}
resources {
cpu = 200
memory = 200
}
restart {
attempts = 2
interval = "30m"
delay = "15s"
mode = "fail"
}
}
task "restic-backup" {
driver = "docker"
config {
image = "restic/restic:0.12.1"
entrypoint = [ "/bin/sh", "-c" ]
args = [ "restic backup $NOMAD_ALLOC_DIR/consul.json && restic forget --keep-within 1m1d --keep-within-weekly 3m --keep-within-monthly 1y && restic prune --max-unused 50% --max-repack-size 2G && restic check" ]
}
template {
data = <<EOH
AWS_ACCESS_KEY_ID={{ key "secrets/backup/consul/backup_aws_access_key_id" }}
AWS_SECRET_ACCESS_KEY={{ key "secrets/backup/consul/backup_aws_secret_access_key" }}
RESTIC_REPOSITORY={{ key "secrets/backup/consul/backup_restic_repository" }}
RESTIC_PASSWORD={{ key "secrets/backup/consul/backup_restic_password" }}
EOH
destination = "secrets/env_vars"
env = true
}
resources {
cpu = 200
memory = 200
}
restart {
attempts = 2
interval = "30m"
delay = "15s"
mode = "fail"
}
}
}
}

View file

@ -0,0 +1,55 @@
job "backup_weekly" {
datacenters = ["dc1"]
type = "batch"
priority = "60"
periodic {
cron = "@weekly"
// Do not allow overlapping runs.
prohibit_overlap = true
}
group "backup-psql" {
task "main" {
driver = "docker"
config {
image = "superboum/backup-psql-docker:gyr3aqgmhs0hxj0j9hkrdmm1m07i8za2"
volumes = [
// Mount a cache on the hard disk to avoid filling the SSD
"/mnt/storage/tmp_bckp_psql:/mnt/cache"
]
}
template {
data = <<EOH
CACHE_DIR=/mnt/cache
AWS_BUCKET=backups-pgbasebackup
AWS_ENDPOINT=s3.deuxfleurs.shirokumo.net
AWS_ACCESS_KEY_ID={{ key "secrets/backup/psql/aws_access_key_id" }}
AWS_SECRET_ACCESS_KEY={{ key "secrets/backup/psql/aws_secret_access_key" }}
CRYPT_PUBLIC_KEY={{ key "secrets/backup/psql/crypt_public_key" }}
PSQL_HOST=psql-proxy.service.2.cluster.deuxfleurs.fr
PSQL_USER={{ key "secrets/postgres/keeper/pg_repl_username" }}
PGPASSWORD={{ key "secrets/postgres/keeper/pg_repl_pwd" }}
EOH
destination = "secrets/env_vars"
env = true
}
resources {
cpu = 200
memory = 200
}
restart {
attempts = 2
interval = "30m"
delay = "15s"
mode = "fail"
}
}
}
}

View file

@ -0,0 +1 @@
USER Backup AWS access key ID

View file

@ -0,0 +1 @@
USER Backup AWS secret access key

View file

@ -0,0 +1 @@
USER Restic password to encrypt backups

View file

@ -0,0 +1 @@
USER Restic repository, eg. s3:https://s3.garage.tld

View file

@ -0,0 +1 @@
USER Minio access key

View file

@ -0,0 +1 @@
USER Minio secret key

View file

@ -0,0 +1 @@
USER a private key to decript backups from age

View file

@ -0,0 +1 @@
USER A public key to encypt backups with age

View file

@ -0,0 +1,83 @@
job "bagage" {
datacenters = ["dc1"]
type = "service"
priority = 90
constraint {
attribute = "${attr.cpu.arch}"
value = "amd64"
}
group "main" {
count = 1
network {
port "web_port" { to = 8080 }
port "ssh_port" {
static = 2222
to = 2222
}
}
task "server" {
driver = "docker"
config {
image = "superboum/amd64_bagage:v11"
readonly_rootfs = false
volumes = [
"secrets/id_rsa:/id_rsa"
]
ports = [ "web_port", "ssh_port" ]
}
env {
BAGAGE_LDAP_ENDPOINT = "bottin2.service.2.cluster.deuxfleurs.fr:389"
}
resources {
memory = 500
}
template {
data = "{{ key \"secrets/bagage/id_rsa\" }}"
destination = "secrets/id_rsa"
}
service {
name = "bagage-ssh"
port = "ssh_port"
address_mode = "host"
tags = [
"bagage",
"(diplonat (tcp_port 2222))"
]
}
service {
name = "bagage-webdav"
tags = [
"bagage",
"traefik.enable=true",
"traefik.frontend.entryPoints=https,http",
"traefik.frontend.rule=Host:bagage.deuxfleurs.fr",
"tricot bagage.deuxfleurs.fr",
]
port = "web_port"
address_mode = "host"
check {
type = "tcp"
port = "web_port"
address_mode = "host"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
}
}
}
}

View file

@ -0,0 +1 @@
CMD ssh-keygen -q -f >(cat) -N "" <<< y 2>/dev/null 1>&2 ; true

View file

@ -1,5 +1,5 @@
job "core" { job "core" {
datacenters = ["dc1"] datacenters = ["dc1", "neptune"]
type = "system" type = "system"
priority = 90 priority = 90
@ -18,15 +18,21 @@ job "core" {
driver = "docker" driver = "docker"
config { config {
image = "darkgallium/amd64_diplonat:v2" image = "lxpz/amd64_diplonat:3"
network_mode = "host" network_mode = "host"
readonly_rootfs = true readonly_rootfs = true
privileged = true privileged = true
}
restart {
interval = "30m"
attempts = 2
delay = "15s"
mode = "delay"
} }
template { template {
data = <<EOH data = <<EOH
DIPLONAT_PRIVATE_IP={{ env "attr.unique.network.ip-address" }}
DIPLONAT_REFRESH_TIME=60 DIPLONAT_REFRESH_TIME=60
DIPLONAT_EXPIRATION_TIME=300 DIPLONAT_EXPIRATION_TIME=300
DIPLONAT_CONSUL_NODE_NAME={{ env "attr.unique.hostname" }} DIPLONAT_CONSUL_NODE_NAME={{ env "attr.unique.hostname" }}

View file

@ -0,0 +1,2 @@
docker load < $(nix-build docker.nix)
docker push superboum/cryptpad:???

View file

@ -0,0 +1,8 @@
{
pkgsSrc = fetchTarball {
# Latest commit on https://github.com/NixOS/nixpkgs/tree/nixos-21.11
# As of 2022-04-15
url ="https://github.com/NixOS/nixpkgs/archive/2f06b87f64bc06229e05045853e0876666e1b023.tar.gz";
sha256 = "sha256:1d7zg96xw4qsqh7c89pgha9wkq3rbi9as3k3d88jlxy2z0ns0cy2";
};
}

View file

@ -0,0 +1,10 @@
let
common = import ./common.nix;
pkgs = import common.pkgsSrc {};
in
pkgs.dockerTools.buildImage {
name = "superboum/cryptpad";
config = {
Cmd = [ "${pkgs.cryptpad}/bin/cryptpad" ];
};
}

View file

@ -0,0 +1,283 @@
/* globals module */
/* DISCLAIMER:
There are two recommended methods of running a CryptPad instance:
1. Using a standalone nodejs server without HTTPS (suitable for local development)
2. Using NGINX to serve static assets and to handle HTTPS for API server's websocket traffic
We do not officially recommend or support Apache, Docker, Kubernetes, Traefik, or any other configuration.
Support requests for such setups should be directed to their authors.
If you're having difficulty difficulty configuring your instance
we suggest that you join the project's IRC/Matrix channel.
If you don't have any difficulty configuring your instance and you'd like to
support us for the work that went into making it pain-free we are quite happy
to accept donations via our opencollective page: https://opencollective.com/cryptpad
*/
module.exports = {
/* CryptPad is designed to serve its content over two domains.
* Account passwords and cryptographic content is handled on the 'main' domain,
* while the user interface is loaded on a 'sandbox' domain
* which can only access information which the main domain willingly shares.
*
* In the event of an XSS vulnerability in the UI (that's bad)
* this system prevents attackers from gaining access to your account (that's good).
*
* Most problems with new instances are related to this system blocking access
* because of incorrectly configured sandboxes. If you only see a white screen
* when you try to load CryptPad, this is probably the cause.
*
* PLEASE READ THE FOLLOWING COMMENTS CAREFULLY.
*
*/
/* httpUnsafeOrigin is the URL that clients will enter to load your instance.
* Any other URL that somehow points to your instance is supposed to be blocked.
* The default provided below assumes you are loading CryptPad from a server
* which is running on the same machine, using port 3000.
*
* In a production instance this should be available ONLY over HTTPS
* using the default port for HTTPS (443) ie. https://cryptpad.fr
* In such a case this should be also handled by NGINX, as documented in
* cryptpad/docs/example.nginx.conf (see the $main_domain variable)
*
*/
httpUnsafeOrigin: 'http://localhost:3000',
/* httpSafeOrigin is the URL that is used for the 'sandbox' described above.
* If you're testing or developing with CryptPad on your local machine then
* it is appropriate to leave this blank. The default behaviour is to serve
* the main domain over port 3000 and to serve the sandbox content over port 3001.
*
* This is not appropriate in a production environment where invasive networks
* may filter traffic going over abnormal ports.
* To correctly configure your production instance you must provide a URL
* with a different domain (a subdomain is sufficient).
* It will be used to load the UI in our 'sandbox' system.
*
* This value corresponds to the $sandbox_domain variable
* in the example nginx file.
*
* Note that in order for the sandboxing system to be effective
* httpSafeOrigin must be different from httpUnsafeOrigin.
*
* CUSTOMIZE AND UNCOMMENT THIS FOR PRODUCTION INSTALLATIONS.
*/
// httpSafeOrigin: "https://some-other-domain.xyz",
/* httpAddress specifies the address on which the nodejs server
* should be accessible. By default it will listen on 127.0.0.1
* (IPv4 localhost on most systems). If you want it to listen on
* all addresses, including IPv6, set this to '::'.
*
*/
httpAddress: '::',
/* httpPort specifies on which port the nodejs server should listen.
* By default it will serve content over port 3000, which is suitable
* for both local development and for use with the provided nginx example,
* which will proxy websocket traffic to your node server.
*
*/
//httpPort: 3000,
/* httpSafePort allows you to specify an alternative port from which
* the node process should serve sandboxed assets. The default value is
* that of your httpPort + 1. You probably don't need to change this.
*
*/
//httpSafePort: 3001,
/* CryptPad will launch a child process for every core available
* in order to perform CPU-intensive tasks in parallel.
* Some host environments may have a very large number of cores available
* or you may want to limit how much computing power CryptPad can take.
* If so, set 'maxWorkers' to a positive integer.
*/
// maxWorkers: 4,
/* =====================
* Admin
* ===================== */
/*
* CryptPad contains an administration panel. Its access is restricted to specific
* users using the following list.
* To give access to the admin panel to a user account, just add their public signing
* key, which can be found on the settings page for registered users.
* Entries should be strings separated by a comma.
*/
/*
adminKeys: [
//"[cryptpad-user1@my.awesome.website/YZgXQxKR0Rcb6r6CmxHPdAGLVludrAF2lEnkbx1vVOo=]",
],
*/
/* =====================
* STORAGE
* ===================== */
/* Pads that are not 'pinned' by any registered user can be set to expire
* after a configurable number of days of inactivity (default 90 days).
* The value can be changed or set to false to remove expiration.
* Expired pads can then be removed using a cron job calling the
* `evict-inactive.js` script with node
*
* defaults to 90 days if nothing is provided
*/
//inactiveTime: 90, // days
/* CryptPad archives some data instead of deleting it outright.
* This archived data still takes up space and so you'll probably still want to
* remove these files after a brief period.
*
* cryptpad/scripts/evict-inactive.js is intended to be run daily
* from a crontab or similar scheduling service.
*
* The intent with this feature is to provide a safety net in case of accidental
* deletion. Set this value to the number of days you'd like to retain
* archived data before it's removed permanently.
*
* defaults to 15 days if nothing is provided
*/
//archiveRetentionTime: 15,
/* It's possible to configure your instance to remove data
* stored on behalf of inactive accounts. Set 'accountRetentionTime'
* to the number of days an account can remain idle before its
* documents and other account data is removed.
*
* Leave this value commented out to preserve all data stored
* by user accounts regardless of inactivity.
*/
//accountRetentionTime: 365,
/* Starting with CryptPad 3.23.0, the server automatically runs
* the script responsible for removing inactive data according to
* your configured definition of inactivity. Set this value to `true`
* if you prefer not to remove inactive data, or if you prefer to
* do so manually using `scripts/evict-inactive.js`.
*/
//disableIntegratedEviction: true,
/* Max Upload Size (bytes)
* this sets the maximum size of any one file uploaded to the server.
* anything larger than this size will be rejected
* defaults to 20MB if no value is provided
*/
//maxUploadSize: 20 * 1024 * 1024,
/* Users with premium accounts (those with a plan included in their customLimit)
* can benefit from an increased upload size limit. By default they are restricted to the same
* upload size as any other registered user.
*
*/
//premiumUploadSize: 100 * 1024 * 1024,
/* =====================
* DATABASE VOLUMES
* ===================== */
/*
* CryptPad stores each document in an individual file on your hard drive.
* Specify a directory where files should be stored.
* It will be created automatically if it does not already exist.
*/
filePath: './root/tmp/mut/datastore/',
/* CryptPad offers the ability to archive data for a configurable period
* before deleting it, allowing a means of recovering data in the event
* that it was deleted accidentally.
*
* To set the location of this archive directory to a custom value, change
* the path below:
*/
archivePath: './root/tmp/mut/data/archive',
/* CryptPad allows logged in users to request that particular documents be
* stored by the server indefinitely. This is called 'pinning'.
* Pin requests are stored in a pin-store. The location of this store is
* defined here.
*/
pinPath: './root/tmp/mut/data/pins',
/* if you would like the list of scheduled tasks to be stored in
a custom location, change the path below:
*/
taskPath: './root/tmp/mut/data/tasks',
/* if you would like users' authenticated blocks to be stored in
a custom location, change the path below:
*/
blockPath: './root/tmp/mut/block',
/* CryptPad allows logged in users to upload encrypted files. Files/blobs
* are stored in a 'blob-store'. Set its location here.
*/
blobPath: './root/tmp/mut/blob',
/* CryptPad stores incomplete blobs in a 'staging' area until they are
* fully uploaded. Set its location here.
*/
blobStagingPath: './root/tmp/mut/data/blobstage',
decreePath: './root/tmp/mut/data/decrees',
/* CryptPad supports logging events directly to the disk in a 'logs' directory
* Set its location here, or set it to false (or nothing) if you'd rather not log
*/
logPath: './root/tmp/mut/data/logs',
/* =====================
* Debugging
* ===================== */
/* CryptPad can log activity to stdout
* This may be useful for debugging
*/
logToStdout: true,
/* CryptPad can be configured to log more or less
* the various settings are listed below by order of importance
*
* silly, verbose, debug, feedback, info, warn, error
*
* Choose the least important level of logging you wish to see.
* For example, a 'silly' logLevel will display everything,
* while 'info' will display 'info', 'warn', and 'error' logs
*
* This will affect both logging to the console and the disk.
*/
logLevel: 'debug',
/* clients can use the /settings/ app to opt out of usage feedback
* which informs the server of things like how much each app is being
* used, and whether certain clientside features are supported by
* the client's browser. The intent is to provide feedback to the admin
* such that the service can be improved. Enable this with `true`
* and ignore feedback with `false` or by commenting the attribute
*
* You will need to set your logLevel to include 'feedback'. Set this
* to false if you'd like to exclude feedback from your logs.
*/
logFeedback: false,
/* CryptPad supports verbose logging
* (false by default)
*/
verbose: true,
/* Surplus information:
*
* 'installMethod' is included in server telemetry to voluntarily
* indicate how many instances are using unofficial installation methods
* such as Docker.
*
*/
installMethod: 'unspecified',
};

View file

@ -4,7 +4,7 @@
"consul_host": "http://consul.service.2.cluster.deuxfleurs.fr:8500", "consul_host": "http://consul.service.2.cluster.deuxfleurs.fr:8500",
"log_level": "debug", "log_level": "debug",
"acl": [ "acl": [
"*,dc=deuxfleurs,dc=fr::read:*:* !userpassword", "*,dc=deuxfleurs,dc=fr::read:*:* !userpassword !user_secret !alternate_user_secrets !garage_s3_secret_key",
"*::read modify:SELF:*", "*::read modify:SELF:*",
"ANONYMOUS::bind:*,ou=users,dc=deuxfleurs,dc=fr:", "ANONYMOUS::bind:*,ou=users,dc=deuxfleurs,dc=fr:",
"ANONYMOUS::bind:cn=admin,dc=deuxfleurs,dc=fr:", "ANONYMOUS::bind:cn=admin,dc=deuxfleurs,dc=fr:",
@ -20,10 +20,6 @@
"*:cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr:modifyAdd:cn=email,ou=groups,dc=deuxfleurs,dc=fr:*", "*:cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr:modifyAdd:cn=email,ou=groups,dc=deuxfleurs,dc=fr:*",
"*,ou=invitations,dc=deuxfleurs,dc=fr::modifyAdd:cn=email,ou=groups,dc=deuxfleurs,dc=fr:*", "*,ou=invitations,dc=deuxfleurs,dc=fr::modifyAdd:cn=email,ou=groups,dc=deuxfleurs,dc=fr:*",
"*:cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr:modifyAdd:cn=seafile,ou=groups,dc=deuxfleurs,dc=fr:*",
"*,ou=invitations,dc=deuxfleurs,dc=fr::modifyAdd:cn=seafile,ou=groups,dc=deuxfleurs,dc=fr:*",
"*:cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr:modifyAdd:cn=nextcloud,ou=groups,dc=deuxfleurs,dc=fr:*",
"*,ou=invitations,dc=deuxfleurs,dc=fr::modifyAdd:cn=seafile,ou=nextcloud,dc=deuxfleurs,dc=fr:*",
"cn=admin,dc=deuxfleurs,dc=fr::read add modify delete:*:*", "cn=admin,dc=deuxfleurs,dc=fr::read add modify delete:*:*",
"*:cn=admin,ou=groups,dc=deuxfleurs,dc=fr:read add modify delete:*:*" "*:cn=admin,ou=groups,dc=deuxfleurs,dc=fr:read add modify delete:*:*"

View file

@ -12,19 +12,23 @@
"invitation_name_attr": "cn", "invitation_name_attr": "cn",
"invited_mail_format": "{}@deuxfleurs.fr", "invited_mail_format": "{}@deuxfleurs.fr",
"invited_auto_groups": [ "invited_auto_groups": [
"cn=email,ou=groups,dc=deuxfleurs,dc=fr", "cn=email,ou=groups,dc=deuxfleurs,dc=fr"
"cn=seafile,ou=groups,dc=deuxfleurs,dc=fr",
"cn=nextcloud,ou=groups,dc=deuxfleurs,dc=fr"
], ],
"web_address": "https://guichet.deuxfleurs.fr", "web_address": "https://guichet.deuxfleurs.fr",
"mail_from": "coucou@deuxfleurs.fr", "mail_from": "deuxfleurs-bienvenue@adnab.me",
"smtp_server": "adnab.me:25", "smtp_server": "adnab.me:25",
"smtp_username": "{{ key "secrets/directory/guichet/smtp_user" | trimSpace }}", "smtp_username": "{{ key "secrets/directory/guichet/smtp_user" | trimSpace }}",
"smtp_password": "{{ key "secrets/directory/guichet/smtp_pass" | trimSpace }}", "smtp_password": "{{ key "secrets/directory/guichet/smtp_pass" | trimSpace }}",
"admin_account": "cn=admin,dc=deuxfleurs,dc=fr", "admin_account": "cn=admin,dc=deuxfleurs,dc=fr",
"group_can_admin": "cn=admin,ou=groups,dc=deuxfleurs,dc=fr", "group_can_admin": "cn=admin,ou=groups,dc=deuxfleurs,dc=fr",
"group_can_invite": "cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr" "group_can_invite": "cn=asso_deuxfleurs,ou=groups,dc=deuxfleurs,dc=fr",
"s3_endpoint": "garage.deuxfleurs.fr",
"s3_access_key": "{{ key "secrets/directory/guichet/s3_access_key" | trimSpace }}",
"s3_secret_key": "{{ key "secrets/directory/guichet/s3_secret_key" | trimSpace }}",
"s3_region": "garage",
"s3_bucket": "bottin-pictures"
} }

View file

@ -21,7 +21,7 @@ job "directory" {
task "bottin" { task "bottin" {
driver = "docker" driver = "docker"
config { config {
image = "lxpz/bottin_amd64:20" image = "superboum/bottin_amd64:22"
network_mode = "host" network_mode = "host"
readonly_rootfs = true readonly_rootfs = true
ports = [ "ldap_port" ] ports = [ "ldap_port" ]
@ -59,6 +59,7 @@ job "directory" {
} }
} }
/*
group "guichet" { group "guichet" {
count = 1 count = 1
@ -69,7 +70,7 @@ job "directory" {
task "guichet" { task "guichet" {
driver = "docker" driver = "docker"
config { config {
image = "lxpz/guichet_amd64:10" image = "dxflrs/guichet:6y7pv4kgfsn02iijj55kf5af0rbksgrn"
readonly_rootfs = true readonly_rootfs = true
ports = [ "web_port" ] ports = [ "web_port" ]
volumes = [ volumes = [
@ -93,6 +94,7 @@ job "directory" {
"traefik.enable=true", "traefik.enable=true",
"traefik.frontend.entryPoints=https,http", "traefik.frontend.entryPoints=https,http",
"traefik.frontend.rule=Host:guichet.deuxfleurs.fr", "traefik.frontend.rule=Host:guichet.deuxfleurs.fr",
"tricot guichet.deuxfleurs.fr",
] ]
port = "web_port" port = "web_port"
address_mode = "host" address_mode = "host"
@ -110,5 +112,6 @@ job "directory" {
} }
} }
} }
*/
} }

View file

@ -0,0 +1 @@
USER Garage access key for Guichet profile pictures

View file

@ -0,0 +1 @@
USER Garage secret key for Guichet profile pictures

View file

@ -0,0 +1 @@
USER SMTP password

View file

@ -0,0 +1 @@
USER SMTP username

View file

@ -1,29 +1,27 @@
version: '3.4' version: '3.4'
services: services:
mariadb:
build:
context: ./seafile/build/mariadb
args:
VERSION: 4 # fake for now
image: superboum/amd64_mariadb:v4
# Instant Messaging # Instant Messaging
riot: riot:
build: build:
context: ./im/build/riotweb context: ./im/build/riotweb
args: args:
# https://github.com/vector-im/riot-web/releases # https://github.com/vector-im/riot-web/releases
VERSION: 1.7.18 VERSION: 1.10.15
image: particallydone/amd64_riotweb:v20 image: superboum/amd64_riotweb:v30
synapse: synapse:
build: build:
context: ./im/build/matrix-synapse context: ./im/build/matrix-synapse
args: args:
# https://github.com/matrix-org/synapse/releases # https://github.com/matrix-org/synapse/releases
VERSION: 1.26.0 VERSION: 1.61.1
image: particallydone/amd64_synapse:v41 # https://github.com/matrix-org/synapse-s3-storage-provider/commits/main
# Update with the latest commit on main each time you update the synapse version
# otherwise synapse may fail to launch due to incompatibility issues
# see this issue for an example: https://github.com/matrix-org/synapse-s3-storage-provider/issues/64
S3_VERSION: ffd3fa477321608e57d27644197e721965e0e858
image: superboum/amd64_synapse:v53
# Email # Email
sogo: sogo:
@ -38,52 +36,54 @@ services:
build: build:
context: ./email/build/alps context: ./email/build/alps
args: args:
VERSION: 5cef0aaff2b8b6ee3e00b566123517e241d8cfb8 VERSION: 9bafa64b9d
image: superboum/amd64_alps:v1 image: superboum/amd64_alps:v1
dovecot:
build:
context: ./email/build/dovecot
image: superboum/amd64_dovecot:v6
# VoIP # VoIP
jitsi-meet: jitsi-meet:
build: build:
context: ./jitsi/build/jitsi-meet context: ./jitsi/build/jitsi-meet
args: args:
# https://github.com/jitsi/jitsi-meet # https://github.com/jitsi/jitsi-meet
PREFIXV: stable/jitsi-meet_ MEET_TAG: stable/jitsi-meet_6826
VERSION: 5463 image: superboum/amd64_jitsi_meet:v5
image: superboum/amd64_jitsi_meet:v4
jitsi-conference-focus: jitsi-conference-focus:
build: build:
context: ./jitsi/build/jitsi-conference-focus context: ./jitsi/build/jitsi-conference-focus
args: args:
# https://github.com/jitsi/jicofo # https://github.com/jitsi/jicofo
PREFIXV: jitsi-meet_ JICOFO_TAG: stable/jitsi-meet_6826
VERSION: 5463 image: superboum/amd64_jitsi_conference_focus:v9
image: superboum/amd64_jitsi_conference_focus:v7
jitsi-videobridge: jitsi-videobridge:
build: build:
context: ./jitsi/build/jitsi-videobridge context: ./jitsi/build/jitsi-videobridge
args: args:
# https://github.com/jitsi/jitsi-videobridge # https://github.com/jitsi/jitsi-videobridge
PREFIXV: jitsi-meet_ # note: JVB is not tagged with non-stable tags
VERSION: 5463 JVB_TAG: stable/jitsi-meet_6826
image: superboum/amd64_jitsi_videobridge:v17 image: superboum/amd64_jitsi_videobridge:v20
jitsi-xmpp: jitsi-xmpp:
build: build:
context: ./jitsi/build/jitsi-xmpp context: ./jitsi/build/jitsi-xmpp
args: args:
PREFIXV: jitsi-meet_ MEET_TAG: stable/jitsi-meet_6826
MEET_VERSION: 5463 PROSODY_VERSION: 0.11.12-1
PROSODY_VERSION: 0.11.7-1~buster4 image: superboum/amd64_jitsi_xmpp:v10
image: superboum/amd64_jitsi_xmpp:v9
plume: plume:
build: build:
context: ./plume/build/plume context: ./plume/build/plume
args: args:
VERSION: 0.6.0 VERSION: 8709f6cf9f8ff7e3c5ee7ea699ee7c778e92fefc
image: superboum/plume:v2 image: superboum/plume:v8
postfix: postfix:
build: build:
@ -92,3 +92,17 @@ services:
# https://packages.debian.org/fr/buster/postfix # https://packages.debian.org/fr/buster/postfix
VERSION: 3.4.14-0+deb10u1 VERSION: 3.4.14-0+deb10u1
image: superboum/amd64_postfix:v3 image: superboum/amd64_postfix:v3
postgres:
build:
args:
# https://github.com/sorintlab/stolon/releases
STOLON_VERSION: 3bb7499f815f77140551eb762b200cf4557f57d3
context: ./postgres/build/postgres
image: superboum/amd64_postgres:v11
backup-consul:
build:
context: ./backup/build/backup-consul
image: lxpz/backup_consul:12

View file

@ -0,0 +1,127 @@
job "drone-ci" {
datacenters = ["dc1"]
type = "service"
group "server" {
count = 1
network {
port "web_port" {
to = 80
}
}
task "drone_server" {
driver = "docker"
config {
image = "drone/drone:2.12.0"
ports = [ "web_port" ]
}
template {
data = <<EOH
DRONE_GITEA_SERVER=https://git.deuxfleurs.fr
DRONE_GITEA_CLIENT_ID={{ key "secrets/drone-ci/oauth_client_id" }}
DRONE_GITEA_CLIENT_SECRET={{ key "secrets/drone-ci/oauth_client_secret" }}
DRONE_RPC_SECRET={{ key "secrets/drone-ci/rpc_secret" }}
DRONE_SERVER_HOST=drone.deuxfleurs.fr
DRONE_SERVER_PROTO=https
DRONE_DATABASE_SECRET={{ key "secrets/drone-ci/db_enc_secret" }}
DRONE_COOKIE_SECRET={{ key "secrets/drone-ci/cookie_secret" }}
AWS_ACCESS_KEY_ID={{ key "secrets/drone-ci/s3_ak" }}
AWS_SECRET_ACCESS_KEY={{ key "secrets/drone-ci/s3_sk" }}
AWS_DEFAULT_REGION=garage
AWS_REGION=garage
DRONE_S3_BUCKET={{ key "secrets/drone-ci/s3_bucket" }}
DRONE_S3_ENDPOINT=https://garage.deuxfleurs.fr
DRONE_S3_PATH_STYLE=true
DRONE_DATABASE_DRIVER=postgres
DRONE_DATABASE_DATASOURCE=postgres://{{ key "secrets/drone-ci/db_user" }}:{{ key "secrets/drone-ci/db_pass" }}@psql-proxy.service.2.cluster.deuxfleurs.fr:5432/drone?sslmode=disable
DRONE_USER_CREATE=username:lx-admin,admin:true
DRONE_REGISTRATION_CLOSED=true
DRONE_LOGS_TEXT=true
DRONE_LOGS_PRETTY=true
DRONE_LOGS_DEBUG=true
DOCKER_API_VERSION=1.39
EOH
destination = "secrets/env"
env = true
}
resources {
cpu = 100
memory = 100
}
service {
name = "drone"
tags = [
"drone",
"traefik.enable=true",
"traefik.frontend.entryPoints=https,http",
"traefik.frontend.rule=Host:drone.deuxfleurs.fr",
"tricot drone.deuxfleurs.fr",
]
port = "web_port"
address_mode = "host"
check {
type = "http"
protocol = "http"
port = "web_port"
path = "/"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "600s"
ignore_warnings = false
}
}
}
}
}
/*
group "runner" {
count = 3
constraint {
operator = "distinct_hosts"
value = "true"
}
task "drone_runner" {
driver = "docker"
config {
network_mode = "host"
#image = "drone/drone-runner-nomad:latest"
image = "drone/drone-runner-docker:1.6.3"
volumes = [
"/var/run/docker.sock:/var/run/docker.sock"
]
}
template {
data = <<EOH
DRONE_RPC_SECRET={{ key "secrets/drone-ci/rpc_secret" }}
DRONE_RPC_HOST=drone.deuxfleurs.fr
DRONE_RPC_PROTO=https
DRONE_RUNNER_NAME={{ env "node.unique.name" }}
DRONE_DEBUG=true
NOMAD_ADDR=http://nomad-client.service.2.cluster.deuxfleurs.fr:4646
DOCKER_API_VERSION=1.39
EOH
destination = "secrets/env"
env = true
}
resources {
memory = 40
cpu = 50
}
}
}
*/
}

View file

@ -0,0 +1,69 @@
## Install Debian
We recommend Debian Bullseye
## Install Docker CE from docker.io
Do not use the docker engine shipped by Debian
Doc:
- https://docs.docker.com/engine/install/debian/
- https://docs.docker.com/compose/install/
On a fresh install, as root:
```bash
apt-get remove -y docker docker-engine docker.io containerd runc
apt-get update
apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
```
## Install the runner
*This is our Nix runner version 2, previously we had another way to start Nix runners. This one has a proper way to handle concurrency, require less boilerplate, and should be safer and more idiomatic.*
```bash
wget https://git.deuxfleurs.fr/Deuxfleurs/infrastructure/raw/branch/main/app/drone-ci/integration/nix.conf
wget https://git.deuxfleurs.fr/Deuxfleurs/infrastructure/raw/branch/main/app/drone-ci/integration/docker-compose.yml
# Edit the docker-compose.yml to adapt its variables to your needs,
# especially the capacitiy value and its name.
COMPOSE_PROJECT_NAME=drone DRONE_SECRET=xxx docker-compose up -d
```
That's all folks.
## Check if a given job is built by your runner
```bash
export URL=https://drone.deuxfleurs.fr
export REPO=Deuxfleurs/garage
export BUILD=1312
curl ${URL}/api/repos/${REPO}/builds/${BUILD} \
| jq -c '[.stages[] | { name: .name, machine: .machine }]'
```
It will give you the following result:
```json
[{"name":"default","machine":"1686a"},{"name":"release-linux-x86_64","machine":"vimaire"},{"name":"release-linux-i686","machine":"carcajou"},{"name":"release-linux-aarch64","machine":"caribou"},{"name":"release-linux-armv6l","machine":"cariacou"},{"name":"refresh-release-page","machine":null}]
```
## Random note
*This part might be deprecated!*
This setup is done mainly to allow nix builds with some cache.
To use the cache in Drone, you must set your repository as trusted.
The command line tool does not work (it says it successfully set your repository as trusted but it did nothing):
the only way to set your repository as trusted is to connect on the DB and set the `repo_trusted` field of your repo to true.

View file

@ -0,0 +1,54 @@
version: '3.4'
services:
nix-daemon:
image: nixpkgs/nix:nixos-22.05
restart: always
command: nix-daemon
privileged: true
volumes:
- "nix:/nix"
- "./nix.conf:/etc/nix/nix.conf:ro"
drone-runner:
image: drone/drone-runner-docker:latest
restart: always
environment:
- DRONE_RPC_PROTO=https
- DRONE_RPC_HOST=drone.deuxfleurs.fr
- DRONE_RPC_SECRET=${DRONE_SECRET}
- DRONE_RUNNER_CAPACITY=3
- DRONE_DEBUG=true
- DRONE_LOGS_TRACE=true
- DRONE_RPC_DUMP_HTTP=true
- DRONE_RPC_DUMP_HTTP_BODY=true
- DRONE_RUNNER_NAME=i_forgot_to_change_my_runner_name
- DRONE_RUNNER_LABELS=nix-daemon:1
# we should put "nix:/nix:ro but it is not supported by
# drone-runner-docker because the dependency envconfig does
# not support having two colons (:) in the same stanza.
# Without the RO flag (or using docker userns), build isolation
# is broken.
# https://discourse.drone.io/t/allow-mounting-a-host-volume-as-read-only/10071
# https://github.com/kelseyhightower/envconfig/pull/153
#
# A workaround for isolation is to configure docker with a userns,
# so even if the folder is writable to root, it is not to any non
# privileged docker daemon ran by drone!
- DRONE_RUNNER_VOLUMES=drone_nix:/nix
- DRONE_RUNNER_ENVIRON=NIX_REMOTE:daemon
ports:
- "3000:3000/tcp"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
drone-gc:
image: drone/gc:latest
restart: always
environment:
- GC_DEBUG=true
- GC_CACHE=10gb
- GC_INTERVAL=10m
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
volumes:
nix:

View file

@ -0,0 +1,9 @@
substituters = https://cache.nixos.org https://nix.web.deuxfleurs.fr
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix.web.deuxfleurs.fr:eTGL6kvaQn6cDR/F9lDYUIP9nCVR/kkshYfLDJf1yKs=
max-jobs = auto
cores = 0
log-lines = 200
filter-syscalls = true
sandbox = true
keep-outputs = true
keep-derivations = true

View file

@ -0,0 +1 @@
CMD openssl rand -hex 16

View file

@ -0,0 +1 @@
CMD_ONCE openssl rand -hex 16

View file

@ -0,0 +1 @@
SERVICE_PASSWORD drone

View file

@ -0,0 +1 @@
CONST drone

View file

@ -0,0 +1 @@
USER OAuth client ID (on Gitea)

View file

@ -0,0 +1 @@
USER OAuth client secret (for gitea)

View file

@ -0,0 +1 @@
CMD openssl rand -hex 16

View file

@ -0,0 +1 @@
USER S3 (garage) access key for Drone

View file

@ -0,0 +1 @@
CONST drone

View file

@ -0,0 +1 @@
USER S3 (garage) secret key for Drone

View file

@ -6,16 +6,15 @@ ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64
WORKDIR /tmp/alps WORKDIR /tmp/alps
RUN git init && \ RUN git init && \
git remote add origin https://git.sr.ht/~migadu/alps && \ git remote add origin https://git.deuxfleurs.fr/Deuxfleurs/alps.git && \
git fetch --depth 1 origin ${VERSION} && \ git fetch --depth 1 origin ${VERSION} && \
git checkout FETCH_HEAD git checkout FETCH_HEAD
COPY skipverify.patch skipverify.patch RUN go build -a -o /usr/local/bin/alps ./cmd/alps
RUN git apply skipverify.patch && \
go build -a -o /usr/local/bin/alps ./cmd/alps
FROM scratch FROM scratch
COPY --from=builder /usr/local/bin/alps /alps COPY --from=builder /usr/local/bin/alps /alps
COPY --from=builder /tmp/alps/themes /themes COPY --from=builder /tmp/alps/themes /themes
COPY --from=builder /tmp/alps/plugins /plugins
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
ENTRYPOINT ["/alps"] ENTRYPOINT ["/alps"]

View file

@ -1,55 +0,0 @@
From 47765c10f1af2013556f76dc63dfa056167ae5e8 Mon Sep 17 00:00:00 2001
From: Quentin <quentin@deuxfleurs.fr>
Date: Fri, 4 Dec 2020 13:19:24 +0100
Subject: [PATCH] Skip CA verification
---
imap.go | 3 ++-
smtp.go | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/imap.go b/imap.go
index 7554331..1a4931d 100644
--- a/imap.go
+++ b/imap.go
@@ -3,6 +3,7 @@ package alps
import (
"fmt"
+ "crypto/tls"
"github.com/emersion/go-imap"
imapclient "github.com/emersion/go-imap/client"
"github.com/emersion/go-message/charset"
@@ -16,7 +17,7 @@ func (s *Server) dialIMAP() (*imapclient.Client, error) {
var c *imapclient.Client
var err error
if s.imap.tls {
- c, err = imapclient.DialTLS(s.imap.host, nil)
+ c, err = imapclient.DialTLS(s.imap.host, &tls.Config{InsecureSkipVerify: true})
if err != nil {
return nil, fmt.Errorf("failed to connect to IMAPS server: %v", err)
}
diff --git a/smtp.go b/smtp.go
index 5e178f2..8d22f1d 100644
--- a/smtp.go
+++ b/smtp.go
@@ -3,6 +3,7 @@ package alps
import (
"fmt"
+ "crypto/tls"
"github.com/emersion/go-smtp"
)
@@ -14,7 +15,7 @@ func (s *Server) dialSMTP() (*smtp.Client, error) {
var c *smtp.Client
var err error
if s.smtp.tls {
- c, err = smtp.DialTLS(s.smtp.host, nil)
+ c, err = smtp.DialTLS(s.smtp.host, &tls.Config{InsecureSkipVerify: true})
if err != nil {
return nil, fmt.Errorf("failed to connect to SMTPS server: %v", err)
}
--
2.28.0

View file

@ -1,4 +1,4 @@
FROM amd64/debian:stretch FROM amd64/debian:bullseye
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y \ apt-get install -y \
@ -11,7 +11,6 @@ RUN apt-get update && \
dovecot-lmtpd && \ dovecot-lmtpd && \
rm -rf /etc/dovecot/* rm -rf /etc/dovecot/*
RUN useradd mailstore RUN useradd mailstore
COPY ./conf/* /etc/dovecot/
COPY entrypoint.sh /usr/local/bin/entrypoint COPY entrypoint.sh /usr/local/bin/entrypoint
ENTRYPOINT ["/usr/local/bin/entrypoint"] ENTRYPOINT ["/usr/local/bin/entrypoint"]

View file

@ -5,4 +5,8 @@ base = dc=deuxfleurs,dc=fr
scope = subtree scope = subtree
user_filter = (&(mail=%u)(&(objectClass=inetOrgPerson)(memberOf=cn=email,ou=groups,dc=deuxfleurs,dc=fr))) user_filter = (&(mail=%u)(&(objectClass=inetOrgPerson)(memberOf=cn=email,ou=groups,dc=deuxfleurs,dc=fr)))
pass_filter = (&(mail=%u)(&(objectClass=inetOrgPerson)(memberOf=cn=email,ou=groups,dc=deuxfleurs,dc=fr))) pass_filter = (&(mail=%u)(&(objectClass=inetOrgPerson)(memberOf=cn=email,ou=groups,dc=deuxfleurs,dc=fr)))
user_attrs = mail=/var/mail/%{ldap:mail} user_attrs = \
=user=%{ldap:cn}, \
=mail=maildir:/var/mail/%{ldap:cn}, \
=uid=1000, \
=gid=1000

View file

@ -19,10 +19,7 @@ service auth {
} }
} }
passdb {
args = /etc/dovecot/dovecot-ldap.conf
driver = ldap
}
service lmtp { service lmtp {
inet_listener lmtp { inet_listener lmtp {
@ -31,7 +28,23 @@ service lmtp {
} }
} }
# https://doc.dovecot.org/configuration_manual/authentication/ldap_authentication/
passdb {
args = /etc/dovecot/dovecot-ldap.conf
driver = ldap
}
userdb {
driver = prefetch
}
userdb {
args = /etc/dovecot/dovecot-ldap.conf
driver = ldap
}
service imap-login { service imap-login {
service_count = 0 # performance mode. set to 1 for secure mode
process_min_avail = 1
inet_listener imap { inet_listener imap {
port = 143 port = 143
} }
@ -40,11 +53,6 @@ service imap-login {
} }
} }
userdb {
args = uid=mailstore gid=mailstore home=/var/mail/%u
driver = static
}
protocol imap { protocol imap {
mail_plugins = $mail_plugins imap_sieve mail_plugins = $mail_plugins imap_sieve
} }

View file

@ -21,8 +21,9 @@ compatibility_level = 2
#=== #===
# TLS parameters # TLS parameters
#=== #===
smtpd_tls_cert_file=/etc/ssl/certs/postfix.crt smtpd_tls_cert_file=/etc/ssl/postfix.crt
smtpd_tls_key_file=/etc/ssl/private/postfix.key smtpd_tls_key_file=/etc/ssl/postfix.key
smtpd_tls_dh1024_param_file=auto
smtpd_use_tls=yes smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

View file

@ -28,8 +28,14 @@ job "email" {
task "server" { task "server" {
driver = "docker" driver = "docker"
constraint {
attribute = "${attr.unique.hostname}"
operator = "="
value = "digitale"
}
config { config {
image = "superboum/amd64_dovecot:v2" image = "superboum/amd64_dovecot:v6"
readonly_rootfs = false readonly_rootfs = false
ports = [ "zauthentication_port", "imaps_port", "imap_port", "lmtp_port" ] ports = [ "zauthentication_port", "imaps_port", "imap_port", "lmtp_port" ]
command = "dovecot" command = "dovecot"
@ -37,8 +43,8 @@ job "email" {
volumes = [ volumes = [
"secrets/ssl/certs:/etc/ssl/certs", "secrets/ssl/certs:/etc/ssl/certs",
"secrets/ssl/private:/etc/ssl/private", "secrets/ssl/private:/etc/ssl/private",
"secrets/conf/dovecot-ldap.conf:/etc/dovecot/dovecot-ldap.conf", "secrets/conf/:/etc/dovecot/",
"/mnt/glusterfs/email/mail:/var/mail/", "/mnt/ssd/mail:/var/mail/",
] ]
} }
@ -135,15 +141,22 @@ job "email" {
destination = "secrets/conf/dovecot-ldap.conf" destination = "secrets/conf/dovecot-ldap.conf"
perms = "400" perms = "400"
} }
template {
data = file("../config/dovecot/dovecot.conf")
destination = "secrets/conf/dovecot.conf"
perms = "400"
}
# ----- secrets ------ # ----- secrets ------
template { template {
data = "{{ key \"secrets/email/dovecot/dovecot.crt\" }}" # data = "{{ key \"secrets/email/dovecot/dovecot.crt\" }}"
data = "{{ with $d := key \"tricot/certs/imap.deuxfleurs.fr\" | parseJSON }}{{ $d.cert_pem }}{{ end }}"
destination = "secrets/ssl/certs/dovecot.crt" destination = "secrets/ssl/certs/dovecot.crt"
perms = "400" perms = "400"
} }
template { template {
data = "{{ key \"secrets/email/dovecot/dovecot.key\" }}" # data = "{{ key \"secrets/email/dovecot/dovecot.key\" }}"
data = "{{ with $d := key \"tricot/certs/imap.deuxfleurs.fr\" | parseJSON }}{{ $d.key_pem }}{{ end }}"
destination = "secrets/ssl/private/dovecot.key" destination = "secrets/ssl/private/dovecot.key"
perms = "400" perms = "400"
} }
@ -248,8 +261,7 @@ job "email" {
command = "postfix" command = "postfix"
args = [ "start-fg" ] args = [ "start-fg" ]
volumes = [ volumes = [
"secrets/ssl/certs:/etc/ssl/certs", "secrets/ssl:/etc/ssl",
"secrets/ssl/private:/etc/ssl/private",
"secrets/postfix:/etc/postfix-conf", "secrets/postfix:/etc/postfix-conf",
"/dev/log:/dev/log" "/dev/log:/dev/log"
] ]
@ -370,14 +382,16 @@ job "email" {
# --- secrets --- # --- secrets ---
template { template {
data = "{{ key \"secrets/email/postfix/postfix.crt\" }}" # data = "{{ key \"secrets/email/postfix/postfix.crt\" }}"
destination = "secrets/ssl/certs/postfix.crt" data = "{{ with $d := key \"tricot/certs/smtp.deuxfleurs.fr\" | parseJSON }}{{ $d.cert_pem }}{{ end }}"
destination = "secrets/ssl/postfix.crt"
perms = "400" perms = "400"
} }
template { template {
data = "{{ key \"secrets/email/postfix/postfix.key\" }}" # data = "{{ key \"secrets/email/postfix/postfix.key\" }}"
destination = "secrets/ssl/private/postfix.key" data = "{{ with $d := key \"tricot/certs/smtp.deuxfleurs.fr\" | parseJSON }}{{ $d.key_pem }}{{ end }}"
destination = "secrets/ssl/postfix.key"
perms = "400" perms = "400"
} }
} }
@ -393,16 +407,21 @@ job "email" {
task "main" { task "main" {
driver = "docker" driver = "docker"
config { config {
image = "superboum/amd64_alps:v1" image = "lxpz/alps_amd64:v2"
readonly_rootfs = true readonly_rootfs = true
ports = [ "alps_web_port" ] ports = [ "alps_web_port" ]
command = "-theme" args = [
args = [ "alps", "imaps://imap.deuxfleurs.fr:993", "smtps://smtp.deuxfleurs.fr:465" ] "-skiptlsverification",
"-theme",
"alps",
"imaps://imap.deuxfleurs.fr:993",
"smtps://smtp.deuxfleurs.fr:465"
]
} }
resources { resources {
cpu = 50 cpu = 100
memory = 40 memory = 100
} }
service { service {
@ -413,7 +432,8 @@ job "email" {
"alps", "alps",
"traefik.enable=true", "traefik.enable=true",
"traefik.frontend.entryPoints=https,http", "traefik.frontend.entryPoints=https,http",
"traefik.frontend.rule=Host:alps.deuxfleurs.fr" "traefik.frontend.rule=Host:alps.deuxfleurs.fr",
"tricot alps.deuxfleurs.fr",
] ]
check { check {
type = "tcp" type = "tcp"
@ -467,7 +487,9 @@ job "email" {
"sogo", "sogo",
"traefik.enable=true", "traefik.enable=true",
"traefik.frontend.entryPoints=https,http", "traefik.frontend.entryPoints=https,http",
"traefik.frontend.rule=Host:www.sogo.deuxfleurs.fr,sogo.deuxfleurs.fr;PathPrefix:/" "traefik.frontend.rule=Host:www.sogo.deuxfleurs.fr,sogo.deuxfleurs.fr;PathPrefix:/",
"tricot www.sogo.deuxfleurs.fr",
"tricot sogo.deuxfleurs.fr",
] ]
check { check {
type = "tcp" type = "tcp"

View file

@ -0,0 +1 @@
USER AWS Acces Key ID

View file

@ -0,0 +1 @@
USER AWS Secret Access key

View file

@ -0,0 +1 @@
USER Restic backup password to encrypt data

View file

@ -0,0 +1 @@
USER Restic Repository URL, check op_guide/backup-minio to see the format

View file

@ -0,0 +1,60 @@
job "frontend" {
datacenters = ["dc1", "neptune"]
type = "service"
priority = 90
group "tricot" {
network {
port "http_port" { static = 80 }
port "https_port" { static = 443 }
}
task "server" {
driver = "docker"
config {
image = "lxpz/amd64_tricot:37"
network_mode = "host"
readonly_rootfs = true
ports = [ "http_port", "https_port" ]
}
resources {
cpu = 2000
memory = 500
}
restart {
interval = "30m"
attempts = 2
delay = "15s"
mode = "delay"
}
template {
data = <<EOH
TRICOT_NODE_NAME={{ env "attr.unique.hostname" }}
TRICOT_LETSENCRYPT_EMAIL=alex@adnab.me
TRICOT_ENABLE_COMPRESSION=true
RUST_LOG=tricot=debug
EOH
destination = "secrets/env"
env = true
}
service {
name = "tricot-http"
port = "http_port"
tags = [ "(diplonat (tcp_port 80))" ]
address_mode = "host"
}
service {
name = "tricot-https"
port = "https_port"
tags = [ "(diplonat (tcp_port 443))" ]
address_mode = "host"
}
}
}
}

View file

@ -1,30 +1,24 @@
block_size = 1048576 block_size = 1048576
metadata_dir = "/garage/meta" metadata_dir = "/meta"
data_dir = "/garage/data" data_dir = "/data"
replication_mode = "3"
rpc_bind_addr = "[::]:3901" rpc_bind_addr = "[::]:3901"
rpc_secret = "{{ key "secrets/garage/rpc_secret" | trimSpace }}"
consul_host = "consul.service.2.cluster.deuxfleurs.fr:8500" sled_cache_capacity = 536870912
consul_service_name = "garage-rpc" sled_sync_interval_ms = 10000
bootstrap_peers = []
max_concurrent_rpc_requests = 12
data_replication_factor = 3
meta_replication_factor = 3
meta_epidemic_fanout = 3
[rpc_tls]
ca_cert = "/garage/garage-ca.crt"
node_cert = "/garage/garage.crt"
node_key = "/garage/garage.key"
[s3_api] [s3_api]
s3_region = "garage" s3_region = "garage"
api_bind_addr = "[::]:3900" api_bind_addr = "[::]:3900"
root_domain = ".garage.deuxfleurs.fr"
[s3_web] [s3_web]
bind_addr = "[::]:3902" bind_addr = "[::]:3902"
root_domain = ".web.deuxfleurs.fr" root_domain = ".web.deuxfleurs.fr"
index = "index.html"
[admin]
api_bind_addr = "[::1]:3903"

View file

@ -1,7 +1,7 @@
job "garage" { job "garage" {
datacenters = ["dc1", "belair", "saturne"] datacenters = ["dc1", "saturne", "neptune"]
type = "system" type = "system"
priority = 40 priority = 80
constraint { constraint {
attribute = "${attr.cpu.arch}" attribute = "${attr.cpu.arch}"
@ -15,20 +15,28 @@ job "garage" {
port "web" { static = 3902 } port "web" { static = 3902 }
} }
update {
max_parallel = 1
min_healthy_time = "30s"
healthy_deadline = "5m"
}
task "server" { task "server" {
driver = "docker" driver = "docker"
config { config {
advertise_ipv6_address = true advertise_ipv6_address = true
image = "lxpz/garage_amd64:v0.1.1b" image = "dxflrs/amd64_garage:v0.7.1"
command = "/garage"
args = [ "server" ]
network_mode = "host" network_mode = "host"
volumes = [ volumes = [
"/mnt/storage/garage/data:/garage/data", "/mnt/storage/garage/data:/data",
"/mnt/ssd/garage/meta:/garage/meta", "/mnt/ssd/garage/meta:/meta",
"secrets/garage.toml:/garage/config.toml", "secrets/garage.toml:/etc/garage.toml",
"secrets/garage-ca.crt:/garage/garage-ca.crt",
"secrets/garage.crt:/garage/garage.crt",
"secrets/garage.key:/garage/garage.key",
] ]
logging {
type = "journald"
}
} }
template { template {
@ -36,31 +44,19 @@ job "garage" {
destination = "secrets/garage.toml" destination = "secrets/garage.toml"
} }
# --- secrets ---
template {
data = "{{ key \"secrets/garage/garage-ca.crt\" }}"
destination = "secrets/garage-ca.crt"
}
template {
data = "{{ key \"secrets/garage/garage.crt\" }}"
destination = "secrets/garage.crt"
}
template {
data = "{{ key \"secrets/garage/garage.key\" }}"
destination = "secrets/garage.key"
}
resources { resources {
memory = 500 memory = 1500
cpu = 1000 cpu = 1000
} }
kill_signal = "SIGINT"
kill_timeout = "20s"
service { service {
tags = [ tags = [
"garage_api", "garage_api",
"traefik.enable=true", "tricot garage.deuxfleurs.fr",
"traefik.frontend.entryPoints=https,http", "tricot *.garage.deuxfleurs.fr",
"traefik.frontend.rule=Host:garage.deuxfleurs.fr"
] ]
port = 3900 port = 3900
address_mode = "driver" address_mode = "driver"
@ -97,6 +93,39 @@ job "garage" {
} }
} }
} }
service {
tags = [
"garage-web",
"tricot * 1",
"tricot-add-header Content-Security-Policy default-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://code.jquery.com/; frame-ancestors 'self'",
"tricot-add-header Strict-Transport-Security max-age=63072000; includeSubDomains; preload",
"tricot-add-header X-Frame-Options SAMEORIGIN",
"tricot-add-header X-XSS-Protection 1; mode=block",
]
port = 3902
address_mode = "driver"
name = "garage-web"
check {
type = "tcp"
port = 3902
address_mode = "driver"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
}
restart {
interval = "30m"
attempts = 10
delay = "15s"
mode = "delay"
}
} }
} }
} }

View file

@ -1 +0,0 @@
USER_LONG garage-ca.crt (generated with Garage's genkeys.sh script)

View file

@ -1 +0,0 @@
USER_LONG garage-ca.key (generated with Garage's genkeys.sh script)

View file

@ -1 +0,0 @@
USER_LONG garage.crt (generated with Garage's genkeys.sh script)

View file

@ -1 +0,0 @@
USER_LONG garage.key (generated with Garage's genkeys.sh script)

View file

@ -0,0 +1 @@
CMD_ONCE openssl rand -hex 32

View file

@ -1,6 +1,7 @@
FROM amd64/debian:buster as builder FROM amd64/debian:buster as builder
ARG VERSION ARG VERSION
ARG S3_VERSION
RUN apt-get update && \ RUN apt-get update && \
apt-get -qq -y full-upgrade && \ apt-get -qq -y full-upgrade && \
apt-get install -y \ apt-get install -y \
@ -18,11 +19,14 @@ RUN apt-get update && \
# postgresql-dev \ # postgresql-dev \
libpq-dev \ libpq-dev \
virtualenv \ virtualenv \
libxslt1-dev && \ libxslt1-dev \
git && \
virtualenv /root/matrix-env -p /usr/bin/python3 && \ virtualenv /root/matrix-env -p /usr/bin/python3 && \
. /root/matrix-env/bin/activate && \ . /root/matrix-env/bin/activate && \
pip3 install \ pip3 install \
https://github.com/matrix-org/synapse/archive/v${VERSION}.tar.gz#egg=matrix-synapse[matrix-synapse-ldap3,postgres,resources.consent,saml2,url_preview] https://github.com/matrix-org/synapse/archive/v${VERSION}.tar.gz#egg=matrix-synapse[matrix-synapse-ldap3,postgres,resources.consent,saml2,url_preview] && \
pip3 install \
git+https://github.com/matrix-org/synapse-s3-storage-provider.git@${S3_VERSION}
FROM amd64/debian:buster FROM amd64/debian:buster
@ -42,6 +46,7 @@ RUN apt-get update && \
ENV LD_PRELOAD /usr/lib/x86_64-linux-gnu/libjemalloc.so.2 ENV LD_PRELOAD /usr/lib/x86_64-linux-gnu/libjemalloc.so.2
COPY --from=builder /root/matrix-env /root/matrix-env COPY --from=builder /root/matrix-env /root/matrix-env
COPY matrix-s3-async /usr/local/bin/matrix-s3-async
COPY entrypoint.sh /usr/local/bin/entrypoint COPY entrypoint.sh /usr/local/bin/entrypoint
ENTRYPOINT ["/usr/local/bin/entrypoint"] ENTRYPOINT ["/usr/local/bin/entrypoint"]

View file

@ -0,0 +1,16 @@
#!/bin/bash
cat > database.yaml <<EOF
user: $PG_USER
password: $PG_PASS
database: $PG_DB
host: $PG_HOST
port: $PG_PORT
EOF
while true; do
/root/matrix-env/bin/s3_media_upload update-db 0d
/root/matrix-env/bin/s3_media_upload --no-progress check-deleted /var/lib/matrix-synapse/media
/root/matrix-env/bin/s3_media_upload --no-progress upload /var/lib/matrix-synapse/media matrix --delete --endpoint-url https://garage.deuxfleurs.fr
sleep 600
done

View file

@ -1,133 +0,0 @@
# Homeserver details
homeserver:
# The address that this appservice can use to connect to the homeserver.
address: https://im.deuxfleurs.fr
# The domain of the homeserver (for MXIDs, etc).
domain: deuxfleurs.fr
# Whether or not to verify the SSL certificate of the homeserver.
# Only applies if address starts with https://
verify_ssl: true
# Application service host/registration related details
# Changing these values requires regeneration of the registration.
appservice:
# The address that the homeserver can use to connect to this appservice.
address: http://fb2mx.service.2.cluster.deuxfleurs.fr:29319
# The hostname and port where this appservice should listen.
hostname: 0.0.0.0
port: 29319
# The maximum body size of appservice API requests (from the homeserver) in mebibytes
# Usually 1 is enough, but on high-traffic bridges you might need to increase this to avoid 413s
max_body_size: 1
# The full URI to the database. SQLite and Postgres are fully supported.
# Other DBMSes supported by SQLAlchemy may or may not work.
# Format examples:
# SQLite: sqlite:///filename.db
# Postgres: postgres://username:password@hostname/dbname
database: '{{ key "secrets/chat/fb2mx/db_url" | trimSpace }}'
# The unique ID of this appservice.
id: facebook
# Username of the appservice bot.
bot_username: facebookbot
# Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty
# to leave display name/avatar as-is.
bot_displayname: Facebook bridge bot
bot_avatar: mxc://maunium.net/ddtNPZSKMNqaUzqrHuWvUADv
# Community ID for bridged users (changes registration file) and rooms.
# Must be created manually.
community_id: "+fbusers:deuxfleurs.fr"
# Authentication tokens for AS <-> HS communication. Autogenerated; do not modify.
as_token: '{{ key "secrets/chat/fb2mx/as_token" | trimSpace }}'
hs_token: '{{ key "secrets/chat/fb2mx/hs_token" | trimSpace }}'
# Bridge config
bridge:
# Localpart template of MXIDs for Facebook users.
# {userid} is replaced with the user ID of the Facebook user.
username_template: "facebook_{userid}"
# Localpart template for per-user room grouping community IDs.
# The bridge will create these communities and add all of the specific user's portals to the community.
# {localpart} is the MXID localpart and {server} is the MXID server part of the user.
#
# `facebook_{localpart}={server}` is a good value.
community_template: "facebook_{localpart}={server}"
# Displayname template for Facebook users.
# {displayname} is replaced with the display name of the Facebook user
# as defined below in displayname_preference.
# Keys available for displayname_preference are also available here.
displayname_template: "{displayname} (FB)"
# Available keys:
# "name" (full name)
# "first_name"
# "last_name"
# "nickname"
# "own_nickname" (user-specific!)
displayname_preference:
- name
# The prefix for commands. Only required in non-management rooms.
command_prefix: "!fb"
# Number of chats to sync (and create portals for) on startup/login.
# Maximum 20, set 0 to disable automatic syncing.
initial_chat_sync: 10
# Whether or not the Facebook users of logged in Matrix users should be
# invited to private chats when the user sends a message from another client.
invite_own_puppet_to_pm: false
# Whether or not to use /sync to get presence, read receipts and typing notifications when using
# your own Matrix account as the Matrix puppet for your Facebook account.
sync_with_custom_puppets: true
# Whether or not to bridge presence in both directions. Facebook allows users not to broadcast
# presence, but then it won't send other users' presence to the client.
presence: true
# Whether or not to update avatars when syncing all contacts at startup.
update_avatar_initial_sync: true
# Permissions for using the bridge.
# Permitted values:
# user - Use the bridge with puppeting.
# admin - Use and administrate the bridge.
# Permitted keys:
# * - All Matrix users
# domain - All users on that homeserver
# mxid - Specific user
permissions:
"deuxfleurs.fr": "user"
# Python logging configuration.
#
# See section 16.7.2 of the Python documentation for more info:
# https://docs.python.org/3.6/library/logging.config.html#configuration-dictionary-schema
logging:
version: 1
formatters:
colored:
(): mautrix_facebook.util.ColorFormatter
format: "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s"
normal:
format: "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s"
handlers:
file:
class: logging.handlers.RotatingFileHandler
formatter: normal
filename: ./mautrix-facebook.log
maxBytes: 10485760
backupCount: 10
console:
class: logging.StreamHandler
formatter: colored
loggers:
mau:
level: DEBUG
fbchat:
level: DEBUG
aiohttp:
level: INFO
root:
level: DEBUG
handlers: [file, console]

View file

@ -1,11 +0,0 @@
id: facebook
as_token: '{{ key "secrets/chat/fb2mx/as_token" | trimSpace }}'
hs_token: '{{ key "secrets/chat/fb2mx/hs_token" | trimSpace }}'
namespaces:
users:
- exclusive: true
regex: '@facebook_.+:deuxfleurs.fr'
group_id: '+fbusers:deuxfleurs.fr'
url: http://fb2mx.service.2.cluster.deuxfleurs.fr:29319
sender_localpart: facebookbot
rate_limited: false

View file

@ -59,7 +59,7 @@ listeners:
x_forwarded: false x_forwarded: false
resources: resources:
- names: [client] - names: [client, federation]
compress: true compress: true
- port: 8448 - port: 8448
@ -83,6 +83,7 @@ listeners:
# Database configuration # Database configuration
database: database:
name: psycopg2 name: psycopg2
allow_unsafe_locale: false
args: args:
user: {{ key "secrets/chat/synapse/postgres_user" | trimSpace }} user: {{ key "secrets/chat/synapse/postgres_user" | trimSpace }}
password: {{ key "secrets/chat/synapse/postgres_pwd" | trimSpace }} password: {{ key "secrets/chat/synapse/postgres_pwd" | trimSpace }}
@ -137,6 +138,29 @@ federation_rc_concurrent: 3
media_store_path: "/var/lib/matrix-synapse/media" media_store_path: "/var/lib/matrix-synapse/media"
uploads_path: "/var/lib/matrix-synapse/uploads" uploads_path: "/var/lib/matrix-synapse/uploads"
media_storage_providers:
- module: s3_storage_provider.S3StorageProviderBackend
store_local: True
store_remote: True
store_synchronous: True
config:
bucket: matrix
# All of the below options are optional, for use with non-AWS S3-like
# services, or to specify access tokens here instead of some external method.
region_name: garage
endpoint_url: https://garage.deuxfleurs.fr
access_key_id: {{ key "secrets/chat/synapse/s3_access_key" | trimSpace }}
secret_access_key: {{ key "secrets/chat/synapse/s3_secret_key" | trimSpace }}
# The object storage class used when uploading files to the bucket.
# Default is STANDARD.
#storage_class: "STANDARD_IA"
# The maximum number of concurrent threads which will be used to connect
# to S3. Each thread manages a single connection. Default is 40.
#
#threadpool_size: 20
# The largest allowed upload size in bytes # The largest allowed upload size in bytes
max_upload_size: "100M" max_upload_size: "100M"
@ -291,7 +315,7 @@ bcrypt_rounds: 12
# Allows users to register as guests without a password/email/etc, and # Allows users to register as guests without a password/email/etc, and
# participate in rooms hosted on this server which have been made # participate in rooms hosted on this server which have been made
# accessible to anonymous users. # accessible to anonymous users.
allow_guest_access: True allow_guest_access: False
# The list of identity servers trusted to verify third party # The list of identity servers trusted to verify third party
# identifiers by this server. # identifiers by this server.
@ -308,11 +332,38 @@ enable_metrics: False
## API Configuration ## ## API Configuration ##
# A list of event types that will be included in the room_invite_state # A list of event types that will be included in the room_invite_state
room_invite_state_types: #room_invite_state_types:
- "m.room.join_rules" # - "m.room.join_rules"
- "m.room.canonical_alias" # - "m.room.canonical_alias"
- "m.room.avatar" # - "m.room.avatar"
- "m.room.name" # - "m.room.name"
# Controls for the state that is shared with users who receive an invite
# to a room
#
room_prejoin_state:
# By default, the following state event types are shared with users who
# receive invites to the room:
#
# - m.room.join_rules
# - m.room.canonical_alias
# - m.room.avatar
# - m.room.encryption
# - m.room.name
# - m.room.create
#
# Uncomment the following to disable these defaults (so that only the event
# types listed in 'additional_event_types' are shared). Defaults to 'false'.
#
#disable_default_event_types: true
# Additional state event types to share with users when they are invited
# to a room.
#
# By default, this list is empty (so only the default event types are shared).
#
#additional_event_types:
# - org.example.custom.event.type
# A list of application service config file to use # A list of application service config file to use
@ -418,3 +469,21 @@ password_config:
report_stats: false report_stats: false
suppress_key_server_warning: true suppress_key_server_warning: true
enable_group_creation: true enable_group_creation: true
#experimental_features:
# spaces_enabled: true
presence:
enabled: false
limit_remote_rooms:
enabled: true
complexity: 3.0
complexity_error: "Ce salon de discussion a trop d'activité, le serveur n'est pas assez puissant pour le rejoindre. N'hésitez pas à remonter l'information à l'équipe technique, nous pourrons ajuster la limitation au besoin."
admins_can_join: false
retention:
enabled: true
# no default policy for now, this is intended.
# DO NOT ADD ONE BECAUSE THIS IS DANGEROUS AND WILL DELETE CONTENT WE WANT TO KEEP!
purge_jobs:
- interval: 1d

View file

@ -15,7 +15,7 @@ job "im" {
driver = "docker" driver = "docker"
config { config {
image = "particallydone/amd64_synapse:v41" image = "superboum/amd64_synapse:v53"
network_mode = "host" network_mode = "host"
readonly_rootfs = true readonly_rootfs = true
ports = [ "client_port", "federation_port" ] ports = [ "client_port", "federation_port" ]
@ -27,8 +27,8 @@ job "im" {
] ]
volumes = [ volumes = [
"secrets/conf:/etc/matrix-synapse", "secrets/conf:/etc/matrix-synapse",
"/mnt/glusterfs/chat/matrix/synapse/media:/var/lib/matrix-synapse/media", "/tmp/synapse-media:/var/lib/matrix-synapse/media",
"/mnt/glusterfs/chat/matrix/synapse/uploads:/var/lib/matrix-synapse/uploads", "/tmp/synapse-uploads:/var/lib/matrix-synapse/uploads",
"/tmp/synapse-logs:/var/log/matrix-synapse", "/tmp/synapse-logs:/var/log/matrix-synapse",
"/tmp/synapse:/tmp" "/tmp/synapse:/tmp"
] ]
@ -86,7 +86,7 @@ job "im" {
resources { resources {
cpu = 1000 cpu = 1000
memory = 4000 memory = 2000
} }
service { service {
@ -95,11 +95,10 @@ job "im" {
address_mode = "host" address_mode = "host"
tags = [ tags = [
"matrix", "matrix",
"traefik.enable=true", "tricot im.deuxfleurs.fr/_matrix 100",
"traefik.frontend.entryPoints=https", "tricot im.deuxfleurs.fr:443/_matrix 100",
"traefik.frontend.rule=Host:im.deuxfleurs.fr;PathPrefix:/_matrix", "tricot im.deuxfleurs.fr/_synapse 100",
"traefik.frontend.headers.customResponseHeaders=Access-Control-Allow-Origin: *", "tricot-add-header Access-Control-Allow-Origin *",
"traefik.frontend.priority=100"
] ]
check { check {
type = "tcp" type = "tcp"
@ -120,94 +119,49 @@ job "im" {
address_mode = "host" address_mode = "host"
tags = [ tags = [
"matrix", "matrix",
"traefik.enable=true", "tricot deuxfleurs.fr/_matrix 100",
"traefik.frontend.entryPoints=https", "tricot deuxfleurs.fr:443/_matrix 100",
"traefik.frontend.rule=Host:deuxfleurs.fr;PathPrefix:/_matrix",
"traefik.frontend.priority=100"
] ]
} }
} }
}
group "easybridge" {
count = 1
network { task "media-async-upload" {
port "api_port" {
static = 8321
to = 8321
}
port "web_port" { to = 8281 }
}
task "easybridge" {
driver = "docker" driver = "docker"
config { config {
image = "lxpz/easybridge_amd64:33" image = "superboum/amd64_synapse:v53"
ports = [ "api_port", "web_port" ] readonly_rootfs = true
command = "/usr/local/bin/matrix-s3-async"
work_dir = "/tmp"
volumes = [ volumes = [
"secrets/conf:/data" "/tmp/synapse-media:/var/lib/matrix-synapse/media",
"/tmp/synapse-uploads:/var/lib/matrix-synapse/uploads",
"/tmp/synapse:/tmp"
] ]
args = [ "./easybridge", "-config", "/data/config.json" ]
}
template {
data = file("../config/easybridge/registration.yaml.tpl")
destination = "secrets/conf/registration.yaml"
}
template {
data = file("../config/easybridge/config.json.tpl")
destination = "secrets/conf/config.json"
} }
resources { resources {
memory = 500 cpu = 100
cpu = 1000 memory = 200
} }
service { template {
name = "easybridge-api" data = <<EOH
tags = ["easybridge-api"] AWS_ACCESS_KEY_ID={{ key "secrets/chat/synapse/s3_access_key" | trimSpace }}
port = "api_port" AWS_SECRET_ACCESS_KEY={{ key "secrets/chat/synapse/s3_secret_key" | trimSpace }}
address_mode = "host" AWS_DEFAULT_REGION=garage
check { PG_USER={{ key "secrets/chat/synapse/postgres_user" | trimSpace }}
type = "tcp" PG_PASS={{ key "secrets/chat/synapse/postgres_pwd" | trimSpace }}
port = "api_port" PG_DB={{ key "secrets/chat/synapse/postgres_db" | trimSpace }}
interval = "60s" PG_HOST=psql-proxy.service.2.cluster.deuxfleurs.fr
timeout = "5s" PG_PORT=5432
check_restart { EOH
limit = 3 destination = "secrets/env"
grace = "90s" env = true
ignore_warnings = false
}
}
}
service {
name = "easybridge-web"
tags = [
"easybridge-web",
"traefik.enable=true",
"traefik.frontend.entryPoints=https,http",
"traefik.frontend.rule=Host:easybridge.deuxfleurs.fr",
]
port = "web_port"
address_mode = "host"
check {
type = "tcp"
port = "web_port"
interval = "60s"
timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
}
} }
} }
} }
group "riotweb" { group "riotweb" {
@ -220,7 +174,7 @@ job "im" {
task "server" { task "server" {
driver = "docker" driver = "docker"
config { config {
image = "particallydone/amd64_riotweb:v20" image = "superboum/amd64_riotweb:v30"
ports = [ "web_port" ] ports = [ "web_port" ]
volumes = [ volumes = [
"secrets/config.json:/srv/http/config.json" "secrets/config.json:/srv/http/config.json"
@ -239,10 +193,8 @@ job "im" {
service { service {
tags = [ tags = [
"webstatic", "webstatic",
"traefik.enable=true", "tricot im.deuxfleurs.fr 10",
"traefik.frontend.entryPoints=https", "tricot riot.deuxfleurs.fr 10",
"traefik.frontend.rule=Host:im.deuxfleurs.fr,riot.deuxfleurs.fr;PathPrefix:/",
"traefik.frontend.priority=10"
] ]
port = "web_port" port = "web_port"
address_mode = "host" address_mode = "host"

View file

@ -0,0 +1 @@
USER matrix

View file

@ -0,0 +1 @@
USER matrix

View file

@ -0,0 +1,91 @@
From 3da458fc04560e8ddd597f7910c4f53b714d58ab Mon Sep 17 00:00:00 2001
From: Quentin Dufour <quentin@dufour.io>
Date: Mon, 1 Feb 2021 06:53:21 +0100
Subject: [PATCH] Remove broken command line args parameters setting
---
src/main/java/org/jitsi/jicofo/Main.java | 61 ------------------------
1 file changed, 61 deletions(-)
diff --git a/src/main/java/org/jitsi/jicofo/Main.java b/src/main/java/org/jitsi/jicofo/Main.java
index 558d1b3..59e04bb 100644
--- a/src/main/java/org/jitsi/jicofo/Main.java
+++ b/src/main/java/org/jitsi/jicofo/Main.java
@@ -50,7 +50,6 @@ public static void main(String[] args)
logger.error("An uncaught exception occurred in thread=" + t, e));
setupMetaconfigLogger();
- setSystemProperties(args);
JitsiConfig.Companion.reloadNewConfig();
// Make sure that passwords are not printed by ConfigurationService
@@ -80,66 +79,6 @@ public static void main(String[] args)
JicofoServices.jicofoServicesSingleton = null;
}
- /**
- * Read the command line arguments and env variables, and set the corresponding system properties used for
- * configuration of the XMPP component and client connections.
- */
- private static void setSystemProperties(String[] args)
- throws ParseException
- {
- CmdLine cmdLine = new CmdLine();
-
- // We may end execution here if one of required arguments is missing
- cmdLine.parse(args);
-
- // XMPP host/domain
- String host;
- String componentDomain;
- // Try to get domain, can be null after this call(we'll fix that later)
- componentDomain = cmdLine.getOptionValue("domain");
- // Host name
- host = cmdLine.getOptionValue("--host", componentDomain == null ? "localhost" : componentDomain);
- // Try to fix component domain
- if (isBlank(componentDomain))
- {
- componentDomain = host;
- }
- if (componentDomain != null)
- {
- // For backward compat, the "--domain" command line argument controls the domain for the XMPP component
- // as well as XMPP client connection.
- System.setProperty(XmppClientConnectionConfig.legacyXmppDomainPropertyName, componentDomain);
- }
- if (host != null)
- {
- // For backward compat, the "--host" command line argument controls the hostname for the XMPP component
- // as well as XMPP client connection.
- System.setProperty(XmppClientConnectionConfig.legacyHostnamePropertyName, host);
- }
-
- // XMPP client connection
- String focusDomain = cmdLine.getOptionValue("--user_domain");
- String focusUserName = cmdLine.getOptionValue("--user_name");
- String focusPassword = cmdLine.getOptionValue("--user_password");
- if (isBlank(focusPassword))
- {
- focusPassword = System.getenv("JICOFO_AUTH_PASSWORD");
- }
-
- if (focusDomain != null)
- {
- System.setProperty(XmppClientConnectionConfig.legacyDomainPropertyName, focusDomain);
- }
- if (focusUserName != null)
- {
- System.setProperty(XmppClientConnectionConfig.legacyUsernamePropertyName, focusUserName);
- }
- if (isNotBlank(focusPassword))
- {
- System.setProperty(XmppClientConnectionConfig.legacyPasswordPropertyName, focusPassword);
- }
- }
-
private static void setupMetaconfigLogger()
{
org.jitsi.utils.logging2.Logger configLogger = new org.jitsi.utils.logging2.LoggerImpl("org.jitsi.config");
--
2.25.1

View file

@ -1,18 +1,21 @@
FROM fedora:33 AS builder FROM debian:bookworm AS builder
RUN dnf install -y java-latest-openjdk-headless maven wget unzip # unzip is required when executing the mvn package command
RUN apt-get update && \
apt-get install -y openjdk-11-jdk-headless maven git unzip
ARG PREFIXV ARG JICOFO_TAG
ARG VERSION RUN git clone --depth 1 --branch $JICOFO_TAG https://github.com/jitsi/jicofo
RUN wget https://github.com/jitsi/jicofo/archive/${PREFIXV}${VERSION}.zip -O jicofo.zip
RUN unzip jicofo.zip && \ WORKDIR jicofo
mv jicofo*${VERSION} jicofo && \ COPY *.patch .
cd jicofo && \ RUN git apply 0001-Remove-broken-command-line-args-parameters-setting.patch
mvn package -DskipTests -Dassembly.skipAssembly=false && \ RUN mvn package -DskipTests -Dassembly.skipAssembly=false
unzip target/jicofo-1.1-SNAPSHOT-archive.zip && \
RUN unzip target/jicofo-1.1-SNAPSHOT-archive.zip && \
mv jicofo-1.1-SNAPSHOT /srv/build mv jicofo-1.1-SNAPSHOT /srv/build
FROM debian:bullseye FROM debian:bookworm
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y openjdk-11-jre-headless ca-certificates apt-get install -y openjdk-11-jre-headless ca-certificates

View file

@ -3,9 +3,7 @@
update-ca-certificates -f update-ca-certificates -f
exec java \ exec java \
-Xmx400m \ -Dlog4j2.formatMsgNoLookups=true \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/tmp \
-Djdk.tls.ephemeralDHKeySize=2048 \ -Djdk.tls.ephemeralDHKeySize=2048 \
-Djava.util.logging.config.file=/usr/share/jicofo/lib/logging.properties \ -Djava.util.logging.config.file=/usr/share/jicofo/lib/logging.properties \
-Dconfig.file=/etc/jitsi/jicofo.conf \ -Dconfig.file=/etc/jitsi/jicofo.conf \

View file

@ -1,28 +1,23 @@
FROM debian:buster AS builder FROM debian:bookworm AS builder
ARG PREFIXV
ARG VERSION
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y curl && \ apt-get install -y curl && \
curl -sL https://deb.nodesource.com/setup_14.x | bash - && \ curl -sL https://deb.nodesource.com/setup_16.x | bash - && \
apt-get install -y git nodejs make wget unzip && \ apt-get install -y git nodejs make git unzip
wget https://github.com/jitsi/jitsi-meet/archive/${PREFIXV}${VERSION}.zip -O jitsi-meet.zip
RUN unzip jitsi-meet.zip && \ ARG MEET_TAG
mv jitsi-meet-*${VERSION} jitsi-meet && \ RUN git clone --depth 1 --branch ${MEET_TAG} https://github.com/jitsi/jitsi-meet
cd jitsi-meet && \
npm install && \ WORKDIR jitsi-meet
RUN npm install && \
make make
FROM debian:buster FROM debian:bookworm
COPY --from=builder /jitsi-meet /srv/jitsi-meet COPY --from=builder /jitsi-meet /srv/jitsi-meet
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y nginx && \ apt-get install -y nginx && \
rm /etc/nginx/sites-enabled/* rm /etc/nginx/sites-enabled/* && \
rm /etc/nginx/nginx.conf
COPY config.js /srv/jitsi-meet/config.js
COPY entrypoint.sh /usr/local/bin/entrypoint
ENTRYPOINT ["/usr/local/bin/entrypoint"]
CMD ["/usr/sbin/nginx", "-g", "daemon off;"] CMD ["/usr/sbin/nginx", "-g", "daemon off;"]

View file

@ -1,517 +0,0 @@
/* eslint-disable no-unused-vars, no-var */
var config = {
// Connection
//
hosts: {
// XMPP domain.
domain: 'jitsi.deuxfleurs.fr',
// When using authentication, domain for guest users.
// anonymousdomain: 'guest.example.com',
// Domain for authenticated users. Defaults to <domain>.
// authdomain: 'jitsi-meet.example.com',
// Jirecon recording component domain.
// jirecon: 'jirecon.jitsi-meet.example.com',
// Call control component (Jigasi).
// call_control: 'callcontrol.jitsi-meet.example.com',
// Focus component domain. Defaults to focus.<domain>.
// focus: 'focus.jitsi-meet.example.com',
// XMPP MUC domain. FIXME: use XEP-0030 to discover it.
muc: 'conference.jitsi.deuxfleurs.fr'
},
// BOSH URL. FIXME: use XEP-0156 to discover it.
bosh: '//jitsi.deuxfleurs.fr/http-bind',
// Websocket URL
// websocket: 'wss://jitsi-meet.example.com/xmpp-websocket',
// The name of client node advertised in XEP-0115 'c' stanza
clientNode: 'http://jitsi.org/jitsimeet',
// The real JID of focus participant - can be overridden here
// focusUserJid: 'focus@auth.jitsi-meet.example.com',
// Testing / experimental features.
//
testing: {
// Enables experimental simulcast support on Firefox.
enableFirefoxSimulcast: false,
// P2P test mode disables automatic switching to P2P when there are 2
// participants in the conference.
p2pTestMode: false
// Enables the test specific features consumed by jitsi-meet-torture
// testMode: false
// Disables the auto-play behavior of *all* newly created video element.
// This is useful when the client runs on a host with limited resources.
// noAutoPlayVideo: false
},
// Disables ICE/UDP by filtering out local and remote UDP candidates in
// signalling.
// webrtcIceUdpDisable: false,
// Disables ICE/TCP by filtering out local and remote TCP candidates in
// signalling.
// webrtcIceTcpDisable: false,
// Media
//
// Audio
// Disable measuring of audio levels.
// disableAudioLevels: false,
// audioLevelsInterval: 200,
// Enabling this will run the lib-jitsi-meet no audio detection module which
// will notify the user if the current selected microphone has no audio
// input and will suggest another valid device if one is present.
enableNoAudioDetection: true,
// Enabling this will run the lib-jitsi-meet noise detection module which will
// notify the user if there is noise, other than voice, coming from the current
// selected microphone. The purpose it to let the user know that the input could
// be potentially unpleasant for other meeting participants.
enableNoisyMicDetection: true,
// Start the conference in audio only mode (no video is being received nor
// sent).
// startAudioOnly: false,
// Every participant after the Nth will start audio muted.
// startAudioMuted: 10,
// Start calls with audio muted. Unlike the option above, this one is only
// applied locally. FIXME: having these 2 options is confusing.
// startWithAudioMuted: false,
// Enabling it (with #params) will disable local audio output of remote
// participants and to enable it back a reload is needed.
// startSilent: false
// Video
// Sets the preferred resolution (height) for local video. Defaults to 720.
resolution: 480,
// w3c spec-compliant video constraints to use for video capture. Currently
// used by browsers that return true from lib-jitsi-meet's
// util#browser#usesNewGumFlow. The constraints are independency from
// this config's resolution value. Defaults to requesting an ideal aspect
// ratio of 16:9 with an ideal resolution of 720.
constraints: {
video: {
aspectRatio: 16 / 9,
height: {
ideal: 480,
max: 720,
min: 240
}
}
},
// Enable / disable simulcast support.
// disableSimulcast: false,
// Enable / disable layer suspension. If enabled, endpoints whose HD
// layers are not in use will be suspended (no longer sent) until they
// are requested again.
// enableLayerSuspension: false,
// Every participant after the Nth will start video muted.
// startVideoMuted: 10,
// Start calls with video muted. Unlike the option above, this one is only
// applied locally. FIXME: having these 2 options is confusing.
// startWithVideoMuted: false,
// If set to true, prefer to use the H.264 video codec (if supported).
// Note that it's not recommended to do this because simulcast is not
// supported when using H.264. For 1-to-1 calls this setting is enabled by
// default and can be toggled in the p2p section.
// preferH264: true,
// If set to true, disable H.264 video codec by stripping it out of the
// SDP.
// disableH264: false,
// Desktop sharing
// The ID of the jidesha extension for Chrome.
desktopSharingChromeExtId: null,
// Whether desktop sharing should be disabled on Chrome.
// desktopSharingChromeDisabled: false,
// The media sources to use when using screen sharing with the Chrome
// extension.
desktopSharingChromeSources: [ 'screen', 'window', 'tab' ],
// Required version of Chrome extension
desktopSharingChromeMinExtVersion: '0.1',
// Whether desktop sharing should be disabled on Firefox.
// desktopSharingFirefoxDisabled: false,
// Optional desktop sharing frame rate options. Default value: min:5, max:5.
// desktopSharingFrameRate: {
// min: 5,
// max: 5
// },
// Try to start calls with screen-sharing instead of camera video.
// startScreenSharing: false,
// Recording
// Whether to enable file recording or not.
// fileRecordingsEnabled: false,
// Enable the dropbox integration.
// dropbox: {
// appKey: '<APP_KEY>' // Specify your app key here.
// // A URL to redirect the user to, after authenticating
// // by default uses:
// // 'https://jitsi-meet.example.com/static/oauth.html'
// redirectURI:
// 'https://jitsi-meet.example.com/subfolder/static/oauth.html'
// },
// When integrations like dropbox are enabled only that will be shown,
// by enabling fileRecordingsServiceEnabled, we show both the integrations
// and the generic recording service (its configuration and storage type
// depends on jibri configuration)
// fileRecordingsServiceEnabled: false,
// Whether to show the possibility to share file recording with other people
// (e.g. meeting participants), based on the actual implementation
// on the backend.
// fileRecordingsServiceSharingEnabled: false,
// Whether to enable live streaming or not.
// liveStreamingEnabled: false,
// Transcription (in interface_config,
// subtitles and buttons can be configured)
// transcribingEnabled: false,
// Enables automatic turning on captions when recording is started
// autoCaptionOnRecord: false,
// Misc
// Default value for the channel "last N" attribute. -1 for unlimited.
channelLastN: -1,
// Disables or enables RTX (RFC 4588) (defaults to false).
// disableRtx: false,
// Disables or enables TCC (the default is in Jicofo and set to true)
// (draft-holmer-rmcat-transport-wide-cc-extensions-01). This setting
// affects congestion control, it practically enables send-side bandwidth
// estimations.
// enableTcc: true,
// Disables or enables REMB (the default is in Jicofo and set to false)
// (draft-alvestrand-rmcat-remb-03). This setting affects congestion
// control, it practically enables recv-side bandwidth estimations. When
// both TCC and REMB are enabled, TCC takes precedence. When both are
// disabled, then bandwidth estimations are disabled.
// enableRemb: false,
// Defines the minimum number of participants to start a call (the default
// is set in Jicofo and set to 2).
// minParticipants: 2,
// Use XEP-0215 to fetch STUN and TURN servers.
// useStunTurn: true,
// Enable IPv6 support.
// useIPv6: true,
// Enables / disables a data communication channel with the Videobridge.
// Values can be 'datachannel', 'websocket', true (treat it as
// 'datachannel'), undefined (treat it as 'datachannel') and false (don't
// open any channel).
// openBridgeChannel: true,
// UI
//
// Use display name as XMPP nickname.
// useNicks: false,
// Require users to always specify a display name.
// requireDisplayName: true,
// Whether to use a welcome page or not. In case it's false a random room
// will be joined when no room is specified.
enableWelcomePage: true,
// Enabling the close page will ignore the welcome page redirection when
// a call is hangup.
// enableClosePage: false,
// Disable hiding of remote thumbnails when in a 1-on-1 conference call.
// disable1On1Mode: false,
// Default language for the user interface.
defaultLanguage: 'fr',
// If true all users without a token will be considered guests and all users
// with token will be considered non-guests. Only guests will be allowed to
// edit their profile.
enableUserRolesBasedOnToken: false,
// Whether or not some features are checked based on token.
// enableFeaturesBasedOnToken: false,
// Enable lock room for all moderators, even when userRolesBasedOnToken is enabled and participants are guests.
// lockRoomGuestEnabled: false,
// When enabled the password used for locking a room is restricted to up to the number of digits specified
// roomPasswordNumberOfDigits: 10,
// default: roomPasswordNumberOfDigits: false,
// Message to show the users. Example: 'The service will be down for
// maintenance at 01:00 AM GMT,
// noticeMessage: '',
// Enables calendar integration, depends on googleApiApplicationClientID
// and microsoftApiApplicationClientID
// enableCalendarIntegration: false,
// Stats
//
// Whether to enable stats collection or not in the TraceablePeerConnection.
// This can be useful for debugging purposes (post-processing/analysis of
// the webrtc stats) as it is done in the jitsi-meet-torture bandwidth
// estimation tests.
// gatherStats: false,
// The interval at which PeerConnection.getStats() is called. Defaults to 10000
// pcStatsInterval: 10000,
// To enable sending statistics to callstats.io you must provide the
// Application ID and Secret.
// callStatsID: '',
// callStatsSecret: '',
// enables sending participants display name to callstats
// enableDisplayNameInStats: false
// enables sending participants email if available to callstats and other analytics
// enableEmailInStats: false
// Privacy
//
// If third party requests are disabled, no other server will be contacted.
// This means avatars will be locally generated and callstats integration
// will not function.
// disableThirdPartyRequests: false,
// Peer-To-Peer mode: used (if enabled) when there are just 2 participants.
//
p2p: {
// Enables peer to peer mode. When enabled the system will try to
// establish a direct connection when there are exactly 2 participants
// in the room. If that succeeds the conference will stop sending data
// through the JVB and use the peer to peer connection instead. When a
// 3rd participant joins the conference will be moved back to the JVB
// connection.
enabled: true,
// Use XEP-0215 to fetch STUN and TURN servers.
// useStunTurn: true,
// The STUN servers that will be used in the peer to peer connections
stunServers: [
// { urls: 'stun:jitsi-meet.example.com:443' },
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'stun:stun1.l.google.com:19302' },
{ urls: 'stun:stun2.l.google.com:19302' }
],
// Sets the ICE transport policy for the p2p connection. At the time
// of this writing the list of possible values are 'all' and 'relay',
// but that is subject to change in the future. The enum is defined in
// the WebRTC standard:
// https://www.w3.org/TR/webrtc/#rtcicetransportpolicy-enum.
// If not set, the effective value is 'all'.
// iceTransportPolicy: 'all',
// If set to true, it will prefer to use H.264 for P2P calls (if H.264
// is supported).
preferH264: true,
// If set to true, disable H.264 video codec by stripping it out of the
// SDP.
// disableH264: false,
// How long we're going to wait, before going back to P2P after the 3rd
// participant has left the conference (to filter out page reload).
backToP2PDelay: 60
},
analytics: {
// The Google Analytics Tracking ID:
// googleAnalyticsTrackingId: 'your-tracking-id-UA-123456-1'
// The Amplitude APP Key:
// amplitudeAPPKey: '<APP_KEY>'
// Array of script URLs to load as lib-jitsi-meet "analytics handlers".
// scriptURLs: [
// "libs/analytics-ga.min.js", // google-analytics
// "https://example.com/my-custom-analytics.js"
// ],
},
// Information about the jitsi-meet instance we are connecting to, including
// the user region as seen by the server.
deploymentInfo: {
// shard: "shard1",
// region: "europe",
// userRegion: "asia"
}
// Information for the chrome extension banner
// chromeExtensionBanner: {
// // The chrome extension to be installed address
// url: 'https://chrome.google.com/webstore/detail/jitsi-meetings/kglhbbefdnlheedjiejgomgmfplipfeb',
// // Extensions info which allows checking if they are installed or not
// chromeExtensionsInfo: [
// {
// id: 'kglhbbefdnlheedjiejgomgmfplipfeb',
// path: 'jitsi-logo-48x48.png'
// }
// ]
// }
// Local Recording
//
// localRecording: {
// Enables local recording.
// Additionally, 'localrecording' (all lowercase) needs to be added to
// TOOLBAR_BUTTONS in interface_config.js for the Local Recording
// button to show up on the toolbar.
//
// enabled: true,
//
// The recording format, can be one of 'ogg', 'flac' or 'wav'.
// format: 'flac'
//
// }
// Options related to end-to-end (participant to participant) ping.
// e2eping: {
// // The interval in milliseconds at which pings will be sent.
// // Defaults to 10000, set to <= 0 to disable.
// pingInterval: 10000,
//
// // The interval in milliseconds at which analytics events
// // with the measured RTT will be sent. Defaults to 60000, set
// // to <= 0 to disable.
// analyticsInterval: 60000,
// }
// If set, will attempt to use the provided video input device label when
// triggering a screenshare, instead of proceeding through the normal flow
// for obtaining a desktop stream.
// NOTE: This option is experimental and is currently intended for internal
// use only.
// _desktopSharingSourceDevice: 'sample-id-or-label'
// If true, any checks to handoff to another application will be prevented
// and instead the app will continue to display in the current browser.
// disableDeepLinking: false
// A property to disable the right click context menu for localVideo
// the menu has option to flip the locally seen video for local presentations
// disableLocalVideoFlip: false
// Deployment specific URLs.
// deploymentUrls: {
// // If specified a 'Help' button will be displayed in the overflow menu with a link to the specified URL for
// // user documentation.
// userDocumentationURL: 'https://docs.example.com/video-meetings.html',
// // If specified a 'Download our apps' button will be displayed in the overflow menu with a link
// // to the specified URL for an app download page.
// downloadAppsUrl: 'https://docs.example.com/our-apps.html'
// }
// List of undocumented settings used in jitsi-meet
/**
_immediateReloadThreshold
autoRecord
autoRecordToken
debug
debugAudioLevels
deploymentInfo
dialInConfCodeUrl
dialInNumbersUrl
dialOutAuthUrl
dialOutCodesUrl
disableRemoteControl
displayJids
etherpad_base
externalConnectUrl
firefox_fake_device
googleApiApplicationClientID
iAmRecorder
iAmSipGateway
microsoftApiApplicationClientID
peopleSearchQueryTypes
peopleSearchUrl
requireDisplayName
tokenAuthUrl
*/
// List of undocumented settings used in lib-jitsi-meet
/**
_peerConnStatusOutOfLastNTimeout
_peerConnStatusRtcMuteTimeout
abTesting
avgRtpStatsN
callStatsConfIDNamespace
callStatsCustomScriptUrl
desktopSharingSources
disableAEC
disableAGC
disableAP
disableHPF
disableNS
enableLipSync
enableTalkWhileMuted
forceJVB121Ratio
hiddenDomain
ignoreStartMuted
nick
startBitrate
*/
};
/* eslint-enable no-unused-vars, no-var */

View file

@ -1,38 +0,0 @@
#!/bin/bash
cat > /etc/nginx/sites-available/jitsi <<EOF
server_names_hash_bucket_size 64;
server {
listen 0.0.0.0:${NGINX_PORT} ssl http2 default_server;
listen [::]:${NGINX_PORT} ssl http2 default_server;
server_name _;
ssl_certificate ${JITSI_CERTS_FOLDER}/jitsi.deuxfleurs.fr.crt;
ssl_certificate_key ${JITSI_CERTS_FOLDER}/jitsi.deuxfleurs.fr.key;
root /srv/jitsi-meet;
index index.html;
location ~ ^/([a-zA-Z0-9=\?]+)$ {
rewrite ^/(.*)$ / break;
}
location / {
ssi on;
}
# BOSH, Bidirectional-streams Over Synchronous HTTP
# https://en.wikipedia.org/wiki/BOSH_(protocol)
location /http-bind {
proxy_pass http://${JITSI_PROSODY_BOSH_HOST}:${JITSI_PROSODY_BOSH_PORT}/http-bind;
proxy_set_header X-Forwarded-For \$remote_addr;
proxy_set_header Host \$http_host;
}
# external_api.js must be accessible from the root of the
# installation for the electron version of Jitsi Meet to work
# https://github.com/jitsi/jitsi-meet-electron
location /external_api.js {
alias /srv/jitsi-meet/libs/external_api.min.js;
}
}
EOF
ln -sf /etc/nginx/sites-available/jitsi /etc/nginx/sites-enabled/jitsi
exec "$@"

View file

@ -0,0 +1,40 @@
From 01507442620e5a57624c921b508eac7d572440d0 Mon Sep 17 00:00:00 2001
From: Quentin Dufour <quentin@deuxfleurs.fr>
Date: Tue, 25 Jan 2022 14:46:22 +0100
Subject: [PATCH] Remove deprecated argument
---
.../main/kotlin/org/jitsi/videobridge/Main.kt | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/jvb/src/main/kotlin/org/jitsi/videobridge/Main.kt b/jvb/src/main/kotlin/org/jitsi/videobridge/Main.kt
index 4f6cb78..3db00f2 100644
--- a/jvb/src/main/kotlin/org/jitsi/videobridge/Main.kt
+++ b/jvb/src/main/kotlin/org/jitsi/videobridge/Main.kt
@@ -52,23 +52,6 @@ import org.jitsi.videobridge.websocket.singleton as webSocketServiceSingleton
fun main(args: Array<String>) {
val logger = LoggerImpl("org.jitsi.videobridge.Main")
- // We only support command line arguments for backward compatibility. The --apis options is the last one supported,
- // and it is only used to enable/disable the REST API (XMPP is only controlled through the config files).
- // TODO: fully remove support for --apis
- CmdLine().apply {
- parse(args)
- getOptionValue("--apis")?.let {
- logger.warn(
- "A deprecated command line argument (--apis) is present. Please use the config file to control the " +
- "REST API instead (see rest.md). Support for --apis will be removed in a future version."
- )
- System.setProperty(
- Videobridge.REST_API_PNAME,
- it.contains(Videobridge.REST_API).toString()
- )
- }
- }
-
setupMetaconfigLogger()
setSystemPropertyDefaults()
--
2.33.1

View file

@ -1,30 +1,24 @@
FROM debian:buster AS builder FROM debian:bookworm AS builder
ARG PREFIXV
ARG VERSION
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y wget unzip maven openjdk-11-jdk && \ apt-get install -y git unzip maven openjdk-11-jdk-headless
wget https://github.com/jitsi/jitsi-videobridge/archive/${PREFIXV}${VERSION}.zip -O jvb.zip
RUN unzip jvb.zip && \ ARG JVB_TAG
mv jitsi-videobridge*${VERSION} jvb && \ RUN git clone --depth 1 --branch ${JVB_TAG} https://github.com/jitsi/jitsi-videobridge
cd jvb && \
mvn package -DskipTests && \ WORKDIR jitsi-videobridge
ls jvb/target && \ COPY *.patch .
unzip jvb/target/jitsi-videobridge*.zip && \ RUN git apply 0001-Remove-deprecated-argument.patch
RUN mvn package -DskipTests
RUN unzip jvb/target/jitsi-videobridge*.zip && \
mv jitsi-videobridge-*-SNAPSHOT build mv jitsi-videobridge-*-SNAPSHOT build
FROM debian:buster FROM debian:bookworm
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y openjdk-11-jre-headless apt-get install -y openjdk-11-jre-headless curl iproute2
COPY --from=builder /jvb/build /srv/jvb COPY --from=builder /jitsi-videobridge/build /usr/share/jvb
ENV HOME=/root
WORKDIR /root
COPY jvb_run /usr/local/bin/jvb_run COPY jvb_run /usr/local/bin/jvb_run
ENV JAVA_SYS_PROPS="-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/root -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=.sip-communicator -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jitsi"
CMD ["/usr/local/bin/jvb_run"] CMD ["/usr/local/bin/jvb_run"]

View file

@ -1,54 +1,22 @@
#!/bin/bash #!/bin/bash
update-ca-certificates -f
cat >> /etc/hosts <<EOF if [ -z "${JITSI_NAT_LOCAL_IP}" ]; then
${JITSI_PROSODY_HOST} jitsi.deuxfleurs.fr conference.jitsi.deuxfleurs.fr jitsi-videobridge.jitsi.deuxfleurs.fr focus.jitsi.deuxfleurs.fr auth.jitsi.deuxfleurs.fr JITSI_NAT_LOCAL_IP=$(ip route get $(ip route show 0.0.0.0/0 | grep -oP 'via \K\S+') | grep -oP 'src \K\S+')
127.0.0.1 `hostname` fi
EOF
mkdir -p /root/.sip-communicator if [ -z "${JITSI_NAT_PUBLIC_IP}" ]; then
JITSI_NAT_PUBLIC_IP=$(curl https://ifconfig.me)
fi
cat > /root/.sip-communicator/sip-communicator.properties <<EOF echo "NAT config: ${JITSI_NAT_LOCAL_IP} -> ${JITSI_NAT_PUBLIC_IP}"
# Enable broadcasting stats/presence in a MUC
org.jitsi.videobridge.ENABLE_STATISTICS=true
org.jitsi.videobridge.STATISTICS_TRANSPORT=muc
# Connect to the first XMPP server exec java \
org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=jitsi.deuxfleurs.fr -Dlog4j2.formatMsgNoLookups=true \
org.jitsi.videobridge.xmpp.user.shard.DOMAIN=auth.jitsi.deuxfleurs.fr -Djdk.tls.ephemeralDHKeySize=2048 \
org.jitsi.videobridge.xmpp.user.shard.USERNAME=jvb -Djava.util.logging.config.file=/usr/share/jvb/lib/logging.properties \
org.jitsi.videobridge.xmpp.user.shard.PASSWORD=${JITSI_SECRET_VIDEOBRIDGE} -Dconfig.file=/etc/jitsi/videobridge.conf \
org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=JvbBrewery@internal.auth.jitsi.deuxfleurs.fr -Dorg.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=${JITSI_NAT_LOCAL_IP} \
org.jitsi.videobridge.xmpp.user.shard.MUC=JvbBrewery@internal.auth.jitsi.deuxfleurs.fr -Dorg.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=${JITSI_NAT_PUBLIC_IP} \
org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME=singleton -cp '/usr/share/jvb/jitsi-videobridge.jar:/usr/share/jvb/lib/*' \
org.jitsi.videobridge.xmpp.user.shard.DISABLE_CERTIFICATE_VERIFICATION=true org.jitsi.videobridge.MainKt
# Do we need it? @FIXME
org.jitsi.impl.neomedia.transform.srtp.SRTPCryptoContext.checkReplay=false
# NAT things, two times just in case...
org.ice4j.ice.harvest.TCP_HARVESTER_PORT=${JITSI_VIDEO_TCP}
org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=${JITSI_NAT_LOCAL_IP}
org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=${JITSI_NAT_PUBLIC_IP}
org.jitsi.videobridge.TCP_HARVESTER_PORT=${JITSI_VIDEO_TCP}
org.jitsi.videobridge.NAT_HARVESTER_LOCAL_ADDRESS=${JITSI_NAT_LOCAL_IP}
org.jitsi.videobridge.NAT_HARVESTER_PUBLIC_ADDRESS=${JITSI_NAT_PUBLIC_IP}
org.jitsi.videobridge.DISABLE_TCP_HARVESTER=false
EOF
[ -v JITSI_DEBUG ] && cat >> /root/.sip-communicator/sip-communicator.properties <<EOF
net.java.sip.communicator.packetlogging.PACKET_LOGGING_ENABLED=true
net.java.sip.communicator.packetlogging.PACKET_LOGGING_ARBITRARY_ENABLED=true
net.java.sip.communicator.packetlogging.PACKET_LOGGING_SIP_ENABLED=true
net.java.sip.communicator.packetlogging.PACKET_LOGGING_JABBER_ENABLED=true
net.java.sip.communicator.packetlogging.PACKET_LOGGING_RTP_ENABLED=true
net.java.sip.communicator.packetlogging.PACKET_LOGGING_ICE4j_ENABLED=true
net.java.sip.communicator.packetlogging.PACKET_LOGGING_FILE_COUNT=1
net.java.sip.communicator.packetlogging.PACKET_LOGGING_FILE_SIZE=-1
EOF
/srv/jvb/jvb.sh \
--host=${JITSI_PROSODY_HOST} \
--domain=jitsi.deuxfleurs.fr \
--port=5347 \
--secret=${JITSI_SECRET_VIDEOBRIDGE} \
--apis=xmpp,rest

View file

@ -1,15 +1,12 @@
FROM debian:buster as builder FROM debian:bookworm as builder
WORKDIR /tmp
ARG MEET_VERSION
ARG PREFIXV
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y wget unzip apt-get install -y git unzip
RUN wget https://github.com/jitsi/jitsi-meet/archive/${PREFIXV}${MEET_VERSION}.zip -O meet.zip
RUN unzip meet.zip && \
mv jitsi-meet-* jitsi-meet
FROM debian:buster ARG MEET_TAG
RUN git clone --depth 1 --branch ${MEET_TAG} https://github.com/jitsi/jitsi-meet/
FROM debian:bookworm
ARG PROSODY_VERSION ARG PROSODY_VERSION
RUN apt-get update && \ RUN apt-get update && \
@ -30,7 +27,7 @@ RUN mkdir -p /usr/local/share/ca-certificates/ && \
mkdir -p /var/lib/prosody && \ mkdir -p /var/lib/prosody && \
chown -R prosody:prosody /var/lib/prosody /run/prosody chown -R prosody:prosody /var/lib/prosody /run/prosody
COPY --from=builder /tmp/jitsi-meet/resources/prosody-plugins /usr/share/jitsi-meet/prosody-plugins/ COPY --from=builder /jitsi-meet/resources/prosody-plugins /usr/share/jitsi-meet/prosody-plugins/
COPY xmpp_prosody /usr/local/bin/xmpp_prosody COPY xmpp_prosody /usr/local/bin/xmpp_prosody
WORKDIR /var/lib/prosody WORKDIR /var/lib/prosody

773
app/jitsi/config/config.js Normal file
View file

@ -0,0 +1,773 @@
/* eslint-disable no-unused-vars, no-var */
var config = {
// Connection
//
hosts: {
// XMPP domain.
domain: 'jitsi',
// When using authentication, domain for guest users.
// anonymousdomain: 'guest.example.com',
// Domain for authenticated users. Defaults to <domain>.
// authdomain: 'jitsi-meet.example.com',
// Focus component domain. Defaults to focus.<domain>.
// focus: 'focus.jitsi-meet.example.com',
// XMPP MUC domain. FIXME: use XEP-0030 to discover it.
muc: 'conference.jitsi'
},
// BOSH URL. FIXME: use XEP-0156 to discover it.
bosh: '//jitsi.deuxfleurs.fr/http-bind',
// Websocket URL
// websocket: 'wss://jitsi-meet.example.com/xmpp-websocket',
// The name of client node advertised in XEP-0115 'c' stanza
clientNode: 'http://jitsi.org/jitsimeet',
// The real JID of focus participant - can be overridden here
// Do not change username - FIXME: Make focus username configurable
// https://github.com/jitsi/jitsi-meet/issues/7376
// focusUserJid: 'focus@auth.jitsi-meet.example.com',
// Testing / experimental features.
//
testing: {
// Disables the End to End Encryption feature. Useful for debugging
// issues related to insertable streams.
// disableE2EE: false,
// P2P test mode disables automatic switching to P2P when there are 2
// participants in the conference.
p2pTestMode: false
// Enables the test specific features consumed by jitsi-meet-torture
// testMode: false
// Disables the auto-play behavior of *all* newly created video element.
// This is useful when the client runs on a host with limited resources.
// noAutoPlayVideo: false
// Enable / disable 500 Kbps bitrate cap on desktop tracks. When enabled,
// simulcast is turned off for the desktop share. If presenter is turned
// on while screensharing is in progress, the max bitrate is automatically
// adjusted to 2.5 Mbps. This takes a value between 0 and 1 which determines
// the probability for this to be enabled.
// capScreenshareBitrate: 1 // 0 to disable
// Enable callstats only for a percentage of users.
// This takes a value between 0 and 100 which determines the probability for
// the callstats to be enabled.
// callStatsThreshold: 5 // enable callstats for 5% of the users.
},
// Disables ICE/UDP by filtering out local and remote UDP candidates in
// signalling.
// webrtcIceUdpDisable: false,
// Disables ICE/TCP by filtering out local and remote TCP candidates in
// signalling.
// webrtcIceTcpDisable: false,
// Media
//
// Audio
// Disable measuring of audio levels.
// disableAudioLevels: false,
// audioLevelsInterval: 200,
// Enabling this will run the lib-jitsi-meet no audio detection module which
// will notify the user if the current selected microphone has no audio
// input and will suggest another valid device if one is present.
enableNoAudioDetection: true,
// Enabling this will show a "Save Logs" link in the GSM popover that can be
// used to collect debug information (XMPP IQs, SDP offer/answer cycles)
// about the call.
// enableSaveLogs: false,
// Enabling this will run the lib-jitsi-meet noise detection module which will
// notify the user if there is noise, other than voice, coming from the current
// selected microphone. The purpose it to let the user know that the input could
// be potentially unpleasant for other meeting participants.
enableNoisyMicDetection: false,
// Start the conference in audio only mode (no video is being received nor
// sent).
startAudioOnly: false,
// Every participant after the Nth will start audio muted.
startAudioMuted: 5,
// Start calls with audio muted. Unlike the option above, this one is only
// applied locally. FIXME: having these 2 options is confusing.
// startWithAudioMuted: false,
// Enabling it (with #params) will disable local audio output of remote
// participants and to enable it back a reload is needed.
// startSilent: false
// Sets the preferred target bitrate for the Opus audio codec by setting its
// 'maxaveragebitrate' parameter. Currently not available in p2p mode.
// Valid values are in the range 6000 to 510000
// opusMaxAverageBitrate: 20000,
// Enables support for opus-red (redundancy for Opus).
// enableOpusRed: false
// Video
// Sets the preferred resolution (height) for local video. Defaults to 720.
// resolution: 720,
// How many participants while in the tile view mode, before the receiving video quality is reduced from HD to SD.
// Use -1 to disable.
// maxFullResolutionParticipants: 2,
// w3c spec-compliant video constraints to use for video capture. Currently
// used by browsers that return true from lib-jitsi-meet's
// util#browser#usesNewGumFlow. The constraints are independent from
// this config's resolution value. Defaults to requesting an ideal
// resolution of 720p.
// constraints: {
// video: {
// height: {
// ideal: 720,
// max: 720,
// min: 240
// }
// }
// },
// Enable / disable simulcast support.
// disableSimulcast: false,
// Enable / disable layer suspension. If enabled, endpoints whose HD
// layers are not in use will be suspended (no longer sent) until they
// are requested again.
// enableLayerSuspension: false,
// Every participant after the Nth will start video muted.
startVideoMuted: 5,
// Start calls with video muted. Unlike the option above, this one is only
// applied locally. FIXME: having these 2 options is confusing.
// startWithVideoMuted: false,
// If set to true, prefer to use the H.264 video codec (if supported).
// Note that it's not recommended to do this because simulcast is not
// supported when using H.264. For 1-to-1 calls this setting is enabled by
// default and can be toggled in the p2p section.
// This option has been deprecated, use preferredCodec under videoQuality section instead.
// preferH264: true,
// If set to true, disable H.264 video codec by stripping it out of the
// SDP.
// disableH264: false,
// Desktop sharing
// Optional desktop sharing frame rate options. Default value: min:5, max:5.
// desktopSharingFrameRate: {
// min: 5,
// max: 5
// },
// Try to start calls with screen-sharing instead of camera video.
// startScreenSharing: false,
// Recording
// Whether to enable file recording or not.
// fileRecordingsEnabled: false,
// Enable the dropbox integration.
// dropbox: {
// appKey: '<APP_KEY>' // Specify your app key here.
// // A URL to redirect the user to, after authenticating
// // by default uses:
// // 'https://jitsi-meet.example.com/static/oauth.html'
// redirectURI:
// 'https://jitsi-meet.example.com/subfolder/static/oauth.html'
// },
// When integrations like dropbox are enabled only that will be shown,
// by enabling fileRecordingsServiceEnabled, we show both the integrations
// and the generic recording service (its configuration and storage type
// depends on jibri configuration)
// fileRecordingsServiceEnabled: false,
// Whether to show the possibility to share file recording with other people
// (e.g. meeting participants), based on the actual implementation
// on the backend.
// fileRecordingsServiceSharingEnabled: false,
// Whether to enable live streaming or not.
// liveStreamingEnabled: false,
// Transcription (in interface_config,
// subtitles and buttons can be configured)
// transcribingEnabled: false,
// Enables automatic turning on captions when recording is started
// autoCaptionOnRecord: false,
// Misc
// Default value for the channel "last N" attribute. -1 for unlimited.
channelLastN: -1,
// Provides a way to use different "last N" values based on the number of participants in the conference.
// The keys in an Object represent number of participants and the values are "last N" to be used when number of
// participants gets to or above the number.
//
// For the given example mapping, "last N" will be set to 20 as long as there are at least 5, but less than
// 29 participants in the call and it will be lowered to 15 when the 30th participant joins. The 'channelLastN'
// will be used as default until the first threshold is reached.
//
// lastNLimits: {
// 5: 20,
// 30: 15,
// 50: 10,
// 70: 5,
// 90: 2
// },
// Specify the settings for video quality optimizations on the client.
// videoQuality: {
// // Provides a way to prevent a video codec from being negotiated on the JVB connection. The codec specified
// // here will be removed from the list of codecs present in the SDP answer generated by the client. If the
// // same codec is specified for both the disabled and preferred option, the disable settings will prevail.
// // Note that 'VP8' cannot be disabled since it's a mandatory codec, the setting will be ignored in this case.
// disabledCodec: 'H264',
//
// // Provides a way to set a preferred video codec for the JVB connection. If 'H264' is specified here,
// // simulcast will be automatically disabled since JVB doesn't support H264 simulcast yet. This will only
// // rearrange the the preference order of the codecs in the SDP answer generated by the browser only if the
// // preferred codec specified here is present. Please ensure that the JVB offers the specified codec for this
// // to take effect.
// preferredCodec: 'VP8',
//
// // Provides a way to configure the maximum bitrates that will be enforced on the simulcast streams for
// // video tracks. The keys in the object represent the type of the stream (LD, SD or HD) and the values
// // are the max.bitrates to be set on that particular type of stream. The actual send may vary based on
// // the available bandwidth calculated by the browser, but it will be capped by the values specified here.
// // This is currently not implemented on app based clients on mobile.
// maxBitratesVideo: {
// low: 200000,
// standard: 500000,
// high: 1500000
// },
//
// // The options can be used to override default thresholds of video thumbnail heights corresponding to
// // the video quality levels used in the application. At the time of this writing the allowed levels are:
// // 'low' - for the low quality level (180p at the time of this writing)
// // 'standard' - for the medium quality level (360p)
// // 'high' - for the high quality level (720p)
// // The keys should be positive numbers which represent the minimal thumbnail height for the quality level.
// //
// // With the default config value below the application will use 'low' quality until the thumbnails are
// // at least 360 pixels tall. If the thumbnail height reaches 720 pixels then the application will switch to
// // the high quality.
// minHeightForQualityLvl: {
// 360: 'standard',
// 720: 'high'
// },
//
// // Provides a way to resize the desktop track to 720p (if it is greater than 720p) before creating a canvas
// // for the presenter mode (camera picture-in-picture mode with screenshare).
// resizeDesktopForPresenter: false
// },
// // Options for the recording limit notification.
// recordingLimit: {
//
// // The recording limit in minutes. Note: This number appears in the notification text
// // but doesn't enforce the actual recording time limit. This should be configured in
// // jibri!
// limit: 60,
//
// // The name of the app with unlimited recordings.
// appName: 'Unlimited recordings APP',
//
// // The URL of the app with unlimited recordings.
// appURL: 'https://unlimited.recordings.app.com/'
// },
// Disables or enables RTX (RFC 4588) (defaults to false).
// disableRtx: false,
// Disables or enables TCC support in this client (default: enabled).
// enableTcc: true,
// Disables or enables REMB support in this client (default: enabled).
// enableRemb: true,
// Enables ICE restart logic in LJM and displays the page reload overlay on
// ICE failure. Current disabled by default because it's causing issues with
// signaling when Octo is enabled. Also when we do an "ICE restart"(which is
// not a real ICE restart), the client maintains the TCC sequence number
// counter, but the bridge resets it. The bridge sends media packets with
// TCC sequence numbers starting from 0.
// enableIceRestart: false,
// Use TURN/UDP servers for the jitsi-videobridge connection (by default
// we filter out TURN/UDP because it is usually not needed since the
// bridge itself is reachable via UDP)
// useTurnUdp: false
// UI
//
// Disables responsive tiles.
// disableResponsiveTiles: false,
// Hides lobby button
// hideLobbyButton: false,
// Require users to always specify a display name.
// requireDisplayName: true,
// Whether to use a welcome page or not. In case it's false a random room
// will be joined when no room is specified.
enableWelcomePage: true,
// Disable app shortcuts that are registered upon joining a conference
// disableShortcuts: false,
// Disable initial browser getUserMedia requests.
// This is useful for scenarios where users might want to start a conference for screensharing only
// disableInitialGUM: false,
// Enabling the close page will ignore the welcome page redirection when
// a call is hangup.
// enableClosePage: false,
// Disable hiding of remote thumbnails when in a 1-on-1 conference call.
// disable1On1Mode: false,
// Default language for the user interface.
defaultLanguage: 'fr',
// Disables profile and the edit of all fields from the profile settings (display name and email)
// disableProfile: false,
// Whether or not some features are checked based on token.
// enableFeaturesBasedOnToken: false,
// When enabled the password used for locking a room is restricted to up to the number of digits specified
// roomPasswordNumberOfDigits: 10,
// default: roomPasswordNumberOfDigits: false,
// Message to show the users. Example: 'The service will be down for
// maintenance at 01:00 AM GMT,
// noticeMessage: '',
// Enables calendar integration, depends on googleApiApplicationClientID
// and microsoftApiApplicationClientID
// enableCalendarIntegration: false,
// When 'true', it shows an intermediate page before joining, where the user can configure their devices.
prejoinPageEnabled: true,
// If etherpad integration is enabled, setting this to true will
// automatically open the etherpad when a participant joins. This
// does not affect the mobile app since opening an etherpad
// obscures the conference controls -- it's better to let users
// choose to open the pad on their own in that case.
// openSharedDocumentOnJoin: false,
// If true, shows the unsafe room name warning label when a room name is
// deemed unsafe (due to the simplicity in the name) and a password is not
// set or the lobby is not enabled.
// enableInsecureRoomNameWarning: false,
// Whether to automatically copy invitation URL after creating a room.
// Document should be focused for this option to work
// enableAutomaticUrlCopy: false,
// Base URL for a Gravatar-compatible service. Defaults to libravatar.
// gravatarBaseURL: 'https://seccdn.libravatar.org/avatar/';
// Stats
//
// Whether to enable stats collection or not in the TraceablePeerConnection.
// This can be useful for debugging purposes (post-processing/analysis of
// the webrtc stats) as it is done in the jitsi-meet-torture bandwidth
// estimation tests.
// gatherStats: false,
// The interval at which PeerConnection.getStats() is called. Defaults to 10000
// pcStatsInterval: 10000,
// To enable sending statistics to callstats.io you must provide the
// Application ID and Secret.
// callStatsID: '',
// callStatsSecret: '',
// Enables sending participants' display names to callstats
// enableDisplayNameInStats: false,
// Enables sending participants' emails (if available) to callstats and other analytics
// enableEmailInStats: false,
// Privacy
//
// If third party requests are disabled, no other server will be contacted.
// This means avatars will be locally generated and callstats integration
// will not function.
// disableThirdPartyRequests: false,
// Peer-To-Peer mode: used (if enabled) when there are just 2 participants.
//
p2p: {
// Enables peer to peer mode. When enabled the system will try to
// establish a direct connection when there are exactly 2 participants
// in the room. If that succeeds the conference will stop sending data
// through the JVB and use the peer to peer connection instead. When a
// 3rd participant joins the conference will be moved back to the JVB
// connection.
enabled: true,
// The STUN servers that will be used in the peer to peer connections
stunServers: [
// { urls: 'stun:jitsi-meet.example.com:3478' },
{ urls: 'stun:meet-jit-si-turnrelay.jitsi.net:443' }
]
// Sets the ICE transport policy for the p2p connection. At the time
// of this writing the list of possible values are 'all' and 'relay',
// but that is subject to change in the future. The enum is defined in
// the WebRTC standard:
// https://www.w3.org/TR/webrtc/#rtcicetransportpolicy-enum.
// If not set, the effective value is 'all'.
// iceTransportPolicy: 'all',
// If set to true, it will prefer to use H.264 for P2P calls (if H.264
// is supported). This setting is deprecated, use preferredCodec instead.
// preferH264: true
// Provides a way to set the video codec preference on the p2p connection. Acceptable
// codec values are 'VP8', 'VP9' and 'H264'.
// preferredCodec: 'H264',
// If set to true, disable H.264 video codec by stripping it out of the
// SDP. This setting is deprecated, use disabledCodec instead.
// disableH264: false,
// Provides a way to prevent a video codec from being negotiated on the p2p connection.
// disabledCodec: '',
// How long we're going to wait, before going back to P2P after the 3rd
// participant has left the conference (to filter out page reload).
// backToP2PDelay: 5
},
analytics: {
// The Google Analytics Tracking ID:
// googleAnalyticsTrackingId: 'your-tracking-id-UA-123456-1'
// Matomo configuration:
// matomoEndpoint: 'https://your-matomo-endpoint/',
// matomoSiteID: '42',
// The Amplitude APP Key:
// amplitudeAPPKey: '<APP_KEY>'
// Configuration for the rtcstats server:
// By enabling rtcstats server every time a conference is joined the rtcstats
// module connects to the provided rtcstatsEndpoint and sends statistics regarding
// PeerConnection states along with getStats metrics polled at the specified
// interval.
// rtcstatsEnabled: true,
// In order to enable rtcstats one needs to provide a endpoint url.
// rtcstatsEndpoint: wss://rtcstats-server-pilot.jitsi.net/,
// The interval at which rtcstats will poll getStats, defaults to 1000ms.
// If the value is set to 0 getStats won't be polled and the rtcstats client
// will only send data related to RTCPeerConnection events.
// rtcstatsPolIInterval: 1000
// Array of script URLs to load as lib-jitsi-meet "analytics handlers".
// scriptURLs: [
// "libs/analytics-ga.min.js", // google-analytics
// "https://example.com/my-custom-analytics.js"
// ],
},
// Logs that should go be passed through the 'log' event if a handler is defined for it
// apiLogLevels: ['warn', 'log', 'error', 'info', 'debug'],
// Information about the jitsi-meet instance we are connecting to, including
// the user region as seen by the server.
deploymentInfo: {
// shard: "shard1",
// region: "europe",
// userRegion: "asia"
},
// Decides whether the start/stop recording audio notifications should play on record.
// disableRecordAudioNotification: false,
// Information for the chrome extension banner
// chromeExtensionBanner: {
// // The chrome extension to be installed address
// url: 'https://chrome.google.com/webstore/detail/jitsi-meetings/kglhbbefdnlheedjiejgomgmfplipfeb',
// // Extensions info which allows checking if they are installed or not
// chromeExtensionsInfo: [
// {
// id: 'kglhbbefdnlheedjiejgomgmfplipfeb',
// path: 'jitsi-logo-48x48.png'
// }
// ]
// },
// Local Recording
//
// localRecording: {
// Enables local recording.
// Additionally, 'localrecording' (all lowercase) needs to be added to
// TOOLBAR_BUTTONS in interface_config.js for the Local Recording
// button to show up on the toolbar.
//
// enabled: true,
//
// The recording format, can be one of 'ogg', 'flac' or 'wav'.
// format: 'flac'
//
// },
// Options related to end-to-end (participant to participant) ping.
// e2eping: {
// // The interval in milliseconds at which pings will be sent.
// // Defaults to 10000, set to <= 0 to disable.
// pingInterval: 10000,
//
// // The interval in milliseconds at which analytics events
// // with the measured RTT will be sent. Defaults to 60000, set
// // to <= 0 to disable.
// analyticsInterval: 60000,
// },
// If set, will attempt to use the provided video input device label when
// triggering a screenshare, instead of proceeding through the normal flow
// for obtaining a desktop stream.
// NOTE: This option is experimental and is currently intended for internal
// use only.
// _desktopSharingSourceDevice: 'sample-id-or-label',
// If true, any checks to handoff to another application will be prevented
// and instead the app will continue to display in the current browser.
// disableDeepLinking: false,
// A property to disable the right click context menu for localVideo
// the menu has option to flip the locally seen video for local presentations
// disableLocalVideoFlip: false,
// Mainly privacy related settings
// Disables all invite functions from the app (share, invite, dial out...etc)
// disableInviteFunctions: true,
// Disables storing the room name to the recents list
// doNotStoreRoom: true,
// Deployment specific URLs.
// deploymentUrls: {
// // If specified a 'Help' button will be displayed in the overflow menu with a link to the specified URL for
// // user documentation.
// userDocumentationURL: 'https://docs.example.com/video-meetings.html',
// // If specified a 'Download our apps' button will be displayed in the overflow menu with a link
// // to the specified URL for an app download page.
// downloadAppsUrl: 'https://docs.example.com/our-apps.html'
// },
// Options related to the remote participant menu.
// remoteVideoMenu: {
// // If set to true the 'Kick out' button will be disabled.
// disableKick: true
// },
// If set to true all muting operations of remote participants will be disabled.
// disableRemoteMute: true,
// Enables support for lip-sync for this client (if the browser supports it).
// enableLipSync: false
/**
External API url used to receive branding specific information.
If there is no url set or there are missing fields, the defaults are applied.
None of the fields are mandatory and the response must have the shape:
{
// The hex value for the colour used as background
backgroundColor: '#fff',
// The url for the image used as background
backgroundImageUrl: 'https://example.com/background-img.png',
// The anchor url used when clicking the logo image
logoClickUrl: 'https://example-company.org',
// The url used for the image used as logo
logoImageUrl: 'https://example.com/logo-img.png'
}
*/
// dynamicBrandingUrl: '',
// The URL of the moderated rooms microservice, if available. If it
// is present, a link to the service will be rendered on the welcome page,
// otherwise the app doesn't render it.
// moderatedRoomServiceUrl: 'https://moderated.jitsi-meet.example.com',
// If true, tile view will not be enabled automatically when the participants count threshold is reached.
// disableTileView: true,
// Hides the conference subject
// hideConferenceSubject: true
// Hides the conference timer.
// hideConferenceTimer: true,
// Hides the participants stats
// hideParticipantsStats: true
// Sets the conference subject
// subject: 'Conference Subject',
// List of undocumented settings used in jitsi-meet
/**
_immediateReloadThreshold
debug
debugAudioLevels
deploymentInfo
dialInConfCodeUrl
dialInNumbersUrl
dialOutAuthUrl
dialOutCodesUrl
disableRemoteControl
displayJids
etherpad_base
externalConnectUrl
firefox_fake_device
googleApiApplicationClientID
iAmRecorder
iAmSipGateway
microsoftApiApplicationClientID
peopleSearchQueryTypes
peopleSearchUrl
requireDisplayName
tokenAuthUrl
*/
/**
* This property can be used to alter the generated meeting invite links (in combination with a branding domain
* which is retrieved internally by jitsi meet) (e.g. https://meet.jit.si/someMeeting
* can become https://brandedDomain/roomAlias)
*/
// brandingRoomAlias: null,
// List of undocumented settings used in lib-jitsi-meet
/**
_peerConnStatusOutOfLastNTimeout
_peerConnStatusRtcMuteTimeout
abTesting
avgRtpStatsN
callStatsConfIDNamespace
callStatsCustomScriptUrl
desktopSharingSources
disableAEC
disableAGC
disableAP
disableHPF
disableNS
enableTalkWhileMuted
forceJVB121Ratio
forceTurnRelay
hiddenDomain
ignoreStartMuted
websocketKeepAlive
websocketKeepAliveUrl
*/
/**
Use this array to configure which notifications will be shown to the user
The items correspond to the title or description key of that notification
Some of these notifications also depend on some other internal logic to be displayed or not,
so adding them here will not ensure they will always be displayed
A falsy value for this prop will result in having all notifications enabled (e.g null, undefined, false)
*/
// notifications: [
// 'connection.CONNFAIL', // shown when the connection fails,
// 'dialog.cameraNotSendingData', // shown when there's no feed from user's camera
// 'dialog.kickTitle', // shown when user has been kicked
// 'dialog.liveStreaming', // livestreaming notifications (pending, on, off, limits)
// 'dialog.lockTitle', // shown when setting conference password fails
// 'dialog.maxUsersLimitReached', // shown when maximmum users limit has been reached
// 'dialog.micNotSendingData', // shown when user's mic is not sending any audio
// 'dialog.passwordNotSupportedTitle', // shown when setting conference password fails due to password format
// 'dialog.recording', // recording notifications (pending, on, off, limits)
// 'dialog.remoteControlTitle', // remote control notifications (allowed, denied, start, stop, error)
// 'dialog.reservationError',
// 'dialog.serviceUnavailable', // shown when server is not reachable
// 'dialog.sessTerminated', // shown when there is a failed conference session
// 'dialog.tokenAuthFailed', // show when an invalid jwt is used
// 'dialog.transcribing', // transcribing notifications (pending, off)
// 'dialOut.statusMessage', // shown when dial out status is updated.
// 'liveStreaming.busy', // shown when livestreaming service is busy
// 'liveStreaming.failedToStart', // shown when livestreaming fails to start
// 'liveStreaming.unavailableTitle', // shown when livestreaming service is not reachable
// 'lobby.joinRejectedMessage', // shown when while in a lobby, user's request to join is rejected
// 'lobby.notificationTitle', // shown when lobby is toggled and when join requests are allowed / denied
// 'localRecording.localRecording', // shown when a local recording is started
// 'notify.disconnected', // shown when a participant has left
// 'notify.grantedTo', // shown when moderator rights were granted to a participant
// 'notify.invitedOneMember', // shown when 1 participant has been invited
// 'notify.invitedThreePlusMembers', // shown when 3+ participants have been invited
// 'notify.invitedTwoMembers', // shown when 2 participants have been invited
// 'notify.kickParticipant', // shown when a participant is kicked
// 'notify.mutedRemotelyTitle', // shown when user is muted by a remote party
// 'notify.mutedTitle', // shown when user has been muted upon joining,
// 'notify.newDeviceAudioTitle', // prompts the user to use a newly detected audio device
// 'notify.newDeviceCameraTitle', // prompts the user to use a newly detected camera
// 'notify.passwordRemovedRemotely', // shown when a password has been removed remotely
// 'notify.passwordSetRemotely', // shown when a password has been set remotely
// 'notify.raisedHand', // shown when a partcipant used raise hand,
// 'notify.startSilentTitle', // shown when user joined with no audio
// 'prejoin.errorDialOut',
// 'prejoin.errorDialOutDisconnected',
// 'prejoin.errorDialOutFailed',
// 'prejoin.errorDialOutStatus',
// 'prejoin.errorStatusCode',
// 'prejoin.errorValidation',
// 'recording.busy', // shown when recording service is busy
// 'recording.failedToStart', // shown when recording fails to start
// 'recording.unavailableTitle', // shown when recording service is not reachable
// 'toolbar.noAudioSignalTitle', // shown when a broken mic is detected
// 'toolbar.noisyAudioInputTitle', // shown when noise is detected for the current microphone
// 'toolbar.talkWhileMutedPopup', // shown when user tries to speak while muted
// 'transcribing.failedToStart' // shown when transcribing fails to start
// ]
// Allow all above example options to include a trailing comma and
// prevent fear when commenting out the last value.
makeJsonParserHappy: 'even if last key had a trailing comma'
// no configuration value should follow this line.
};
/* eslint-enable no-unused-vars, no-var */

View file

@ -1,10 +0,0 @@
JITSI_SECRET_VIDEOBRIDGE={{ key "secrets/jitsi/jitsi_secret_videobridge" }}
JITSI_SECRET_JICOFO_COMPONENT={{ key "secrets/jitsi/jitsi_secret_jicofo_component" }}
JITSI_SECRET_JICOFO_USER={{ key "secrets/jitsi/jitsi_secret_jicofo_user" }}
JITSI_PROSODY_BOSH_PORT={{ env "NOMAD_PORT_bosh_port" }}
JITSI_PROSODY_BOSH_HOST=127.0.0.1
JITSI_PROSODY_HOST=127.0.0.1
JITSI_CERTS_FOLDER=/secrets/certs/
JITSI_NAT_PUBLIC_IP=78.197.205.190
JITSI_NAT_LOCAL_IP={{ env "NOMAD_IP_video1_port" }}
NGINX_PORT={{ env "NOMAD_PORT_https_port" }}

View file

@ -0,0 +1,273 @@
jicofo {
// Authentication with external services
authentication {
enabled = false
// The type of authentication. Supported values are XMPP, JWT or SHIBBOLETH (default).
type = SHIBBOLETH
// The pattern of authentication URL. See ShibbolethAuthAuthority for more information.
# login-url =
# logout-url =
authentication-lifetime = 24 hours
enable-auto-login = true
}
// Configuration related to jitsi-videobridge
bridge {
// The maximum number of participants in a single conference to put on one bridge (use -1 for no maximum).
max-bridge-participants = -1
// The assumed maximum packet rate that a bridge can handle.
max-bridge-packet-rate = 50000
// The assumed average packet rate per participant.
average-participant-packet-rate-pps = 500
// The assumed average stress per participant.
average-participant-stress = 0.01
// The assumed time that an endpoint takes to start contributing fully to the load on a bridge. To avoid allocating
// a burst of endpoints to the same bridge, the bridge stress is adjusted by adding the number of new endpoints
// in the last [participant-rampup-time] multiplied by [average-participant-stress].
participant-rampup-interval = 20 seconds
// The stress level above which a bridge is considered overstressed.
stress-threshold = 0.8
// The amount of to wait before retrying using a failed bridge.
failure-reset-threshold = 1 minute
// The bridge selection strategy. The built-in strategies are:
// SingleBridgeSelectionStrategy: Use the least loaded bridge, do not split a conference between bridges (Octo).
// SplitBridgeSelectionStrategy: Use a separate bridge for each participant (for testing).
// RegionBasedBridgeSelectionStrategy: Attempt to put each participant in a bridge in their local region (i.e. use
// Octo for geo-location).
// IntraRegionBridgeSelectionStrategy: Use additional bridges when a bridge becomes overloaded (i.e. use Octo for
// load balancing).
//
// Additionally, you can use the fully qualified class name for custom BridgeSelectionStrategy implementations.
selection-strategy = SingleBridgeSelectionStrategy
health-checks {
// Whether jicofo should perform periodic health checks to the connected bridges.
enabled = true
// The interval at which to perform health checks.
interval = 10 seconds
// When a health checks times out, jicofo will retry and only consider it fail after the retry fails. This
// configures the delay between the original health check timing out and the second health check being sent.
// It is a duration and defaults to half the [interval].
# retry-delay = 5 seconds
}
// The JID of the MUC to be used as a brewery for bridge instances.
brewery-jid = "jvbbrewery@internal.auth.jitsi"
}
// Configure the codecs and RTP extensions to be used in the offer sent to clients.
codec {
video {
vp8 {
enabled = true
pt = 100
// Payload type for the associated RTX stream. Set to -1 to disable RTX.
rtx-pt = 96
}
vp9 {
enabled = true
pt = 101
// Payload type for the associated RTX stream. Set to -1 to disable RTX.
rtx-pt = 97
}
h264 {
enabled = true
pt = 107
// Payload type for the associated RTX stream. Set to -1 to disable RTX.
rtx-pt = 99
}
}
audio {
isac-16000 {
enabled = true
pt = 103
}
isac-32000 {
enabled = true
pt = 104
}
opus {
enabled = true
pt = 111
minptime = 10
use-inband-fec = true
red {
enabled = false
pt = 112
}
}
telephone-event {
enabled = true
pt = 126
}
}
// RTP header extensions
rtp-extensions {
audio-level {
enabled = true
id = 1
}
tof {
// TOF is currently disabled, because we don't support it in the bridge
// (and currently clients seem to not use it when abs-send-time is
// available).
enabled = false
id = 2
}
abs-send-time {
enabled = true
id = 3
}
rid {
enabled = false
id = 4
}
tcc {
enabled = true
id = 5
}
video-content-type {
enabled = false
id = 7
}
framemarking {
enabled = false
id = 9
}
}
}
conference {
// Whether to automatically grant the 'owner' role to the first participant in the conference (and subsequently to
// the next in line when the current owner leaves).
enable-auto-owner = true
// How long to wait for the initial participant in a conference.
initial-timeout = 15 seconds
// Whether jicofo should inject a random SSRC for endpoints which don't advertise any SSRCs. This is a temporary
// workaround for an issue with signaling endpoints for Octo.
inject-ssrc-for-recv-only-endpoints = false
max-ssrcs-per-user = 20
// How long a participant's media session will be kept alive once it remains the only participant in the room.
single-participant-timeout = 20 seconds
// The minimum number of participants required for the conference to be started.
min-participants = 2
// Experimental.
enable-lip-sync = false
shared-document {
// If `true` the shared document uses a random name. Otherwise, it uses the conference name.
use-random-name = false
}
}
// Configuration for the internal health checks performed by jicofo.
health {
// Whether to perform health checks.
enabled = false
// The interval between health checks. If set to 0, periodic health checks will not be performed.
interval = 10 seconds
# The timeout for a health check
timeout = 30 seconds
# If performing a health check takes longer than this, it is considered unsuccessful.
max-check-duration = 20 seconds
# The prefix to use when creating MUC rooms for the purpose of health checks.
room-name-prefix = "__jicofo-health-check"
}
jibri {
// The JID of the MUC to be used as a brewery for jibri instances for streaming.
# brewery-jid = "jibribrewery@example.com"
// How many times to retry a given Jibri request before giving up. Set to -1 to allow infinite retries.
num-retries = 5
// How long to wait for Jibri to start recording from the time it accepts a START request.
pending-timeout = 90 seconds
}
jibri-sip {
// The JID of the MUC to be used as a brewery for jibri instances for SIP.
# brewery-jid = "jibrisipbrewery@example.com"
}
jigasi {
// The JID of the MUC to be used as a brewery for jigasi instances.
# brewery-jid = "jigasibrewery@example.com"
}
// The region in which the machine is running.
#local-region="us-east-1"
octo {
// Whether or not to use Octo. Note that when enabled, its use will be determined by
// $jicofo.bridge.selection-strategy.
enabled = false
// An identifier of the Jicofo instance, used for the purpose of generating conference IDs unique across a set of
// Jicofo instances. Valid values are [1, 65535]. The value 0 is used when none is explicitly configured.
id = 1
}
rest {
port = 8888
tls-port = 8843
}
sctp {
// Whether to allocate SCTP channels on the bridge (only when the client advertises support, and SCTP is
// enabled in the per-conference configuration).
enabled = true
}
task-pools {
shared-pool-max-threads = 1500
}
xmpp {
// The separate XMPP connection used for communication with clients (endpoints).
client {
enabled = true
hostname = "{{ env "NOMAD_IP_xmpp_port" }}"
port = {{ env "NOMAD_PORT_xmpp_port" }}
domain = "auth.jitsi"
username = "focus"
password = {{ key "secrets/jitsi/jicofo_pass" | trimSpace }}
// How long to wait for a response to a stanza before giving up.
reply-timeout = 15 seconds
// The JID/domain of the MUC service used for conferencing.
conference-muc-jid = conference.jitsi
// A flag to suppress the TLS certificate verification.
disable-certificate-verification = false
}
// The separate XMPP connection used for internal services (currently only jitsi-videobridge).
service {
enabled = false
hostname = "jitsi-xmpp"
port = 5222
domain = "auth.jitsi"
username = "focus"
password = "jicofopass"
// How long to wait for a response to a stanza before giving up.
reply-timeout = 15 seconds
// A flag to suppress the TLS certificate verification.
disable-certificate-verification = false
}
}
}

133
app/jitsi/config/nginx.conf Normal file
View file

@ -0,0 +1,133 @@
# some doc: https://www.nginx.com/resources/wiki/start/topics/examples/full/
error_log /dev/stderr info;
events {}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# mimetypes, required by jitsi!
include /etc/nginx/mime.types;
default_type application/octet-stream;
types {
application/wasm wasm;
}
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Gzip Settings
##
gzip on;
access_log /dev/stdout;
server_names_hash_bucket_size 64;
# inspired by https://raw.githubusercontent.com/jitsi/docker-jitsi-meet/master/web/rootfs/defaults/meet.conf
server {
#listen 0.0.0.0:{{ env "NOMAD_PORT_https_port" }} ssl http2 default_server;
#listen [::]:{{ env "NOMAD_PORT_https_port" }} ssl http2 default_server;
listen 0.0.0.0:{{ env "NOMAD_PORT_https_port" }} default_server;
listen [::]:{{ env "NOMAD_PORT_https_port" }} default_server;
client_max_body_size 0;
server_name _;
# ssi on with javascript for multidomain variables in config.js
ssi on;
ssi_types application/x-javascript application/javascript;
#ssl_certificate /etc/nginx/jitsi.crt;
#ssl_certificate_key /etc/nginx/jitsi.key;
root /srv/jitsi-meet;
index index.html;
error_page 404 /static/404.html;
location = /config.js {
alias /srv/jitsi-meet/config.js;
}
location = /interface_config.js {
alias /srv/jitsi-meet/interface_config.js;
}
location = /external_api.js {
alias /srv/jitsi-meet/libs/external_api.min.js;
}
# ensure all static content can always be found first
location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
{
add_header 'Access-Control-Allow-Origin' '*';
alias /srv/jitsi-meet/$1/$2;
}
# not used yet VVV
# colibri (JVB) websockets
#location ~ ^/colibri-ws/([a-zA-Z0-9-\.]+)/(.*) {
# proxy_pass http://$1:9090/colibri-ws/$1/$2$is_args$args;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# tcp_nodelay on;
#}
location = /http-bind {
# We add CORS to use a different frontend which is useful for load testing as we do not want to advertise too much our URL
add_header 'Access-Control-Allow-Headers' 'content-type';
add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,OPTIONS';
add_header 'Access-Control-Allow-Origin' '*';
proxy_pass http://{{ env "NOMAD_ADDR_bosh_port" }}/http-bind;
proxy_set_header X-Forwarded-For \$remote_addr;
#proxy_set_header Host \$http_host;
}
# not used yet VVV
# xmpp websockets
#location = /xmpp-websocket {
# proxy_pass {{ .Env.XMPP_BOSH_URL_BASE }}/xmpp-websocket;
# proxy_http_version 1.1;
# proxy_set_header Connection "upgrade";
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Host {{ .Env.XMPP_DOMAIN }};
# proxy_set_header X-Forwarded-For $remote_addr;
# tcp_nodelay on;
#}
location ~ ^/([^/?&:'"]+)$ {
try_files $uri @root_path;
}
location @root_path {
rewrite ^/(.*)$ / break;
}
# Not used yet VVVV
# Etherpad-lite
# location /etherpad/ {
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection 'upgrade';
# proxy_set_header Host $host;
# proxy_cache_bypass $http_upgrade;
# proxy_pass {{ .Env.ETHERPAD_URL_BASE }}/;
# proxy_set_header X-Forwarded-For $remote_addr;
# proxy_buffering off;
# proxy_set_header Host {{ .Env.XMPP_DOMAIN }};
# }
}
}

View file

@ -0,0 +1,135 @@
modules_enabled = {
"roster"; -- Allow users to have a roster. Recommended ;)
"saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
"tls"; -- Add support for secure TLS on c2s/s2s connections
"dialback"; -- s2s dialback support
"disco"; -- Service discovery
"posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
"version"; -- Replies to server version requests
"uptime"; -- Report how long server has been running
"time"; -- Let others know the time here on this server
"ping"; -- Replies to XMPP pings with pongs
"pep"; -- Enables users to publish their mood, activity, playing music and more
-- jitsi
--"smacks"; -- not shipped with prosody
"carbons";
"mam";
"lastactivity";
"offline";
"pubsub";
"adhoc";
"websocket";
--"http_altconnect"; -- not shipped with prosody
}
modules_disabled = { "s2s" }
plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }
log = {
--log less on console with warn="*console"; or err="*console" or more with debug="*console"
info="*console";
}
daemonize = false
use_libevent = true
-- domain mapper options, must at least have domain base set to use the mapper
muc_mapper_domain_base = "jitsi.deuxfleurs.fr";
--@FIXME would be great to configure it
--turncredentials_secret = "__turnSecret__";
--turncredentials = {
-- { type = "stun", host = "jitmeet.example.com", port = "3478" },
-- { type = "turn", host = "jitmeet.example.com", port = "3478", transport = "udp" },
-- { type = "turns", host = "jitmeet.example.com", port = "5349", transport = "tcp" }
--};
cross_domain_bosh = false;
consider_bosh_secure = true;
component_ports = { } -- it seems we don't need external components for now...
https_ports = { } -- we don't need https
http_ports = { {{env "NOMAD_PORT_bosh_port" }} }
c2s_ports = { {{env "NOMAD_PORT_xmpp_port" }} }
-- https://ssl-config.mozilla.org/#server=haproxy&version=2.1&config=intermediate&openssl=1.1.0g&guideline=5.4
ssl = {
protocol = "tlsv1_2+";
ciphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
}
VirtualHost "jitsi"
enabled = true -- Remove this line to enable this host
authentication = "anonymous"
-- Properties below are modified by jitsi-meet-tokens package config
-- and authentication above is switched to "token"
--app_id="example_app_id"
--app_secret="example_app_secret"
-- Assign this host a certificate for TLS, otherwise it would use the one
-- set in the global section (if any).
-- Note that old-style SSL on port 5223 only supports one certificate, and will always
-- use the global one.
ssl = {
key = "/var/lib/prosody/jitsi.key";
certificate = "/var/lib/prosody/jitsi.crt";
}
speakerstats_component = "speakerstats.jitsi"
conference_duration_component = "conferenceduration.jitsi"
-- we need bosh
modules_enabled = {
"bosh";
"pubsub";
"ping"; -- Enable mod_ping
"speakerstats";
--"turncredentials"; not supported yet
"conference_duration";
"muc_lobby_rooms";
}
c2s_require_encryption = false
lobby_muc = "lobby.jitsi"
main_muc = "conference.jitsi"
-- muc_lobby_whitelist = { "recorder.jitmeet.example.com" } -- Here we can whitelist jibri to enter lobby enabled rooms
Component "conference.jitsi" "muc"
storage = "memory"
modules_enabled = {
"muc_meeting_id";
"muc_domain_mapper";
--"token_verification";
}
admins = { "focus@auth.jitsi" }
muc_room_locking = false
muc_room_default_public_jids = true
-- internal muc component
Component "internal.auth.jitsi" "muc"
storage = "memory"
modules_enabled = {
"ping";
}
admins = { "focus@auth.jitsi", "jvb@auth.jitsi" }
muc_room_locking = false
muc_room_default_public_jids = true
VirtualHost "auth.jitsi"
ssl = {
key = "/var/lib/prosody/auth.jitsi.key";
certificate = "/var/lib/prosody/auth.jitsi.crt";
}
authentication = "internal_plain"
Component "focus.jitsi" "client_proxy"
target_address = "focus@auth.jitsi"
Component "speakerstats.jitsi" "speakerstats_component"
muc_component = "conference.jitsi"
Component "conferenceduration.jitsi" "conference_duration_component"
muc_component = "conference.jitsi"
Component "lobby.jitsi" "muc"
storage = "memory"
restrict_room_creation = true
muc_room_locking = false
muc_room_default_public_jids = true

View file

@ -0,0 +1,290 @@
videobridge {
entity-expiration {
# If an entity has no activity after this timeout, it is expired
timeout=1 minute
# The interval at which the videobridge will check for expired entities
check-interval=${videobridge.entity-expiration.timeout}
}
health {
# The interval between health checks
interval=10 seconds
# The timeout for a health check
timeout=30 seconds
# If performing a health check takes longer than this, it is considered unsuccessful.
max-check-duration=3 seconds
# Whether or not health check failures should be 'sticky'
# (i.e. once the bridge becomes unhealthy, it will never
# go back to a healthy state)
sticky-failures=false
}
ep-connection-status {
# How long we'll wait for an endpoint to *start* sending
# data before we consider it 'inactive'
first-transfer-timeout=15 seconds
# How long an endpoint can be 'inactive' before it will
# be considered disconnected
max-inactivity-limit=3 seconds
# How often we check endpoint's connectivity status
check-interval=500 milliseconds
}
cc {
bwe-change-threshold=0.15
thumbnail-max-height-px=180
onstage-ideal-height-px=1080
onstage-preferred-height-px=360
onstage-preferred-framerate=30
enable-onstage-video-suspend=false
trust-bwe=true
# How often we check to send probing data
padding-period=15ms
# How often we'll force recalculations of forwarded
# streams
max-time-between-calculations = 15 seconds
# A JVB-wide last-n value, observed by all endpoints. Endpoints
# will take the minimum of their setting and this one (-1 implies
# no last-n limit)
jvb-last-n = -1
}
# The APIs by which the JVB can be controlled
apis {
xmpp-client {
# The interval at which presence is published in the configured MUCs.
presence-interval = ${videobridge.stats.interval}
configs {
unique-xmpp-server {
hostname="{{ env "NOMAD_IP_xmpp_port" }}"
port = {{ env "NOMAD_PORT_xmpp_port" }}
domain = "auth.jitsi"
username = "jvb"
password = "{{ key "secrets/jitsi/jvb_pass" | trimSpace }}"
muc_jids = "jvbbrewery@internal.auth.jitsi"
# The muc_nickname must be unique across all jitsi-videobridge instances
muc_nickname = "unique-jvb-server"
disable_certificate_verification = false
}
# example-connection-id {
# For the properties which should be
# filled out here, see MucClientConfiguration
# }
}
}
# The COLIBRI REST API
rest {
enabled = true
}
jvb-api {
enabled = true
}
}
# Configuration of the different REST APIs.
# Note that the COLIBRI REST API is configured under videobridge.apis.rest instead.
rest {
debug {
enabled = true
}
health {
enabled = true
}
shutdown {
# Note that the shutdown API requires the COLIBRI API to also be enabled.
enabled = false
}
version {
enabled = true
}
}
http-servers {
# The HTTP server which hosts services intended for 'public' use
# (e.g. websockets for the bridge channel connection)
public {
# See JettyBundleActivatorConfig in Jicoco for values
port = -1
tls-port = -1
}
# The HTTP server which hosts services intended for 'private' use
# (e.g. health or debug stats)
private {
# See JettyBundleActivatorConfig in Jicoco for values
host = 127.0.0.1
}
}
octo {
# Whether or not Octo is enabled
enabled=false
# A string denoting the 'region' of this JVB. This region
# will be used by Jicofo in the selection of a bridge for
# a client by comparing it to the client's region.
# Must be set when 'enabled' is true
#region="us-west-1"
# The address on which the Octo relay should bind
# Must be set when 'enabled' is true
#bind-address=198.51.100.1
# The port to which the Octo relay should bind
bind-port=4096
# The address which controls the public address which
# will be part of the Octo relayId
#public-address=198.51.100.1
# The size of the incoming octo queue. This queue is per-remote-endpoint,
# so it matches what we use for local endpoints
recv-queue-size=1024
# The size of the outgoing octo queue. This is a per-originating-endpoint
# queue, so assuming all packets are routed (as they currently are for Octo)
# it should be the same size as the transceiver recv queue in
# jitsi-media-transform. Repeating the description from there:
# Assuming 300pps for high-definition, 200pps for standard-definition,
# 100pps for low-definition and 50pps for audio, this queue is fed
# 650pps, so its size in terms of millis is 1024/650*1000 ~= 1575ms.
send-queue-size=1024
}
load-management {
# Whether or not the reducer will be enabled to take actions to mitigate load
reducer-enabled = false
load-measurements {
packet-rate {
# The packet rate at which we'll consider the bridge overloaded
load-threshold = 50000
# The packet rate at which we'll consider the bridge 'underloaded' enough
# to start recovery
recovery-threshold = 40000
}
}
load-reducers {
last-n {
# The factor by which we'll reduce the current last-n when trying to reduce load
reduction-scale = .75
# The factor by which we'll increase the current last-n when trying to recover
recover-scale = 1.25
# The minimum time in between runs of the last-n reducer to reduce or recover from
# load
impact-time = 1 minute
# The lowest value we'll set for last-n
minimum-last-n-value = 0
# The highest last-n value we'll enforce. Once the enforced last-n exceeds this value
# we'll remove the limit entirely
maximum-enforced-last-n-value = 40
}
}
}
sctp {
# Whether SCTP data channels are enabled.
enabled=true
}
stats {
# Whether periodic collection of statistics is enabled or not. When enabled they are accessible through the REST
# API (at `/colibri/stats`), and are available to other modules (e.g. to be pushed to callstats or in a MUC).
enabled = true
# The interval at which stats are gathered.
interval = 5 seconds
# Configuration related to pushing statistics to callstats.io.
callstats {
# An integer application ID (use 0 to disable pushing stats to callstats).
app-id = 0
# The shared secred to authentication with callstats.io.
//app-secret = "s3cret"
# ID of the key that was used to generate token.
//key-id = "abcd"
# The path to private key file.
//key-path = "/etc/jitsi/videobridge/ecpriv.jwk"
# The ID of the server instance to be used when reporting to callstats.
bridge-id = "jitsi"
# TODO: document
//conference-id-prefix = "abcd"
# The interval at which statististics will be published to callstats. This affects both per-conference and global
# statistics.
# Note that this value will be overriden if a "callstatsio" transport is defined in the parent "stats" section.
interval = ${videobridge.stats.interval}
}
}
websockets {
enabled=false
server-id="default-id"
# Optional, even when 'enabled' is set to true
# tls=true
# Must be set when enabled = true
#domain="some-domain"
}
ice {
tcp {
# Whether ICE/TCP is enabled.
enabled = true
# The port to bind to for ICE/TCP.
port = {{ env "NOMAD_PORT_video_port" }}
# An optional additional port to advertise.
# mapped-port = 8443
# Whether to use "ssltcp" or plain "tcp".
ssltcp = true
}
udp {
# The port for ICE/UDP.
port = {{ env "NOMAD_PORT_video_port" }}
}
# An optional prefix to include in STUN username fragments generated by the bridge.
#ufrag-prefix = "jvb-123:"
# Which candidate pairs to keep alive. The accepted values are defined in ice4j's KeepAliveStrategy:
# "selected_and_tcp", "selected_only", or "all_succeeded".
keep-alive-strategy = "selected_and_tcp"
# Whether to use the "component socket" feature of ice4j.
use-component-socket = true
# Whether to attempt DNS resolution for remote candidates that contain a non-literal address. When set to 'false'
# such candidates will be ignored.
resolve-remote-candidates = false
# The nomination strategy to use for ICE. THe accepted values are defined in ice4j's NominationStrategy:
# "NominateFirstValid", "NominateHighestPriority", "NominateFirstHostOrReflexiveValid", or "NominateBestRTT".
nomination-strategy = "NominateFirstValid"
}
transport {
send {
# The size of the dtls-transport outgoing queue. This is a per-participant
# queue. Packets from the egress end-up in this queue right before
# transmission by the outgoing srtp pipeline (which mainly consists of the
# packet sender).
#
# Its size needs to be of the same order of magnitude as the rtp sender
# queue. In a 100 participant call, assuming 300pps for the on-stage and
# 100pps for low-definition, last-n 20 and 2 participants talking, so
# 2*50pps for audio, this queue is fed 300+19*100+2*50 = 2300pps, so its
# size in terms of millis is 1024/2300*1000 ~= 445ms.
queue-size=1024
}
}
version {
// Wheather to announe the jitsi-videobridge version to clients in the ServerHello message.
announce = false
}
}

View file

@ -2,6 +2,8 @@ job "jitsi" {
datacenters = ["dc1"] datacenters = ["dc1"]
type = "service" type = "service"
priority = "10"
constraint { constraint {
attribute = "${attr.cpu.arch}" attribute = "${attr.cpu.arch}"
value = "amd64" value = "amd64"
@ -11,46 +13,59 @@ job "jitsi" {
network { network {
port "bosh_port" { } port "bosh_port" { }
port "ext_port" { static = 5347 } port "xmpp_port" { }
port "xmpp_port" { static = 5222 }
port "https_port" { } port "https_port" { }
port "video1_port" { static = 8081 } port "video_port" { static = 8080 }
port "video2_port" { static = 10000 }
} }
task "xmpp" { task "xmpp" {
driver = "docker" driver = "docker"
config { config {
image = "superboum/amd64_jitsi_xmpp:v8" image = "superboum/amd64_jitsi_xmpp:v10"
ports = [ "bosh_port", "ext_port", "xmpp_port" ] ports = [ "bosh_port", "xmpp_port" ]
network_mode = "host" network_mode = "host"
volumes = [
"secrets/prosody.cfg.lua:/etc/prosody/prosody.cfg.lua",
"secrets/certs/auth.jitsi.crt:/var/lib/prosody/auth.jitsi.crt",
"secrets/certs/auth.jitsi.key:/var/lib/prosody/auth.jitsi.key",
"secrets/certs/jitsi.crt:/var/lib/prosody/jitsi.crt",
"secrets/certs/jitsi.key:/var/lib/prosody/jitsi.key"
]
} }
template { template {
data = file("../config/global_env.tpl") data = <<EOF
JICOFO_AUTH_PASSWORD={{ key "secrets/jitsi/jicofo_pass" | trimSpace }}
JVB_AUTH_PASSWORD={{ key "secrets/jitsi/jvb_pass" | trimSpace }}
EOF
destination = "secrets/global_env" destination = "secrets/global_env"
env = true env = true
} }
template {
data = file("../config/prosody.cfg.lua")
destination = "secrets/prosody.cfg.lua"
}
# --- secrets --- # --- secrets ---
template { template {
data = "{{ key \"secrets/jitsi/auth.jitsi.deuxfleurs.fr.crt\" }}" data = "{{ key \"secrets/jitsi/auth.jitsi.crt\" }}"
destination = "secrets/certs/auth.jitsi.deuxfleurs.fr.crt" destination = "secrets/certs/auth.jitsi.crt"
} }
template { template {
data = "{{ key \"secrets/jitsi/auth.jitsi.deuxfleurs.fr.key\" }}" data = "{{ key \"secrets/jitsi/auth.jitsi.key\" }}"
destination = "secrets/certs/auth.jitsi.deuxfleurs.fr.key" destination = "secrets/certs/auth.jitsi.key"
} }
template { template {
data = "{{ key \"secrets/jitsi/jitsi.deuxfleurs.fr.crt\" }}" data = "{{ key \"secrets/jitsi/jitsi.crt\" }}"
destination = "secrets/certs/jitsi.deuxfleurs.fr.crt" destination = "secrets/certs/jitsi.crt"
} }
template { template {
data = "{{ key \"secrets/jitsi/jitsi.deuxfleurs.fr.key\" }}" data = "{{ key \"secrets/jitsi/jitsi.key\" }}"
destination = "secrets/certs/jitsi.deuxfleurs.fr.key" destination = "secrets/certs/jitsi.key"
} }
resources { resources {
@ -62,7 +77,7 @@ job "jitsi" {
tags = [ "jitsi", "bosh" ] tags = [ "jitsi", "bosh" ]
port = "bosh_port" port = "bosh_port"
address_mode = "host" address_mode = "host"
name = "jitsi-xmpp-bosh" name = "bosh-jitsi"
check { check {
type = "tcp" type = "tcp"
port = "bosh_port" port = "bosh_port"
@ -76,43 +91,46 @@ job "jitsi" {
} }
} }
service {
tags = [ "jitsi", "ext" ]
port = "ext_port"
address_mode = "host"
name = "jitsi-ext"
}
service { service {
tags = [ "jitsi", "xmpp" ] tags = [ "jitsi", "xmpp" ]
port = "xmpp_port" port = "xmpp_port"
address_mode = "host" address_mode = "host"
name = "jitsi-xmpp" name = "xmpp-jitsi"
} }
} }
task "front" { task "front" {
driver = "docker" driver = "docker"
config { config {
image = "superboum/amd64_jitsi_meet:v3" image = "superboum/amd64_jitsi_meet:v5"
network_mode = "host" network_mode = "host"
ports = [ "https_port" ] ports = [ "https_port" ]
volumes = [
"secrets/certs/jitsi.crt:/etc/nginx/jitsi.crt",
"secrets/certs/jitsi.key:/etc/nginx/jitsi.key",
"secrets/config.js:/srv/jitsi-meet/config.js",
"secrets/nginx.conf:/etc/nginx/nginx.conf"
]
} }
template { template {
data = file("../config/global_env.tpl") data = file("../config/config.js")
destination = "secrets/global_env" destination = "secrets/config.js"
env = true }
template {
data = file("../config/nginx.conf")
destination = "secrets/nginx.conf"
} }
# --- secrets --- # --- secrets ---
template { template {
data = "{{ key \"secrets/jitsi/jitsi.deuxfleurs.fr.crt\" }}" data = "{{ key \"secrets/jitsi/jitsi.crt\" }}"
destination = "secrets/certs/jitsi.deuxfleurs.fr.crt" destination = "secrets/certs/jitsi.crt"
} }
template { template {
data = "{{ key \"secrets/jitsi/jitsi.deuxfleurs.fr.key\" }}" data = "{{ key \"secrets/jitsi/jitsi.key\" }}"
destination = "secrets/certs/jitsi.deuxfleurs.fr.key" destination = "secrets/certs/jitsi.key"
} }
resources { resources {
@ -124,13 +142,14 @@ job "jitsi" {
tags = [ tags = [
"jitsi", "jitsi",
"traefik.enable=true", "traefik.enable=true",
"traefik.frontend.entryPoints=https,http", "traefik.frontend.entryPoints=https",
"traefik.frontend.rule=Host:jitsi.deuxfleurs.fr;PathPrefix:/", "traefik.frontend.rule=Host:jitsi.deuxfleurs.fr;PathPrefix:/",
"traefik.protocol=https" "traefik.protocol=https",
"tricot jitsi.deuxfleurs.fr",
] ]
port = "https_port" port = "https_port"
address_mode = "host" address_mode = "host"
name = "jitsi-front-https" name = "https-jitsi"
check { check {
type = "tcp" type = "tcp"
port = "https_port" port = "https_port"
@ -148,25 +167,29 @@ job "jitsi" {
task "jicofo" { task "jicofo" {
driver = "docker" driver = "docker"
config { config {
image = "superboum/amd64_jitsi_conference_focus:v6" image = "superboum/amd64_jitsi_conference_focus:v9"
network_mode = "host" network_mode = "host"
volumes = [
"secrets/certs/jitsi.crt:/usr/local/share/ca-certificates/jitsi.crt",
"secrets/certs/auth.jitsi.crt:/usr/local/share/ca-certificates/auth.jitsi.crt",
"secrets/jicofo.conf:/etc/jitsi/jicofo.conf"
]
} }
template { template {
data = file("../config/global_env.tpl") data = file("../config/jicofo.conf")
destination = "secrets/global_env" destination = "secrets/jicofo.conf"
env = true
} }
#--- secrets --- #--- secrets ---
template { template {
data = "{{ key \"secrets/jitsi/jitsi.deuxfleurs.fr.crt\" }}" data = "{{ key \"secrets/jitsi/jitsi.crt\" }}"
destination = "secrets/certs/jitsi.deuxfleurs.fr.crt" destination = "secrets/certs/jitsi.crt"
} }
template { template {
data = "{{ key \"secrets/jitsi/auth.jitsi.deuxfleurs.fr.crt\" }}" data = "{{ key \"secrets/jitsi/auth.jitsi.crt\" }}"
destination = "secrets/certs/auth.jitsi.deuxfleurs.fr.crt" destination = "secrets/certs/auth.jitsi.crt"
} }
resources { resources {
@ -178,56 +201,60 @@ job "jitsi" {
task "videobridge" { task "videobridge" {
driver = "docker" driver = "docker"
config { config {
image = "superboum/amd64_jitsi_videobridge:v16" image = "superboum/amd64_jitsi_videobridge:v20"
network_mode = "host" network_mode = "host"
ports = [ "video1_port", "video2_port" ] ports = [ "video_port" ]
ulimit { ulimit {
nofile = "1048576:1048576" nofile = "1048576:1048576"
nproc = "65536:65536" nproc = "65536:65536"
} }
volumes = [
"secrets/certs/jitsi.crt:/usr/local/share/ca-certificates/jitsi.crt",
"secrets/certs/auth.jitsi.crt:/usr/local/share/ca-certificates/auth.jitsi.crt",
"secrets/videobridge.conf:/etc/jitsi/videobridge.conf"
]
} }
env { env {
#JITSI_DEBUG = 1 # Our container can autodetect the public IP with the ifconfig.me service
JITSI_VIDEO_TCP = 8081 # However we would like to avoid relying on a 3rd party service for production use
VIDEOBRIDGE_MAX_MEMORY = "1450m" # That's why I am setting the public IP address statically here VVVV
JITSI_NAT_PUBLIC_IP = "82.64.119.240"
} }
template { template {
data = file("../config/global_env.tpl") data = file("../config/videobridge.conf")
destination = "secrets/global_env" destination = "secrets/videobridge.conf"
env = true }
# --- secrets ---
template {
data = "{{ key \"secrets/jitsi/jitsi.crt\" }}"
destination = "secrets/certs/jitsi.crt"
}
template {
data = "{{ key \"secrets/jitsi/auth.jitsi.crt\" }}"
destination = "secrets/certs/auth.jitsi.crt"
} }
resources { resources {
cpu = 900 cpu = 900
memory = 1500 memory = 3000
} }
service { service {
tags = [ "jitsi", "(diplonat (tcp_port 8081))" ] tags = [ "jitsi", "(diplonat (tcp_port 8080) (udp_port 8080))" ]
port = "video1_port" port = "video_port"
address_mode = "host" address_mode = "host"
name = "jitsi-videobridge-video1" name = "video-jitsi"
check { check {
type = "tcp" type = "tcp"
port = "video1_port" port = "video_port"
interval = "60s" interval = "60s"
timeout = "5s" timeout = "5s"
check_restart {
limit = 3
grace = "90s"
ignore_warnings = false
}
} }
} }
service {
tags = [ "jitsi", "(diplonat (udp_port 10000))" ]
port = "video2_port"
address_mode = "host"
name = "jitsi-videobridge-video2"
}
} }
} }
} }

View file

@ -11,9 +11,10 @@ Several server components:
- etc. - etc.
Some libs: Some libs:
- libjitsi - libjitsi seems deprecated
- jicoco - jicoco contains some parent classes to handle Jitsi's Configuration
- jitsi-utils - [jitsi-utils](https://github.com/jitsi/jitsi-utils) contains the Logger definition for example
- [ice4j](https://github.com/jitsi/ice4j) contains jitsi's implementation of WebRTC
- etc. - etc.
Client components: Client components:
@ -62,6 +63,28 @@ instead, we should look at this one: https://github.com/jitsi/jitsi-meet/blob/ma
Jitsi can be configured to authenticated through tokens, Jitsi can be configured to authenticated through tokens,
the postinst file is here: https://github.com/jitsi/jitsi-meet/blob/master/debian/jitsi-meet-tokens.postinst the postinst file is here: https://github.com/jitsi/jitsi-meet/blob/master/debian/jitsi-meet-tokens.postinst
## Remote debug
Add this parameter to the java process you want to debug (either jicofo or jvb). It must be added by modifying the entrypoint script, next to the respective Dockerfile of each container.
```
-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005
```
## Be careful
jiti-videobridge (jvb) does not start to listen on ICE ports (both TCP and UDP) at boot.
Instead, listening is triggered on the creation of the first conference (a 2 people P2P conference is enough).
A nice entrypoint to check with your debugger is:
- [Videobridge.java#XmppConnectionEventHandle.colibriConferenceIqReceived](https://github.com/jitsi/jitsi-videobridge/blob/256dc7acb7ee10440502a6073a498329eaf1e819/jvb/src/main/java/org/jitsi/videobridge/Videobridge.java#L627)
- [VideobridgeShim.java#VideobridgeShim.handleColibriConferenceIQ](https://github.com/jitsi/jitsi-videobridge/blob/256dc7acb7ee10440502a6073a498329eaf1e819/jvb/src/main/java/org/jitsi/videobridge/shim/VideobridgeShim.java#L251)
- [ConferenceShim.java#ConferenceShim.initializeSignaledEndpoints](https://github.com/jitsi/jitsi-videobridge/blob/256dc7acb7ee10440502a6073a498329eaf1e819/jvb/src/main/java/org/jitsi/videobridge/shim/ConferenceShim.java#L274)
- [ConferenceShim.java#ConferenceShim.ensureEndpointCreated](https://github.com/jitsi/jitsi-videobridge/blob/256dc7acb7ee10440502a6073a498329eaf1e819/jvb/src/main/java/org/jitsi/videobridge/shim/ConferenceShim.java#L312)
- [Conference.java#Conference.createLocalEndpoint](https://github.com/jitsi/jitsi-videobridge/blob/256dc7acb7ee10440502a6073a498329eaf1e819/jvb/src/main/java/org/jitsi/videobridge/Conference.java#L602)
- [Endpoint.java#Endpoint.new](https://github.com/jitsi/jitsi-videobridge/blob/256dc7acb7ee10440502a6073a498329eaf1e819/jvb/src/main/java/org/jitsi/videobridge/Endpoint.java#L254)
- [IceTransport.kt#IceTransport.iceAgent(init)](https://github.com/jitsi/jitsi-videobridge/blob/0c2ac250ec6b518eaf75fbc83f7936ec01e7b5f6/jvb/src/main/kotlin/org/jitsi/videobridge/transport/ice/IceTransport.kt#L99)
- [IceTransport.kt#companionObject.appendHarvesters](https://github.com/jitsi/jitsi-videobridge/blob/0c2ac250ec6b518eaf75fbc83f7936ec01e7b5f6/jvb/src/main/kotlin/org/jitsi/videobridge/transport/ice/IceTransport.kt#L350)
## Resources to understand jitsi ## Resources to understand jitsi
- [jicofo/debian/postinst](https://github.com/jitsi/jicofo/blob/master/debian/postinst) - [jicofo/debian/postinst](https://github.com/jitsi/jicofo/blob/master/debian/postinst)

View file

@ -15,23 +15,28 @@ services:
jitsi-conference-focus: jitsi-conference-focus:
image: superboum/amd64_jitsi_conference_focus:v7 image: superboum/amd64_jitsi_conference_focus:v7
volumes: volumes:
- "./prosody/certs/jitsi.crt:/usr/local/share/ca-certificates/jitsi.crt:ro"
- "./prosody/certs/auth.jitsi.crt:/usr/local/share/ca-certificates/auth.jitsi.crt:ro" - "./prosody/certs/auth.jitsi.crt:/usr/local/share/ca-certificates/auth.jitsi.crt:ro"
- "./jicofo/jicofo.conf:/etc/jitsi/jicofo.conf:ro" - "./jicofo/jicofo.conf:/etc/jitsi/jicofo.conf:ro"
environment:
- JDOMAIN=jitsi jitsi-videobridge:
- JHOST=jitsi-xmpp image: superboum/amd64_jitsi_videobridge:v17
- JPORT=5347 volumes:
- JSUBDOMAIN=focus - "./prosody/certs/jitsi.crt:/usr/local/share/ca-certificates/jitsi.crt:ro"
- JICOFO_SECRET=jicofosecretpass - "./prosody/certs/auth.jitsi.crt:/usr/local/share/ca-certificates/auth.jitsi.crt:ro"
- JUSERDOMAIN=auth.jitsi - "./jvb/videobridge.conf:/etc/jitsi/videobridge.conf:ro"
- JUSERNAME=focus - "./jvb/logging.properties:/usr/share/jvb/lib/logging.properties:ro"
- JICOFO_AUTH_PASSWORD=jicofopass ports:
# jitsi-meet: - "8089:8089/tcp"
# image: superboum/amd64_jitsi_meet:v1 - "10000:10000/udp"
# ports:
# - "443:443" jitsi-meet:
# jitsi-videobridge: image: superboum/amd64_jitsi_meet:v4
# image: superboum/amd64_jitsi_videobridge:v14 volumes:
# ports: - "./prosody/certs/jitsi.crt:/etc/nginx/jitsi.crt:ro"
# - "8080:8080/tcp" - "./prosody/certs/jitsi.key:/etc/nginx/jitsi.key:ro"
# - "10000:10000/udp" - "./meet/config.js:/srv/jitsi-meet/config.js:ro"
- "./meet/nginx.conf:/etc/nginx/nginx.conf:ro"
ports:
- "443:443"

View file

@ -53,7 +53,7 @@ jicofo {
} }
// The JID of the MUC to be used as a brewery for bridge instances. // The JID of the MUC to be used as a brewery for bridge instances.
brewery-jid = "jvbbrewery@jitsi" brewery-jid = "jvbbrewery@internal.auth.jitsi"
} }
// Configure the codecs and RTP extensions to be used in the offer sent to clients. // Configure the codecs and RTP extensions to be used in the offer sent to clients.
codec { codec {
@ -256,7 +256,7 @@ jicofo {
} }
// The separate XMPP connection used for internal services (currently only jitsi-videobridge). // The separate XMPP connection used for internal services (currently only jitsi-videobridge).
service { service {
enabled = true enabled = false
hostname = "jitsi-xmpp" hostname = "jitsi-xmpp"
port = 5222 port = 5222
domain = "auth.jitsi" domain = "auth.jitsi"

View file

@ -0,0 +1,47 @@
handlers= java.util.logging.ConsoleHandler
#handlers= java.util.logging.ConsoleHandler, com.agafua.syslog.SyslogHandler
#handlers= java.util.logging.ConsoleHandler, io.sentry.jul.SentryHandler
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter
net.java.sip.communicator.util.ScLogFormatter.programname=JVB
# default
.level=INFO
# for debug
#.level=FINE
org.jitsi.videobridge.xmpp.ComponentImpl.level=FINE
# All of the INFO level logs from MediaStreamImpl are unnecessary in the context of jitsi-videobridge.
org.jitsi.impl.neomedia.MediaStreamImpl.level=WARNING
# Syslog (uncomment handler to use)
com.agafua.syslog.SyslogHandler.transport = udp
com.agafua.syslog.SyslogHandler.facility = local0
com.agafua.syslog.SyslogHandler.port = 514
com.agafua.syslog.SyslogHandler.hostname = localhost
com.agafua.syslog.SyslogHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter
com.agafua.syslog.SyslogHandler.escapeNewlines = false
# Sentry (uncomment handler to use)
io.sentry.jul.SentryHandler.level=WARNING
# to disable double timestamps in syslog uncomment next line
#net.java.sip.communicator.util.ScLogFormatter.disableTimestamp=true
# time series logging
java.util.logging.SimpleFormatter.format= %5$s%n
java.util.logging.FileHandler.level = ALL
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.pattern = /tmp/jvb-series.log
java.util.logging.FileHandler.limit = 200000000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.append = false
timeseries.level=OFF
timeseries.org.jitsi.videobridge.cc.allocation.BitrateAllocator.level=ALL
timeseries.useParentHandlers = false
# time series logging is disabled by default. Uncomment the line below to enable it.
#timeseries.handlers = java.util.logging.FileHandler

View file

@ -61,6 +61,17 @@ videobridge {
presence-interval = ${videobridge.stats.interval} presence-interval = ${videobridge.stats.interval}
configs { configs {
unique-xmpp-server {
hostname="jitsi-xmpp"
domain = "auth.jitsi"
username = "jvb"
password = "jvbpass"
port = 5222
muc_jids = "jvbbrewery@internal.auth.jitsi"
# The muc_nickname must be unique across all jitsi-videobridge instances
muc_nickname = "unique-jvb-server"
disable_certificate_verification = false
}
# example-connection-id { # example-connection-id {
# For the properties which should be # For the properties which should be
# filled out here, see MucClientConfiguration # filled out here, see MucClientConfiguration
@ -69,10 +80,10 @@ videobridge {
} }
# The COLIBRI REST API # The COLIBRI REST API
rest { rest {
enabled = false enabled = true
} }
jvb-api { jvb-api {
enabled = false enabled = true
} }
} }
# Configuration of the different REST APIs. # Configuration of the different REST APIs.
@ -177,7 +188,7 @@ videobridge {
stats { stats {
# Whether periodic collection of statistics is enabled or not. When enabled they are accessible through the REST # Whether periodic collection of statistics is enabled or not. When enabled they are accessible through the REST
# API (at `/colibri/stats`), and are available to other modules (e.g. to be pushed to callstats or in a MUC). # API (at `/colibri/stats`), and are available to other modules (e.g. to be pushed to callstats or in a MUC).
enabled = false enabled = true
# The interval at which stats are gathered. # The interval at which stats are gathered.
interval = 5 seconds interval = 5 seconds
@ -223,7 +234,7 @@ videobridge {
enabled = true enabled = true
# The port to bind to for ICE/TCP. # The port to bind to for ICE/TCP.
port = 8080 port = 8089
# An optional additional port to advertise. # An optional additional port to advertise.
# mapped-port = 8443 # mapped-port = 8443

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