## title: Play Teeworlds through Docker
## date: "2023-10-24"
Many Teeworlds servers currently in use are containerized.
However, it is also possible to containerize the Teeworlds
client using Docker.
The Dockerfile is available below, it compiles and executes
the ELF file in the Docker container. I've also published
the image on Docker's public registry, Docker Hub.
## Build the Docker image
So there are two methods to get the Docker image, you can
download it or building it yourself.
### Pull from Docker Hub
docker pull b0thr34l/teeworlds:1.0
### Build from source
FROM ubuntu:20.04 as build
# Avoid tz stuck at installation
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Moscow
# Install dependencies to build binaries
RUN apt-get update -y &&
apt-get -y install --no-install-recommends
ca-certificates
build-essential
cmake
git
libfreetype6-dev
libsdl2-dev
libpnglite-dev
libwavpack-dev
# Clone the git repository
RUN git clone https://github.com/teeworlds/teeworlds /client
# Go into the build directory
WORKDIR /client
# Compile client only
RUN mkdir -p build &&
cd build &&
cmake .. &&
make teeworlds
FROM ubuntu:20.04 as run
# Install the shared library
RUN apt-get update -y &&
apt-get -y install --no-install-recommends
libfreetype6
libsdl2-2.0-0
libpnglite0
libwavpack1
libopengl0
libgl1
# Create a new user
RUN useradd -ms /bin/bash tee
USER tee
WORKDIR /teeworlds
# Copy the output files
COPY --from=build /client/build/data ./data
COPY --from=build /client/build/teeworlds .
CMD [ "./teeworlds" ]
## Create and start the Docker container
Now we can create and start a new container with the
teeworlds client image we just created or downloaded.
I consider that you're using X as your windowing system,
rather than something like Wayland or something else.
### X display server
So that the game can work and we can play it. I assume you
are using an X display server and that it is listening at a
UNIX domain socket.
That is why we are forwarding the /tmp/.X11-unix/ directory
that contains the UNIX domain socket(s) for the X server.
The DISPLAY environment variable is going to target the UNIX
socket that we are using. This means that, technically, the
container will be able to write data to this UNIX socket,
and thus create a new window.
Make sure that your X server controll is configured
correctly before running the Docker container. If you just
want to try you could disable entirely the policies but it
is not recommended.
xhost +
Instead, you should add a single local user.
xhost +si:localuser:$USER
### Storage configuration
Teeworlds uses a specific location to store its data, it is
described in a file named storage.cfg that we can find on
the offical Teeworlds GitHub repository.
(HTM) offical Teeworlds GitHub repository
We are looking for $USERDIR, we are going to mount this
directory into our Docker container.
The first option is to create a new Docker volume containing
the Teeworlds user data. We don't want to override the
container directory, so we will create a shared Docker
volume.
#!/bin/sh
TW_USERDIR=$HOME/.config/teeworlds-userdir
TW_DOCKER_VOLUME=teeworlds-userdir
mkdir -p ${TW_USERDIR}
docker volume create
--driver local
--opt type=none
--opt device=${TW_USERDIR}
--opt o=bind
${TW_DOCKER_VOLUME}
docker run -it
-e "DISPLAY=$DISPLAY"
-v "/tmp/.X11-unix:/tmp/.X11-unix"
-v "${TW_DOCKER_VOLUME}:/home/tee/.local/share/teeworlds"
--device "/dev/snd"
--device "/dev/dri"
b0thr34l/teeworlds:1.0
If you already had Teeworlds data in an user directory on
your host system. You can mount a volume directly without
creating a Docker volume, as shown in the example below.
-v "$HOME/.teeworlds:/home/tee/.local/share/teeworlds"