Installing OpenTalk on Debian 12
OpenTalk is a video conferencing solution prioritizing productivity, digital sovereignty, and privacy. It is tailored to support moderators and ensure a good user experience with scalable performance during video conferences.
First, set up a Debian server with firewall ufw
.
Reverse Proxy
Firewall
Domain/DNS
Go to your domain provider and point your domain at your server's IP 4 and IP 6 adresses.
Create configuration files (see appendix):
sudo vi /etc/nginx/sites-available/controller.conf
sudo vi /etc/nginx/sites-available/frontend.conf
sudo vi /etc/nginx/sites-available/keycloak.conf
Certificates
sudo certbot certonly --standalone -d talk.example.com sudo certbot certonly --standalone -d accounts.talk.example.com sudo certbot certonly --standalone -d controller.talk.example.com
Install Nginx
Generate a DH parameter file:
Copy sslsettings.conf:
Configure Nginx
sudo vi /etc/nginx/sites-available/controller.conf sudo vi /etc/nginx/sites-available/frontend.conf sudo vi /etc/nginx/sites-available/keycloak.conf sudo ln -s /etc/nginx/sites-available/controller.conf /etc/nginx/sites-enabled/ sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/ sudo ln -s /etc/nginx/sites-available/keycloak.conf /etc/nginx/sites-enabled/ sudo systemctl restart nginx
Test Nginx configuration:
OpenTalk
Install Docker
From their homepage (https://docs.docker.com/engine/install/debian/#install-using-the-repository):
sudo apt-get update sudo apt-get install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/debian \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo docker run hello-world sudo apt-get update sudo apt-get install docker-compose-plugin docker compose version
Firewall
Container stack
git clone https://gitlab.opencode.de/opentalk/ot-setup.git /opt/opentalk cd /opt/opentalk cp env.sample .env cp extras/opentalk-samples/controller.toml.sample config/controller.toml sudo apt-get install pwgen bash extras/gen-secrets.sh
The last command produces an output that you can use to replace the header area
in the .env file. Note that the OT_DOMAIN
must be set manually.
vi .env
:
OT_DOMAIN="talk.example.com" POSTGRES_PASSWORD=paiquohlai9eQueih0Aiki3ror9chuyu KEYCLOAK_ADMIN_PASSWORD=Aelai3ucu2aewoo7couth9Afiezeeyai KEYCLOAK_CLIENT_SECRET_CONTROLLER=iengoo5Ohhaog3ig9piogooh6phouluM KEYCLOAK_CLIENT_SECRET_OBELISK=Pai9juem8ha2iiKaovai0veofaeTheeL KEYCLOAK_CLIENT_SECRET_RECORDER=heus6aiJoh5eu3oofairo1oovahwau5U SPACEDECK_API_TOKEN=dae6ein6ootuang3aihaebenu0Oixuit SPACEDECK_INVITE_CODE=thoo0ne4ooGhaichinie3ohpouZoht7e ETHERPAD_API_KEY=jaisaephaico1Ohz3maaGh9quocuNg3i
Replace the placeholders in vi config/controller.toml
:
# ``POSTGRES_PASSWORD`` from ``.env.`` url = "postgres://ot:<POSTGRES_PASSWORD>@postgres:5432/opentalk" cors.allowed_origin = ['talk.example.com'] base_url = "https://accounts.talk.example.com/auth" # ``KEYCLOAK_CLIENT_SECRET_RECORDER`` from ``.env.`` client_secret = "<KEYCLOAK_CLIENT_SECRET_CONTROLLER>"
Run the OpenTalk stack
Post installation tasks
Point your web browser to https://accounts.talk.example.com/auth
.
- user
-
admin
- password
-
KEYCLOAK_CLIENT_SECRET_CONTROLLER
fromenv.
.
After login to Keycloak administration, switch to the realm opentalk and create a new user with the default role default-roles-opentalk. As reference you can refer the testuser provided for demo purposes. You can also enable the testuser and reset the password for testing OpenTalk.
Log in to your OpenTalk instance
If you have successfully created an OpenTalk user, you can now use it to log in to your new OpenTalk installation. By default, the OpenTalk web interface is available at the root of your domain e.g. https://talk.example.com.
Trouble Shooting
ancestor violates the following Content Security Policy directive: "frame-ancestors 'self'"
Set the Content-Security-Policy on the Keycloak webinterface at Keycloak -> reaml "opentalk" (Dropdown) -> Realm settings -> Security defenses Content-Security-Policy:
frame-ancestors 'self' https://talk.example.com https://accounts.talk.example.com https://controller.talk.example.com; default-src 'self' https://talk.example.com https://accounts.talk.example.com https://controller.talk.example.com; frame-src 'unsafe-inline' 'self' https://talk.example.com https://accounts.talk.example.com https://controller.talk.example.com; style-src 'unsafe-inline' 'self'; connect-src 'unsafe-inline' 'self' https://talk.example.com https://accounts.talk.example.com https://controller.talk.example.com
Access to fetch at 'https://controller.talk.suredigital.de/v1/auth/login' from origin 'https://talk.suredigital.de' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
TODO
"``Invalid parameter: redirect_uri`` und Bad Request"
The bad request is triggered by the URL-Paratemer redirect_uri
. The error
message should be correctly: "Invalid value for parameter: redirect_uri".
The value of that parameter needs to correspond an URL set in Keycloak.
To fix the "Bad Request": in the Admin-Panel of Keycloak go to -> realm "opentalk" (Dropdown) -> Clients ->
OtBackend -> Valid redirect URL -> Add valid redirect URIs: change all entries from
talk.example.com
tosubdomain.foo.com
.OtFrontend -> Valid redirect URL -> Add valid redirect URIs: change all entries from
talk.example.com
tosubdomain.foo.com
.
Note this happens when changing domains after setting up the Docker container for the first time, as while some values get updated on later configuration changes, those values won't be updated.
Appendix
/etc/nginx/sites-available/controller.conf
upstream controller { server localhost:8090; } map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; listen [::]:80; server_name controller.talk.example.com; # include snippets/letsencrypt.conf; location / { access_log off; return 301 https://$server_name$request_uri; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name controller.talk.example.com; ssl_certificate /etc/letsencrypt/live/controller.talk.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/controller.talk.example.com/privkey.pem; # NOTE: ChatGPT says this is not needed for a reverse proxy # root controller.talk.example.com; include /etc/nginx/snippets/sslsettings.conf; access_log /var/log/nginx/https-access_controller.talk.example.com.log; error_log /var/log/nginx/https-error_controller.talk.example.com.log; client_max_body_size 1G; location / { proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_buffers 8 8k; proxy_buffer_size 8k; proxy_pass http://controller; } }
/etc/nginx/sites-available/frontend.conf
upstream web-frontend { server localhost:8080; } map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; listen [::]:80; server_name talk.example.com; # include snippets/letsencrypt.conf; location / { access_log off; return 301 https://$server_name$request_uri; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name talk.example.com; ssl_certificate /etc/letsencrypt/live/talk.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/talk.example.com/privkey.pem; # NOTE: ChatGPT says, this is not needed for a reverse proxy: # root talk.example.com; include /etc/nginx/snippets/sslsettings.conf; access_log /var/log/nginx/https-access_talk.example.com.log; error_log /var/log/nginx/https-error_talk.example.com.log; location / { proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_buffers 8 8k; proxy_buffer_size 8k; proxy_pass http://web-frontend; } }
/etc/nginx/sites-available/keycloak.conf
upstream keycloak { server localhost:8087; } map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; listen [::]:80; server_name accounts.talk.example.com; # include snippets/letsencrypt.conf; location / { access_log off; return 301 https://$server_name$request_uri; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name accounts.talk.example.com; ssl_certificate /etc/letsencrypt/live/accounts.talk.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/accounts.talk.example.com/privkey.pem; # NOTE: ChatGPT says, this is not needed for a remote proxy setup: # root accounts.talk.example.com; include /etc/nginx/snippets/sslsettings.conf; access_log /var/log/nginx/https-access_accounts.talk.example.com.log; error_log /var/log/nginx/https-error_accounts.talk.example.com.log; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_buffers 8 8k; proxy_buffer_size 8k; proxy_pass http://keycloak; } }
Changing domain
sed -i 's^old.com^new.com^g' /opt/opentalk/.env find /opt/opentalk/config/ -name "*.toml" -exec sed -i 's^old.com^new.com^g' '{}' \; sudo find /etc/nginx/sites-available/ -name "*.conf" -exec sed -i 's^old.com^new.com^g' '{}' \;
Create certificates for the new domain und sub domains, if not existened yet.