Search code examples
pythonpyinstallergitlab-cix11xorg

Is it possible to run X11 on Gitlab CI?


I'm trying to use pyinstaller to build a python game into a binary file. I had it working, but today I switched to using arcade instead of pygame. I can build this fine locally, but when pyinstaller is building, pyglet throws an exception saying that it can't find the X11 library. I installed xorg before building it, and not it throws an exception just saying that it can't connect to a display server. Here is the full traceback:

$ pyinstaller -F biogame.spec
39 INFO: PyInstaller: 4.1
39 INFO: Python: 3.8.5
50 INFO: Platform: Linux-4.19.78-coreos-x86_64-with-glibc2.29
52 INFO: UPX is not available.
54 INFO: Extending PYTHONPATH with paths
['/builds/TabulateJarl8/biogame', '/builds/TabulateJarl8/biogame']
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/pyglet/__init__.py", line 337, in __getattr__
    return getattr(self._module, name)
AttributeError: 'NoneType' object has no attribute 'Window'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/local/bin/pyinstaller", line 8, in <module>
    sys.exit(run())
  File "/usr/local/lib/python3.8/dist-packages/PyInstaller/__main__.py", line 114, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "/usr/local/lib/python3.8/dist-packages/PyInstaller/__main__.py", line 65, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "/usr/local/lib/python3.8/dist-packages/PyInstaller/building/build_main.py", line 720, in main
    build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "/usr/local/lib/python3.8/dist-packages/PyInstaller/building/build_main.py", line 667, in build
    exec(code, spec_namespace)
  File "biogame.spec", line 8, in <module>
    a = Analysis(['biogame.py'],
  File "/usr/local/lib/python3.8/dist-packages/PyInstaller/building/build_main.py", line 212, in __init__
    self.hookspath += list(entry_point.load()())
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2445, in load
    return self.resolve()
  File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 2451, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/local/lib/python3.8/dist-packages/arcade/__init__.py", line 72, in <module>
    from .window_commands import close_window
  File "/usr/local/lib/python3.8/dist-packages/arcade/window_commands.py", line 106, in <module>
    def get_window() -> pyglet.window.Window:
  File "/usr/local/lib/python3.8/dist-packages/pyglet/__init__.py", line 343, in __getattr__
    __import__(import_name)
  File "/usr/local/lib/python3.8/dist-packages/pyglet/window/__init__.py", line 1897, in <module>
    gl._create_shadow_window()
  File "/usr/local/lib/python3.8/dist-packages/pyglet/gl/__init__.py", line 206, in _create_shadow_window
    _shadow_window = Window(width=1, height=1, visible=False)
  File "/usr/local/lib/python3.8/dist-packages/pyglet/window/xlib/__init__.py", line 173, in __init__
    super(XlibWindow, self).__init__(*args, **kwargs)
  File "/usr/local/lib/python3.8/dist-packages/pyglet/window/__init__.py", line 585, in __init__
    display = pyglet.canvas.get_display()
  File "/usr/local/lib/python3.8/dist-packages/pyglet/canvas/__init__.py", line 94, in get_display
    return Display()
  File "/usr/local/lib/python3.8/dist-packages/pyglet/canvas/xlib.py", line 123, in __init__
    raise NoSuchDisplayException('Cannot connect to "%s"' % name)
pyglet.canvas.xlib.NoSuchDisplayException: Cannot connect to "None"

I tried running xinit but that just errored out since there isn't any display, I tried xrandr but that failed as well, and I also tried doing export DISPLAY=:0 which didn't help. Is there any way to get X11 running on Gitlab CI or is this impossible? Here's the section of my CI file that's relevant:

ubuntubuild:
    image: ubuntu:latest
    stage: ubuntubuild
    before_script:
        - apt update
        - DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends python3-pip python3-dev libjpeg-dev zlib1g-dev xorg
        - python3 -m pip install pyinstaller
        - python3 -m pip install -r requirements.txt
    script:
        - pyinstaller -F biogame.spec
    artifacts:
        paths:
            - dist/biogame

UPDATE 1:

I managed to get Xvfb running but now pyglet throws an error saying pyglet.gl.glx_info.GLXInfoException: pyglet requires an X server with GLX. I've tried to tweak the Xvfb to be Xvfb :1 -screen 0 1152x900x8 +extension GLX +render -noreset &, and I've tried installing these packages: mesa-common-dev libgl1-mesa-glx libgl1-mesa-dev libglu1-mesa-dev


Solution

  • I finally figured out how to fix it. I installed these packages and ran pyinstaller with xvfb-run

    sudo apt install xorg-dev libglu1-mesa libgl1-mesa-dev xvfb libxinerama1 libxcursor1
    xvfb-run -a -s "-screen 0 1400x900x24 +extension RANDR" -- pyinstaller -F biogame.spec