View Source Container image for eturnal STUN/TURN Server

eturnal container images are available for multiple architectures as ghcr.io/processone/eturnal from GitHub Packages or DockerHub. The images are based on Alpine Linux.

Tags and variants

XX.YY.ZZ represents the official eturnal release, a -AA suffix the image version of a particular release in case of any bug fix etc. of the image.

TagsDescriptionAdditional notes
edgeBuilt from master branch, see changelogFor testing purposes.
1.12.0, latestRelease changelog

Images are scanned daily by Trivy and, if necessary, the latest release will be rebuilt and updated.

Getting started

Note: the below commands can be run with podman as well, just use podman as an equivalent: alias docker=podman

To pull the image:

docker pull ghcr.io/processone/eturnal:latest

This will run a container named eturnal with the default, unprivileged user eturnal (uid=9000) in foreground mode with default ports published, if started this way:

docker run -d --rm \
    --name eturnal \
    -p 3478:3478 \
    -p 3478:3478/udp \
    -p 49152-65535:49152-65535/udp \
  ghcr.io/processone/eturnal:latest

Recommended: The container can also run in a less privileged mode:

docker run -d --rm \
    --name eturnal \
    --read-only \
    --cap-drop=ALL \
    --security-opt no-new-privileges \
    -p 3478:3478 \
    -p 3478:3478/udp \
    -p 49152-65535:49152-65535/udp \
  ghcr.io/processone/eturnal:latest

Note: Stating --cap-add=NET_BIND_SERVICE may be needed here depending on the container runtime, see e.g. Docker

Only relevant for Docker, not Podman: Since Docker does not perform well with large port ranges, consider decreasing the TURN default port range, e.g. through environment variables:

docker run -d --rm \
    --name eturnal \
    --read-only \
    --cap-drop=ALL \
    --security-opt no-new-privileges \
    -p 3478:3478 \
    -p 3478:3478/udp \
    -p 50000-50500:50000-50500/udp \
    -e ETURNAL_RELAY_MIN_PORT=50000 \
    -e ETURNAL_RELAY_MAX_PORT=50500 \
  ghcr.io/processone/eturnal:latest

Or use the host network by adding --network=host to the command line:

docker run -d --rm \
    --name eturnal \
    --read-only \
    --cap-drop=ALL \
    --security-opt no-new-privileges \
    --network=host \
  ghcr.io/processone/eturnal:latest

Note: The container is no longer isolated from the host network when using this option.

Inspect the running container with:

docker logs eturnal

To use the eturnalctl command, e.g. just run:

docker exec eturnal eturnalctl info

Stop the running container with:

docker stop eturnal

Configuration

Configuration is mainly done by a mounted eturnal.yml file (recommended), see the example configuration file. The file must be readable by the eturnal user (e.g. chown 9000:9000 and chmod 640). Mountpath, e.g. with docker run add:

-v /path/to/eturnal.yml:/etc/eturnal.yml:ro

eturnal may also be configured by specifying certain environment variables, see the documentation. Here are some more hints how to configure eturnal.

General hints:

  • For logs to be printed with the docker logs command, log_dir: should be set to stdout in eturnal.yml.

  • The container attempts to autodetect the relay_ipv4_address and relay_ipv6_address using an external STUN service.

    • This STUN service may be exchanged by defining a different external STUN service with the STUN_SERVICE environment variable, which defaults to: STUN_SERVICE="stun.conversations.im 3478". Note: the stun client only supports UDP queries.
    • If that fails, consider defining the relay_ipv4_address (and relay_ipv6_address) either within a mounted eturnal.yml file or with the ETURNAL_RELAY_IPV4_ADDR (and ETURNAL_RELAY_IPV6_ADDR) environment variable to enable the TURN service. Note: the IPv6 address is optional.
    • If the external STUN lookup is not desired, define the environment variable STUN_SERVICE=false in the docker run command.
  • If eturnal shall bind to privileged ports (<1024) directly, there are two ways to accomplish that:

    • The eturnal container has the capability NET_BIND_SERVICE included and the option --security-opt no-new-privileges is not set, since the unprivileged container user eturnal needs to escalate NET_BIND_SERVICE.

    • You enable binding to privileged ports system-wide through defining the lowest port:

      sysctl net.ipv4.ip_unprivileged_port_start=80

      This also works in kubernetes.

    Hint: Newer Docker versions set this option during install already.

Custom TLS certificates and dh-parameter file

To use eturnal's TLS listener with cutsom TLS certificates/dh-parameter files they must be mounted into the container and referenced in the eturnal.yml file. TLS certificates and the dh-parameter file shall be .pem files. They must be readable by the eturnal user/group and should not have world-readable access rights (e.g. chown 9000:9000 and chmod 440). Mountpath, e.g. with docker run add:

-v /path/to/tls-files:/opt/eturnal/tls:ro

Rootless environments:

  • If eturnal runs in rootless environments, e.g. podman rootless, then file permissions and editing files must be performed within the same user namespace as the container runs in. More information here.
  • The "magic" command in e.g. podman rootless is called podman unshare.
  • To change e.g. the file permissions for eturnal.yml use:
podman unshare chown 9000:9000 /path/to/eturnal.yml
podman unshare chmod 640 /path/to/eturnal.yml

Deployment examples

This repository also contains configuration examples for:

Building yourself

Instructions can be found here.