diff --git a/runtime/Dockerfile.intel b/runtime/Dockerfile.intel index 3f0ee230..bf49e444 100644 --- a/runtime/Dockerfile.intel +++ b/runtime/Dockerfile.intel @@ -82,12 +82,14 @@ RUN set -eux; \ # copy runtime configs COPY --chown=neko:neko .Xresources /home/$USERNAME/.Xresources COPY dbus /usr/bin/dbus +COPY intel/neko-serve /usr/bin/neko-serve COPY default.pa /etc/pulse/default.pa COPY supervisord.conf /etc/neko/supervisord.conf COPY supervisord.dbus.conf /etc/neko/supervisord.dbus.conf +COPY intel/supervisord.neko.conf /etc/neko/supervisord/neko.conf COPY xorg.conf /etc/neko/xorg.conf COPY intel/add-render-group.sh /usr/bin/add-render-group.sh -COPY intel/supervisord.rendergroup.conf /etc/neko/supervisord/supervisord.rendergroup.conf +COPY intel/entrypoint.sh /usr/bin/entrypoint.sh # # copy runtime folders @@ -106,6 +108,10 @@ ENV NEKO_PLUGINS_ENABLED=true ENV NEKO_PLUGINS_DIR=/etc/neko/plugins/ ENV NEKO_HWENC=VAAPI ENV RENDER_GID= +# libva does not initialize the X11 display without an explicitly selected +# driver here ('vaGetDriverNames() failed'), and the GStreamer VA plugin scan +# uses X11. This image only ships the iHD driver (intel-media-va-driver-non-free). +ENV LIBVA_DRIVER_NAME=iHD # # add healthcheck @@ -116,4 +122,5 @@ HEALTHCHECK --interval=10s --timeout=5s --retries=8 \ # # run neko +ENTRYPOINT ["/usr/bin/entrypoint.sh"] CMD ["/usr/bin/supervisord", "-c", "/etc/neko/supervisord.conf"] diff --git a/runtime/intel/entrypoint.sh b/runtime/intel/entrypoint.sh new file mode 100755 index 00000000..a00b4767 --- /dev/null +++ b/runtime/intel/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# supervisord reads /etc/group to determine the supplementary groups of every +# program it spawns, so the render group has to be assigned before supervisord +# starts. Doing it from a program spawned by supervisord (as the previous +# 'rendergroup-init' did) races with the neko program: neko is usually spawned +# before 'usermod' has finished and is left without access to /dev/dri/render*, +# which in turn makes the VA-API encoders fail to register. +# +# Assign the render group to the neko user first, then hand over to supervisord. +if ! /usr/bin/add-render-group.sh; then + echo "entrypoint: could not assign the render group, VA-API may not work (is /dev/dri passed to the container?)" >&2 +fi + +exec "$@" diff --git a/runtime/intel/neko-serve b/runtime/intel/neko-serve new file mode 100755 index 00000000..8f8bab19 --- /dev/null +++ b/runtime/intel/neko-serve @@ -0,0 +1,26 @@ +#!/bin/sh + +# GStreamer only registers the VA-API elements (e.g. vah264enc) if a usable VA +# display is found while the plugins are scanned for the first time, and the +# result of that scan is cached in the user's registry. supervisord starts the +# X server and neko in the same pass, so without waiting here neko can scan the +# plugins before X (and therefore VA-API) is usable. The cache then lacks the +# encoder elements and every client connect fails with +# '(pipeline error) no element "vah264enc"'. +# +# Wait until VA is usable through X, then drop any stale registry, so that the +# first scan of this process happens with a working VA display. +i=0 +while [ "$i" -lt 30 ]; do + if vainfo >/dev/null 2>&1; then break; fi + sleep 1 + i=$((i + 1)) +done + +if [ "$i" -ge 30 ]; then + echo "neko-serve: VA-API was not usable after 30s, starting neko anyway" >&2 +fi + +rm -f "$HOME/.cache/gstreamer-1.0/registry."* + +exec /usr/bin/neko serve "$@" diff --git a/runtime/intel/supervisord.neko.conf b/runtime/intel/supervisord.neko.conf new file mode 100644 index 00000000..37d5e47d --- /dev/null +++ b/runtime/intel/supervisord.neko.conf @@ -0,0 +1,16 @@ +# supervisord reads the files matched by [include] after the main config, and +# the last definition of a program wins, so this overrides the [program:neko] +# block from /etc/neko/supervisord.conf. Only the intel image ships +# /usr/bin/neko-serve. Keep the two blocks in sync. +[program:neko] +environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s",DISPLAY="%(ENV_DISPLAY)s" +command=/usr/bin/neko-serve --server.static "/var/www" +stopsignal=INT +stopwaitsecs=3 +autorestart=true +priority=800 +user=%(ENV_USER)s +stdout_logfile=/var/log/neko/neko.log +stdout_logfile_maxbytes=100MB +stdout_logfile_backups=10 +redirect_stderr=true diff --git a/runtime/intel/supervisord.rendergroup.conf b/runtime/intel/supervisord.rendergroup.conf deleted file mode 100644 index 8a187080..00000000 --- a/runtime/intel/supervisord.rendergroup.conf +++ /dev/null @@ -1,12 +0,0 @@ -[program:rendergroup-init] -environment=RENDER_GID="%(ENV_RENDER_GID)s",USER="%(ENV_USER)s" -command=/usr/bin/add-render-group.sh -startsecs=0 -startretries=0 -autorestart=false -priority=10 -user=root -stdout_logfile=/var/log/neko/rendergroup.log -stdout_logfile_maxbytes=1MB -stdout_logfile_backups=10 -redirect_stderr=true