## 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"