Container image for eturnal STUN/TURN Server
View Sourceeturnal container images are available for multiple
architectures as ghcr.io/processone/eturnal
from GitHub Packages
or DockerHub.
Starting from releases newer than 1.12.1
container images are built using
the glibc
based binaries and Wolfi OS. The
Alpine Linux based images are still available, but
have a tag suffix -alpine
, i.e. ghcr.io/processone/eturnal:latest-alpine
.
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.
Tags | Description | Additional notes |
---|---|---|
edge | Built from master branch, see changelog | For testing purposes. |
1.12.2 , latest | Release changelog | |
1.12.2-acme , acme | As the standalone image, but including the acme.sh | Variant specific documentation |
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 tostdout
ineturnal.yml
.The container attempts to autodetect the
relay_ipv4_address
andrelay_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
(andrelay_ipv6_address
) either within a mountedeturnal.yml
file or with theETURNAL_RELAY_IPV4_ADDR
(andETURNAL_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 thedocker run
command.
- This STUN service may be exchanged by defining a different external STUN
service with the
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 usereturnal
needs to escalateNET_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.
Note: All variables can be defined as secrets with a __FILE
suffix:
printf "secret" | podman secret create eturnal_secret -
podman run \
... \
--secret eturnal_secret \
-e ETURNAL_SECRET__FILE='/run/secrets/eturnal_secret' \
ghcr.io/processone/eturnal:latest
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.