The Galène videoconferencing server

# Installation

## Build the server binary

    CGO_ENABLED=0 go build -ldflags='-s -w'

## Create a server certificate

    mkdir data
    openssl req -newkey rsa:2048 -nodes -keyout data/key.pem -x509 -days 365 -out data/cert.pem

## Set the server administrator credentials

This step is optional.

    echo 'god:topsecret' > data/passwd

## Set up a group

A group called *groupname* is is set up by creating a file

    mkdir groups
    vi groups/groupname.json
A group with a single operator and no password for ordinary users looks
like this:

        "op": [{"username": "jch", "password": "1234"}],
        "presenter": [{}]
A group with one operator and two users looks like this:

        "op": [{"username": "jch", "password": "1234"}],
        "presenter": [
            {"username": "mom", "password": "0000"},
            {"username": "dad", "password": "1234"}
More options are described under *Details of group definitions* below.

## Test locally

    ./galene &
You should be able to access Galène at `https://localhost:8443`.  Connect
to the group that you have just set up in two distinct browser windows,
then press *Ready* in one of the two; you should see a video in the other.

If you have set up a TURN server, type `/relay-test` in the chat box; if
the TURN server is properly configured, you should see a message saying
that the relay test has been successful.  (The relay test will fail if you
didn't configure a TURN server; this is normal, and nothing to worry

## Configure your server's firewall

If your server has a global IPv4 address and there is no firewall, there
is nothing to do.

If your server has a global IPv4 address, then the firewall must, at
a strict minimum, allow incoming traffic to TCP port 8443 (or whatever is
configured with the `-http` command-line option) and TCP port 1194 (or
whatever is configured with the `-turn` command-line option).  For best
performance, it should also allow UDP traffic to the TURN port, and UDP
traffic to ephemeral (high-numbered) ports.

If your server only has a global IPv6 address, then you should probably
configure an external double-stack (IPv4 and IPv6) TURN server: see
"ICE Servers" below.

If your server is behind NAT, then the best solution is to run an external
TURN server that is not behind NAT (see "ICE Servers" below).  If that is
not possible, then you should configure your NAT device to forward, at
a minimum, ports 8443 (TCP) and 1194 (TCP and UDP).  In addition, you
should add the option `-turn` to Galène's command line,
where `` is your NAT's external (global) IPv4 address.

## Cross-compile for your server

If your server runs a different OS or has a different CPU than your build
machine, you will need to recompile the binary for the server.

For a Linux server with an Intel or AMD CPU:

    CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags='-s -w'

For a Raspberry Pi 1:

    CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=6 go build -ldflags='-s -w'

For a BeagleBone or a Raspberry Pi 2 or later:

    CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build -ldflags='-s -w'

For a 64-bit ARM board (Olimex Olinuxino-A64, Pine64, etc.):

    CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags='-s -w'

For a 32-bit MIPS board with no hardware floating point (WNDR3800, etc.):

    CGO_ENABLED=0 GOOS=linux GOARCH=mips GOMIPS=softfloat go build -ldflags='-s -w'

## Deploy to your server

Set up a user *galene* on your server, then do:

    rsync -a galene static data groups [email protected]:
Now run the binary on the server:

    ssh [email protected]
    ulimit -n 65536
    nohup ./galene &

If you are using *runit*, use a script like the following:

    exec 2>&1
    cd ~galene
    ulimit -n 65536
    exec setuidgid galene ./galene

If you are using *systemd*:




# Usage

## Locations

There is a landing page at the root of the server.  It contains a form
for typing the name of a group, and a clickable list of public groups.

Groups are available under `/group/groupname`.  You may share this URL
with others, there is no need to go through the landing page.

Recordings can be accessed under `/recordings/groupname`.  This is only
available to the administrator of the group.

Some statistics are available under `/stats`.  This is only available to
the server administrator.

## Side menu

There is a menu on the right of the user interface.  This allows choosing
the camera and microphone and setting the video throughput.  The
*Blackboard mode* checkbox increases resolution and sacrifices framerate
in favour of image quality.  The *Play local file* dialog allows streaming
a video from a local file.

## Commands

Typing a line starting with a slash `/` in the chat dialogue causes
a command to be sent to the server.  Type `/help` to get the list of
available commands; the output depends on whether you are an operator or

# Details of group definitions

Groups are defined by files in the `./groups` directory (this may be
configured by the `-groups` command-line option, try `./galene -help`).
The definition for the group called *groupname* is in the file
`groups/groupname.json`; it does not contain the group name, which makes
it easy to copy or link group definitions.  You may use subdirectories:
a file `groups/teaching/networking.json` defines a group called

Every group definition file contains a JSON directory.  All fields are
optional, but unless you specify at least one user definition (`op`,
`presenter`, or `other`), nobody will be able to join the group.  The
following fields are allowed:

 - `op`, `presenter`, `other`: each of these is an array of user
   definitions (see below) and specifies the users allowed to connect
   respectively with operator privileges, with presenter privileges, and
   as passive listeners;
 - `public`: if true, then the group is visible on the landing page;
 - `description`: a human-readable description of the group; this is
   displayed on the landing page for public groups;
 - `contact`: a human-readable contact for this group, such as an e-mail
 - `comment`: a human-readable string;
 - `max-clients`: the maximum number of clients that may join the group at
   a time;
 - `max-history-age`: the time, in seconds, during which chat history is
   kept (default 14400, i.e. 4 hours);
 - `allow-recording`: if true, then recording is allowed in this group;
 - `allow-anonymous`: if true, then users may connect with an empty username;
 - `allow-subgroups`: if true, then subgroups of the form `group/subgroup`
   are automatically created when first accessed;
 - `autolock`: if true, the group will start locked and become locked
   whenever there are no clients with operator privileges;
 - `autokick`: if true, all clients will be kicked out whenever there are
   no clients with operator privileges; this is not recommended, prefer
   the `autolock` option instead;
 - `redirect`: if set, then attempts to join the group will be redirected
   to the given URL; most other fields are ignored in this case;
 - `codecs`: this is a list of codecs allowed in this group.  The default
   is `["vp8", "opus"]`.
Supported video codecs include:

 - `"vp8"` (compatible with all supported browsers);
 - `"vp9"` (better video quality than `"vp8"`, but incompatible with
   older versions of Mac OS);
 - `"h264"` (incompatible with Debian, Ubuntu, and some Android devices,
   recording is not supported).

Supported audio codecs include `"opus"`, `"g722"`, `"pcmu"` and `"pcma"`.
There is no good reason to use anything except Opus.
A user definition is a dictionary with the following fields:

 - `username`: the username of the user; if omitted, any username is
 - `password`: if omitted, then no password is required.  Otherwise, this
   can either be a string, specifying a plain text password, or
   a dictionary generated by the `galene-password-generator` utility.
For example,

    {"username": "jch", "password": "1234"}
specifies user *jch* with password *1234*, while

    {"password": "1234"}
specifies that any (non-empty) username will do, and

allows any (non-empty) username with any password.

If you don't wish to store cleartext passwords on the server, you may
generate hashed password with the `galene-password-generator` utility.  A
user entry with a hashed password looks like this:

        "username": "jch",
        "password": {
            "type": "pbkdf2",
            "hash": "sha-256",
            "key": "f591c35604e6aef572851d9c3543c812566b032b6dc083c81edd15cc24449913",
            "salt": "92bff2ace56fe38f",
            "iterations": 4096

# ICE Servers

ICE is the NAT and firewall traversal protocol used by WebRTC.  ICE can
make use of two kinds of servers to help with NAT traversal: STUN servers,
that help punching holes in well-behaved NATs, and TURN servers, that
serve as relays for traffic.  TURN is a superset of STUN: no STUN server
is necessary if a TURN server is available.

Galène includes an IPv4-only TURN server, which is controlled by the
`-turn` command-line option.  If its value is set to the empty string
`""`, then the built-in server is disabled.  If its value is a colon
followed with a port number, for example `:1194`, then the TURN server
will listen on all public IPv4 addresses of the local host, over UDP and
TCP.  If the value of this option is a socket address, such as
``, then the TURN server will listen on all addresses of
the local host but assume that the address seen by the clients is the one
given in the option; this is useful when running behind NAT with port
forwarding set up.  The default value is `-turn auto`, which starts a
TURN server on port 1194 unless there is a `data/ice-servers.json` file.

Some users may prefer to use an external ICE server.  In that case, the
built-in TURN server should be disabled (`-turn ""` or the default `-turn
auto`), and a working ICE configuration should be given in the file
`data/ice-servers.json`.  In the case of a single STUN server, it should
look like this:

            "urls": [
In the case of s single TURN server, the `ice-servers.json` file should
look like this:

            "urls": [
            "username": "galene",
            "credential": "secret"

If you prefer to use coturn's `use-auth-secret` option, then the
`ice-servers.json` file should look like this:

            "Urls": [
            "username": "galene",
            "credential": "secret",
            "credentialType": "hmac-sha1"
For redundancy, you may set up multiple TURN servers, and ICE will use the
first one that works.  If an `ice-servers.json` file is present and
Galène's built-in TURN server is enabled, then the external server will be
used in preference to the built-in server.

# Further information

Galène's web page is at <>.

Answers to common questions and issues are at <>.

-- Juliusz Chroboczek <>
  • Management interface issue

    Management interface issue

    Pull Request on Issue #11

    What we add :

    • An administrative interface which is not part of the Galène server, so it needs to be executed independently. It needs to have an read and write access to change the json files.
    • An administrator can change the groups manually or with the interface, the json files are human readable.
    • You have a admin.json which have the admin's usernames and passwords to connect to the interface .
    • You can create new groups and modify the old ones
    opened by Aeljs 19
  • running Galene behind haproxy ?

    running Galene behind haproxy ?

    Question is about HAPROXY.

    Galene is installed sucessfuly but can't see each other on a room.

    I only see my own face. (users also see only their own face).

    Configuration Running Galene in a container with only a private IP ( Public IP is behind another container dedicated to haproxy ( + PUblic IP ) which send the 443 traffic to Galene container on 8443 port. Also some iptables redirect for 1194/UDP and 10000-65535 udp port from Haproxy container to Galene container.

    when starting Galene:

    # ./galene -turn PUBLIC_IP:1194
    2021/01/22 11:51:01 Starting built-in TURN server
    2021/01/22 11:51:21 Relay test failed: timeout
    2021/01/22 11:51:21 Perhaps you didn't configure a TURN server?
    2021/01/22 11:53:31 client: read tcp> read: connection reset by peer

    As we can see, it shows Haproxy IP ( instead of user IP. (X Forward For ?).

    Does Galene support haproxy ?


    opened by nlienard 18
  • Not being able to see others video/audio

    Not being able to see others video/audio

    Hi all and a big thx first: Galene works great for our team – awesome work.

    There is one bug that bothers a little: Sometimes participants can't join the conversation. They appear in the sidebar, are able to click the ready button and even see their own video – but not the others' video/audio. From their perspective, all the others (despite being visible in the sidebar) didn't join the conversation yet. Meanwhile the others can see each other and even hear and see the person with the bug

    The weird thing is the irregularity of this:

    • most of the users with this bug use Firefox or Safari (we, therefore, agreed on using Chromium browsers internally. But it can be difficult to explain that to external guests that only join once).
    • But unfortunately, it even happened to people using latest Google Chrome browsers.
    • Today it even happened to me using a Mac, latest Google Chrome with Internet from a Smartphone LTE Hotspot
    • Often it helps to restart the browser and or open the link in a private window, but sometimes not...

    What makes the bug a problem is, that you cannot see that it is actually you having the bug. It just seems that the rest of the team did not join yet. Chat works btw.

    We host Galene as part of aYunohost installation on a VPS. Everything is up to date.

    Tell me if I can provide any logs or more information. I am not so deep into programming etc. but I just thought it is good to report the issue.

    opened by jakobkilian 16
  • Showing admins infos on a specific admin port

    Showing admins infos on a specific admin port

    A private http server for debugging purpose, performance analysis, or monitoring.

    It listens on localhost, and should not be routed on Internet.

    It exposes :

    opened by athoune 14
  • Firefox issue ?

    Firefox issue ?

    On Chrome, Safari all is working perfectely On Firefox, user can connect but is not showing the video of other people. (other can see him).

    Is it a general issue on FF ?


    opened by nlienard 12
  • Sanity-checking of settings on startup

    Sanity-checking of settings on startup

    It would be useful if Galene could sanity-check the config on startup. In particular:

    • Read all config files and verify their syntax and semantics, log any errors
    • Try out the ICE config and log success/failure to connect to each candidate

    This would make it easier to be sure that the config works after a change/restart. Maybe even (optionally?) fail to startup if there's an error, so the failure can be picked up by 'systemctl restart'?

    opened by tohojo 12
  • Authentication and authorisation

    Authentication and authorisation

    The current authentication and authorisation scheme is simple and expressive, but has some limitations:

    • if a user is authorised in multiple groups, their password entry needs to be duplicated (there is no global password file);
    • there is no means of authentication delegation ("login with Github").

    On the latter point, one must carefully distinguish between authentication and authorisation. Protocols such as OAuth2 delegate authentication — they say e.g. that a user has authentic Github credentials, but they say nothing about whether said user is allowed to access a given instance of Galène.

    Please refrain from commenting about how horrible OAuth2 is. This is true, but quite besides the point.

    opened by jech 11
  • iOS web. Webrtc does not have permission in Chrome but works on iOS safari and firefox

    iOS web. Webrtc does not have permission in Chrome but works on iOS safari and firefox

    Am trying this out from an iOS device.

    It’s using Chrome.

    When I press the Green button to enable webrtc is barks at me this:


    I wonder if it’s a permission problem.

    Also it might work if it’s added using A2HS

    opened by gedw99 10
  • LDAP authentication

    LDAP authentication

    Here is an attempt to add LDAP authentication for Galène. Main features are:

    • no regexps
    • pure Go ldap interaction, based on
    • credentials are checked against the LDAP database; permissions like op, presenter and so on are defined in the groups JSON files, by defining a list of constraints.

    Here is an example of a working descrition (file groups/demo.json). There are no "manually created" accounts:

        "description" : "Salon de démonstration numéro 1",
        "autolock": true,
        "ldapurl": "ldap://",
        "ldapbase": "dc=lycee,dc=jb",
        "ldapuserbranch": "cn=Users,dc=lycee,dc=jb",
        "ldapbinduser": "personne",
        "ldapbindpassword": "donottellsecret",
        "op_ldap": [{"field": "memberOf", "begins": "CN=profs"}],
        "presenter_ldap": [{"field": "memberOf", "begins": "CN=profs"}]
    opened by georgesk 10
  • Option for High(er) Quality Audio

    Option for High(er) Quality Audio

    Hey! Thanks again for this great tool, I am so grateful to be able to use it! One feature would make me very very happy. I will try to describe it shortly:

    I have often had the situation where I wanted to share a piece of music. This works well (e.g. via line-in or internal rounding), but the quality is relatively poor. On the one hand because of the 32 kbit bitrate (?) and on the other because Galene (presumably) tries to normalise the volume and the level therefore varies constantly and is therefore sometimes very loud and sometimes very quiet.

    My suggestion: A dropdown option for one client to stream audio in high(er) quality. No need for lossless, but a bit better to get the music...

    Thanks a lot in advance.

    opened by jakobkilian 8
  • Can't activate microphone on iPhone

    Can't activate microphone on iPhone

    Greetings I'm happily using Galene with a lot of people and they all love it, but (for some obscure reason) some of them are still using iPhones, and they are reporting they cannot join because they cannot activate the microphone, even if they click "Allow". Do you know a way to work around that? I'm using Galene on server with a public name and a certificate from Let's Encrypt. Thanks in advance Regards

    opened by gregfr 8
  • Sometimes not working on iOS

    Sometimes not working on iOS

    Hello! Thank you sooo much for galene, it's an amazing piece of software. The UI/SFU itself is amazing already and with the built-in TURN server it makes deployment so much easier. I can already see a future where companies/nerds can self-host a video server with a budget-friendly Raspberry Pi! That is doing so much to have a self-hosted future where everyone owns their data.

    I have recently tried it out with friends and... apologies with the rather boring paragraphs, I have a few questions. I want to start by apologizing that I don't have much logs to share, I know it makes this a VERY bad issue report, but the trouble is it's hard to remotely debug iOS Safari while I only have a Linux desktop. Making sure iOS Safari is a goal for me.

    1. H264 doesn't work as well on iOS Safari. I have my codec set to ["h264", "opus"] and they won't talk to each other. My bad memory tells me that iOS -> Edge is working, but Edge -> iOS Safari is not. The error is "failed to set local answer sdp failed to set local video description recv parameters m-section with mid=1".

    Device A: Windows MS Edge Chromium, have H/W acceleration for H264 & VP8 as per chrome://gpu Device B: iOS 15.3.1 Safari

    1. iOS Safari is flaky I now have my codec set to ["h264", "vp8" "opus"]. It doesn't work when I have Device A & C FIRST, then Device B joins. By doesn't work, I mean Device A & C can see stream from Device B, but Device B can only see itself. (This is about video, forgot audio's behaviour). If only Device A & B is there, it works.

    From Device A's chrome://webrtc-internals, Device A is sending VP8, while Device C is sending H264.

    Device A: Windows MS Edge Chromium, have H/W acceleration for H264 & VP8 as per chrome://gpu Device B: iOS 15.3.1 Safari Device C: OS X 12 Safari

    1. iOS Safari - lost navigation? I am not sure if it is a navigation problem or something else, but my friend (Device D, iOS Safari, version unknown) she's lost. She was presented with this screen: signal-2022-02-25-203306

    There were already 2 devices in the group. However she couldn't hear/see the other 2 devices. At the same time, the other 2 devices didn't see her, not even in the chat sidebar.

    Is she in a good state? Is all she need to do is close the sidebar on the left?


    opened by isaackwan 6
  • A2HS for mobile and desktop

    A2HS for mobile and desktop

    A2HS allows users would be able to install the app onto their Desktop and Mobile.

    Its great because it bypasses the App Stores, but gives a App Store like experience. For example it adds a Icon to your Desktop or Mobile home screen. And because it uses service worker it self updates.

    I have used this with golang apps.

    Here is an example in golang: And the demo:

    IOS Safari video demo for install:

    I also tried it in IOS Chrome and Safari, but for some reason there is no ability to instal it. I know it can be done because i have done it with flutter web... I suspect that loki may not everything setup correctly.

    If i get more info on this, i will update it here.

    opened by gedw99 6
  • Show the version in the gui

    Show the version in the gui

    Noticed a lot of small bugs from people being reported.

    Mit might be a good idea to have a page or something that shows:

    Version of build ( githash ) User agent

    you could even add a button that creates an issue and passes that data perhaps but that maybe not needed.

    opened by gedw99 11
  • Make (un)present button width dynamic

    Make (un)present button width dynamic

    The present and unpresent button width is fixed to 5.8em. This is problematic as the content might need more space. By removing the width attribute, the element takes the width it requires.

    image Screenshot before the modification: "Disable" is overflowing to the right the button.

    opened by erdnaxe 2
Juliusz Chroboczek
Juliusz Chroboczek
a simple http server as replacement of python -m http.server

ser a simple http server as replacement of python -m http.server

Changkun Ou 4 Feb 16, 2022
OpenAPI specs for your Go server, generated at server runtime. No CLI, no code generation, and no HTTP

Overview "oas" is short for "OpenAPI Spec". Go package for generating OpenAPI docs at runtime. Non-features: No code generation. No CLI. No magic comm

Nelo Mitranim 0 Dec 3, 2021
A Language Server Protocol (LSP) server for Jsonnet

Jsonnet Language Server A Language Server Protocol (LSP) server for Jsonnet. Features Jump to definition self-support.mp4 dollar-support.mp4 Error/War

Grafana Labs 56 Jun 24, 2022
Go web server - A web server that can accept a GET request and serve a response.

go_web_server A web server that can accept a GET request and serve a response. Go is a great language for creating simple yet efficient web servers an

Gilbert Ngeno 0 Jan 3, 2022
:tophat: Small self-contained pure-Go web server with Lua, Markdown, HTTP/2, QUIC, Redis and PostgreSQL support

Web server with built-in support for QUIC, HTTP/2, Lua, Markdown, Pongo2, HyperApp, Amber, Sass(SCSS), GCSS, JSX, BoltDB (built-in, stores the databas

Alexander F. Rødseth 2k Jun 25, 2022
Fast, multi-platform web server with automatic HTTPS

a project Every site on HTTPS Caddy is an extensible server platform that uses TLS by default. Releases · Documentation · Get Help Menu Features Insta

Caddy 41.4k Jun 27, 2022
A simple SHOUTcast server.

DudelDu DudelDu is a simple audio/video streaming server using the SHOUTcast protocol. Features Supports various streaming clients: VLC, ServeStream,

Matthias Ladkau 136 Apr 20, 2022
A feature flag solution, with only a YAML file in the backend (S3, GitHub, HTTP, local file ...), no server to install, just add a file in a central system and refer to it. 🎛️

??️ go-feature-flag A feature flag solution, with YAML file in the backend (S3, GitHub, HTTP, local file ...). No server to install, just add a file i

Thomas Poignant 447 Jun 29, 2022
An XMPP server written in Go (Golang).

jackal An XMPP server written in Go. About jackal is a free, open-source, high performance XMPP server which aims to be known for its stability, simpl

Miguel Ángel Ortuño 1.3k Jun 25, 2022
A proxy server than converts JSON request bodies to protocol buffers

Welcome to Protoxy ?? What is Protoxy? Protoxy allows you to test your REST APIs that use Protocol Buffer serialization through Postman and other API

null 24 May 21, 2022
High-performance PHP application server, load-balancer and process manager written in Golang

[RR2-BETA] RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports runnin

Spiral Scout 6.6k Jul 2, 2022
Fully featured and highly configurable SFTP server with optional FTP/S and WebDAV support - S3, Google Cloud Storage, Azure Blob

SFTPGo Fully featured and highly configurable SFTP server with optional FTP/S and WebDAV support, written in Go. Several storage backends are supporte

Nicola Murino 4.4k Jun 27, 2022
A RTP -> WebRTC broadcast server for Project Lightspeed.

Project Lightspeed WebRTC A RTP -> WebRTC server based on Pion written in Go. This server accepts RTP packets on port 65535 and broadcasts them via We

Garrett GRVY Graves 70 Jun 23, 2022
Heart 💜A high performance Lua web server with a simple, powerful API

Heart ?? A high performance Lua web server with a simple, powerful API. See the full documentation here. Overview Heart combines Go's fasthttp with Lu

Hyperspace Logistics 75 Jun 22, 2022
A push notification server written in Go (Golang).

A push notification micro server using Gin framework written in Go (Golang)

Bo-Yi Wu 6.4k Jul 1, 2022
KissLists is a very simple shared lists server

KissLists is a very simple shared lists server. with mobile optimised design basic theme support websockets messages sqlite database but no

Vincent Lark 37 Feb 18, 2022
⚡ A fast, lightweight, and secure chat protocol, client and server, written in Go.

⚡ A fast, lightweight, and secure chat protocol, client and server, written in Go.

Bolt 16 Jan 19, 2022
Demonstration of a browser connecting to Pion WebRTC without a signaling server.

Offline Browser Sync WebRTC without a signaling server! This repo demonstrates how you can connect two WebRTC proccesses without signaling. No configu

Pion 136 Jun 22, 2022
A simple HTTP Server to share files over WiFi via Qr Code

go-fileserver A simple HTTP server to share files over WiFi via QRCode Installation You can download compressed version from

Pradeep Khileri 69 May 30, 2022