# Technical Documentation: screego/server

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/screego/server)

### Overview (`README.md`)

<p align="center">
    <a href="https://screego.net">
        <img src="docs/logo.png" />
    </a>
</p>


<h1 align="center">screego/server</h1>
<p align="center"><i>screen sharing for developers</i></p>

<p align="center">
    <a href="https://github.com/screego/server/actions?query=workflow%3Abuild">
        <img alt="Build Status" src="https://github.com/screego/server/workflows/build/badge.svg">
    </a> 
    <a href="https://hub.docker.com/r/screego/server">
        <img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/screego/server.svg">
    </a>
    <a href="https://github.com/screego/server/releases/latest">
        <img alt="latest release" src="https://img.shields.io/github/release/screego/server.svg">
    </a>
</p>

## Intro

In the past I've had some problems sharing my screen with coworkers using
corporate chatting solutions like Microsoft Teams. I wanted to show them some
of my code, but either the stream lagged several seconds behind or the quality
was so poor that my colleagues couldn't read the code. Or both.

That's why I created screego. It allows you to share your screen with good
quality and low latency. Screego is an addition to existing software and 
only helps to share your screen. Nothing else (:.

## Features

* Multi User Screenshare
* Secure transfer via WebRTC
* Low latency / High resolution
* Simple Install via Docker / single binary
* Integrated TURN Server see [NAT Traversal](https://screego.net/#/nat-traversal)

[Demo / Public Instance](https://app.screego.net/) ᛫ [Installation](https://screego.net/#/install) ᛫ [Configuration](https://screego.net/#/config) 

## Versioning

We use [SemVer](http://semver.org/) for versioning. For the versions available, see the
[tags on this repository](https://github.com/screego/server/tags).

---

### Overview (`docs/README.md`)

# screego/server

In the past I've had some problems sharing my screen with coworkers using
corporate chatting solutions like Microsoft Teams. I wanted to show them some
of my code, but either the stream lagged several seconds behind or the quality
was so poor that my colleagues couldn't read the code. Or both.

That's why I created screego. It allows you to share your screen with good
quality and low latency. Screego is an addition to existing software and 
only helps to share your screen. Nothing else (:.


## Features

* Multi User Screenshare
* Secure transfer via WebRTC
* Low latency / High resolution
* Simple Install via [Docker](https://hub.docker.com/r/screego/server) / single binary
* Integrated [TURN](nat-traversal.md) Server see [NAT Traversal](nat-traversal.md)

---

[Demo / Public Instance](https://app.screego.net/) ᛫ [Installation](https://screego.net/#/install) ᛫ [Configuration](https://screego.net/#/config)

---

###  Sidebar (`docs/_sidebar.md`)

* [Home](/)
* [Installation](install.md)
* [Config](config.md)
* [NAT Traversal](nat-traversal.md)
* [Reverse Proxy](proxy.md)
* [Development](development.md)
* [FAQ](faq.md)
* [GitHub](https://github.com/screego/server)

---

### Config (`docs/config.md`)

# Config

!> TLS is required for Screego to work. Either enable TLS inside Screego or 
   use a reverse proxy to serve Screego via TLS.

Screego tries to obtain config values from different locations in sequence. 
Properties will never be overridden. Thus, the first occurrence of a setting will be used.

#### Order

* Environment Variables
* `screego.config.local` (in same path as the binary)
* `screego.config` (in same path as the binary)
* `$HOME/.config/screego/server.config`
* `/etc/screego/server.config`

#### Config Example

[screego.config.example](https://raw.githubusercontent.com/screego/server/master/screego.config.example ':include :type=code ini')

---

### Development (`docs/development.md`)

# Development

Screego requires:

- Go 1.15+
- Node 13.x
- Yarn 9+

## Setup

### Clone Repository

Clone screego/server source from git:

```bash
$ git clone https://github.com/screego/server.git && cd server
```

### GOPATH

If you are in GOPATH, enable [go modules](https://github.com/golang/go/wiki/Modules) explicitly:

```bash
$ export GO111MODULE=on
```

### Download Dependencies:

```bash
# Server
$ go mod download
# UI
$ (cd ui && yarn install)
```

## Start / Linting

### Backend

Create a file named `screego.config.development.local` inside the screego folder with the content:

```ini
SCREEGO_EXTERNAL_IP=YOURIP
```

and replace `YOURIP` with your external ip.

Start the server in development mode.

```bash
$ go run . serve
```

The backend is available on [http://localhost:5050](http://localhost:5050)

?> When accessing `localhost:5050` it is normal that there are panics with `no such file or directory`.
The UI will be started separately.

### Frontend

Start the UI development server.

_Commands must be executed inside the ui directory._

```bash
$ yarn start
```

Open [http://localhost:3000](http://localhost:3000) inside your favorite browser.

### Lint

Screego uses [golangci-lint](https://github.com/golangci/golangci-lint) for linting.

After installation you can check the source code with:

```bash
$ golangci-lint run
```

## Build

1. [Setup](#setup)

1. Build the UI

   ```bash
   $ (cd ui && yarn build)
   ```

1. Build the binary
   ```bash
   go build -ldflags "-X main.version=$(git describe --tags HEAD) -X main.mode=prod" -o screego ./main.go
   ```

---

### Faq (`docs/faq.md`)

# Frequently Asked Questions

## Stream doesn't load

Check that
* you are using https to access Screego.
* `SCREEGO_EXTERNAL_IP` is set to your external IP. See [Configuration](config.md)
* you are using TURN for NAT-Traversal. See [NAT-Traversal](nat-traversal.md). *On app.screego.net it's enabled without login; when self-hosting it requires user login*
* your browser doesn't block WebRTC (extensions or other settings)
* you have opened ports in your firewall. By default 5050, 3478 and any UDP port when using TURN.

## Automatically create room on join

Sometimes you want to reuse the screego room, but always have to recreate it.
By passing `create=true` in the url, you can automatically create the room if it does not exist.

Example: https://app.screego.net/?room=not-existing-room&create=true

---

### Install (`docs/install.md`)

# Installation

Latest Version: **GITHUB_VERSION**

Before starting Screego you may read [Configuration](config.md).

!> TLS is required for Screego to work. Either enable TLS inside Screego or 
   use a reverse proxy to serve Screego via TLS.

## Docker

Setting up Screego with docker is pretty easy, you basically just have to start the docker container, and you are ready to go:

[ghcr.io/screego/server](https://github.com/orgs/screego/packages/container/package/server) and
[screego/server](https://hub.docker.com/r/screego/server)
docker images are multi-arch docker images.
This means the image will work for `amd64`, `i386`, `ppc64le` (power pc), `riscv64`, `arm64`, `armv7` (Raspberry PI) and `armv6`.

By default, Screego runs on port 5050.

?> Replace `EXTERNALIP` with your external IP. One way to find your external ip is with ipify.
   `curl 'https://api.ipify.org'`

```bash
$ docker run --net=host -e SCREEGO_EXTERNAL_IP=EXTERNALIP ghcr.io/screego/server:GITHUB_VERSION
```

**docker-compose.yml**
```yaml
services:
  screego:
    image: ghcr.io/screego/server:GITHUB_VERSION
    network_mode: host
    environment:
      SCREEGO_EXTERNAL_IP: "EXTERNALIP"
```

If you don't want to use the host network, then you can configure docker like this:

<details><summary>(Click to expand)</summary>
<p>

!> Screego may not work correctly when deploying it in docker without `network_mode: host`.
   See [#226](https://github.com/screego/server/issues/226)

```bash
$ docker run -it \
    -e SCREEGO_EXTERNAL_IP=EXTERNALIP \
    -e SCREEGO_TURN_PORT_RANGE=50000:50200 \
    -p 5050:5050 \
    -p 3478:3478 \
    -p 50000-50200:50000-50200/udp \
    screego/server:GITHUB_VERSION
```

#### docker-compose.yml

```yml
version: "3.7"
services:
  screego:
    image: ghcr.io/screego/server:GITHUB_VERSION
    ports:
      - 5050:5050
      - 3478:3478
      - 50000-50200:50000-50200/udp
    environment:
      SCREEGO_EXTERNAL_IP: "192.168.178.2"
      SCREEGO_TURN_PORT_RANGE: "50000:50200"
```

</p>
</details>

## Binary

### Supported Platforms:

- linux_amd64 (64bit)
- linux_i386 (32bit)
- armv7 (32bit used for Raspberry Pi)
- armv6
- arm64 (ARMv8)
- ppc64
- ppc64le
- windows_i386.exe (32bit)
- windows_amd64.exe (64bit)

Download the zip with the binary for your platform from [screego/server Releases](https://github.com/screego/server/releases).

```bash
$ wget https://github.com/screego/server/releases/download/vGITHUB_VERSION/screego_GITHUB_VERSION_{PLATFORM}.tar.gz
```

Unzip the archive.

```bash
$ tar xvf screego_GITHUB_VERSION_{PLATFORM}.tar.gz
```

Make the binary executable (linux only).

```bash
$ chmod +x screego
```

Execute screego:

```bash
$ ./screego
# on windows
$ screego.exe
```

## Arch-Linux(aur)

!> Maintenance of the AUR Packages is not performed by the Screego team.
   You should always check the PKGBUILD before installing an AUR package.

Screego's latest release is available in the AUR as [screego-server](https://aur.archlinux.org/packages/screego-server/) and [screego-server-bin](https://aur.archlinux.org/packages/screego-server-bin/).
The development-version can be installed with [screego-server-git](https://aur.archlinux.org/packages/screego-server-git/).

## FreeBSD

!> Maintenance of the FreeBSD Package is not performed by the Screego team.
   Check yourself, if you can trust it.

```bash
$ pkg install screego
```

## Source

[See Development#build](development.md#build)

---

### Nat Traversal (`docs/nat-traversal.md`)

# NAT Traversal

In most cases peers cannot directly communicate with each other because of firewalls or other restrictions like NAT.
To work around this issue, WebRTC uses 
[Interactive Connectivity Establishment (ICE)](http://en.wikipedia.org/wiki/Interactive_Connectivity_Establishment).
This is a framework for helping to connect peers.

ICE uses STUN and/or TURN servers to accomplish this.

?> Screego exposes a STUN and TURN server. You don't have to configure this separately.
   By default, user authentication is required for using TURN.

## STUN

[Session Traversal Utilities for NAT (STUN)](http://en.wikipedia.org/wiki/STUN) is used to find
the public / external ip of a peer. This IP is later sent to others to create a direct connection.

When STUN is used, only the connection enstablishment will be done through Screego. The actual video stream will be
directly sent to the other peer and doesn't go through Screego.

While STUN should work for most cases, there are stricter NATs f.ex. 
[Symmetric NATs](https://en.wikipedia.org/wiki/Network_address_translation) 
where it doesn't, then, TURN will be used.

## TURN

[Traversal Using Relays around NAT (TURN)](http://en.wikipedia.org/wiki/TURN) is used to work around Symmetric NATs.
It does it by relaying all data through a TURN server. As relaying will create traffic on the server,
Screego will require user authentication to use the TURN server. This can be configured see [Configuration](config.md).

---

### Proxy (`docs/proxy.md`)

# Proxy

!> When using a proxy enable `SCREEGO_TRUST_PROXY_HEADERS`. See [Configuration](config.md).

## nginx

### At root path

```nginx
upstream screego {
  # Set this to the address configured in
  # SCREEGO_SERVER_ADDRESS. Default 5050
  server 127.0.0.1:5050;
}

server {
  listen 80;

  # Here goes your domain / subdomain
  server_name screego.example.com;

  location / {
    # Proxy to screego
    proxy_pass         http://screego;
    proxy_http_version 1.1;

    # Set headers for proxying WebSocket
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Connection "upgrade";
    proxy_redirect     http:// $scheme://;

    # Set proxy headers
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto http;

    # The proxy must preserve the host because screego verifies it with the origin
    # for WebSocket connections
    proxy_set_header   Host $http_host;
  }
}
```

### At a sub path

```nginx
upstream screego {
  # Set this to the address configured in
  # SCREEGO_SERVER_ADDRESS. Default 5050
  server 127.0.0.1:5050;
}

server {
  listen 80;

  # Here goes your domain / subdomain
  server_name screego.example.com;

  location /screego/ {
    rewrite ^/screego(/.*) $1 break;
  
    # Proxy to screego
    proxy_pass         http://screego;
    proxy_http_version 1.1;

    # Set headers for proxying WebSocket
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Connection "upgrade";
    proxy_redirect     http:// $scheme://;

    # Set proxy headers
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto http;

    # The proxy must preserve the host because screego verifies it with the origin
    # for WebSocket connections
    proxy_set_header   Host $http_host;
  }
}
```

## Apache (httpd)

The following modules are required:

* mod_proxy
* mod_proxy_wstunnel
* mod_proxy_http

### At root path

```apache
<VirtualHost *:80>
    ServerName screego.example.com
    Keepalive On

    # The proxy must preserve the host because screego verifies it with the origin
    # for WebSocket connections
    ProxyPreserveHost On

    # Replace 5050 with the port defined in SCREEGO_SERVER_ADDRESS.
    # Default 5050

    # Proxy web socket requests to /stream
    ProxyPass "/stream" ws://127.0.0.1:5050/stream retry=0 timeout=5

    # Proxy all other requests to /
    ProxyPass "/" http://127.0.0.1:5050/ retry=0 timeout=5

    ProxyPassReverse / http://127.0.0.1:5050/
</VirtualHost>
```

### At a sub path

```apache
<VirtualHost *:80>
    ServerName screego.example.com
    Keepalive On

    Redirect 301 "/screego" "/screego/"

    # The proxy must preserve the host because screego verifies it with the origin
    # for WebSocket connections
    ProxyPreserveHost On

    # Proxy web socket requests to /stream
    ProxyPass "/screego/stream" ws://127.0.0.1:5050/stream retry=0 timeout=5

    # Proxy all other requests to /
    ProxyPass "/screego/" http://127.0.0.1:5050/ retry=0 timeout=5
    #                 ^- !!trailing slash is required!!

    ProxyPassReverse /screego/ http://127.0.0.1:5050/
</VirtualHost>
```

---

--- METRICS ---
- Files Extracted: 9
- Estimated Token Budget: ~3650 tokens
- Canonical Reference: https://codewiki.google/github.com/screego/server
