Based on the following guide: https://ericdraken.com/running-xvfb-on-a-shared-host-without-x/
Using the following docker image: https://hub.docker.com/r/lambci/lambda/
It's an Amazon Linux image that matches the environment of Lambda tasks.
# On my Mac, from the directory where I'll be working on my lambda function.
$ docker run -v "$PWD":/var/task -it lambci/lambda:build bash
# bash-4.2#
We'll need some utils that it comes with.
$ yum install xorg-x11-server-Xvfb.x86_64 wget
$ cd /tmp
$ wget https://www.x.org/releases/X11R7.7/src/xserver/xorg-server-1.12.2.tar.gz
$ tar -xvf xorg-server-1.12.2.tar.gz
$ cd xorg-server-1.12.2
Edit xkb/xkbInit.c
at line 754 in XkbProcessArguments()
return 2;
}
// ADDED - Change xkbcomp bin directory with an environment variable
char *xkbBinDir = getenv("XKB_BINDIR");
if (xkbBinDir) {
XkbBinDirectory = Xstrdup(xkbBinDir);
}
// ADDED - Change base xkb directory with an environment variable
char *xkbBaseDir = getenv("XKBDIR");
if (xkbBaseDir) {
XkbBaseDirectory = Xstrdup(xkbBaseDir);
}
return 0;
}
Edit xkb/ddxLoad.c
at line 188 in XkbDDXCompileKeymapByNames()
const char *emptystring = "";
char *xkbbasedirflag = NULL;
const char *xkbbindir = emptystring;
const char *xkbbindirsep = emptystring;
#ifdef WIN32
char tmpname[PATH_MAX];
const char *xkmfile = tmpname;
#else
// MODIFICATION - Now using 'default.xkm' file to satisfy xkbcomp
// const char *xkmfile = "-";
const char *xkmfile = "default.xkm";
#endif
Contents for default.xkb
:
xkb_keymap "default" {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compatibility { include "complete" };
xkb_symbols { include "pc+us+inet(evdev)" };
xkb_geometry { include "pc(pc105)" };
};
Create and compile it:
$ cd /tmp
$ vim default.xkb
# Insert contents above and save
$ xkbcomp -xkm default.xkb
Copy it into your lambda function /lib
$ mkdir /var/task/lib
$ cp default.xkm /var/task/lib
$ yum install pixman-devel.x86_64 \
libdrm-devel.x86_64 \
libX11-devel.x86_64 \
mesa-libGL-devel.x86_64 \
openssl-devel.x86_64 \
xorg-x11-xtrans-devel.noarch \
libxkbfile-devel.x86_64 \
libXfont-devel.x86_64 \
libpciaccess-devel.x86_64 \
xcb-util-keysyms-devel.x86_64
$ ./configure
$ make
$ cp hw/vfb/Xvfb /var/task/lib
# cd (your task directory)
$ docker run -v "$PWD":/var/task -it lambci/lambda:build bash
Looks ok?
$ ls -la /var/task/lib
total 10812
drwxr-xr-x 5 root root 170 Dec 2 23:55 .
drwxr-xr-x 4 root root 136 Dec 2 23:28 ..
-rw-r--r-- 1 root root 314 Dec 2 23:43 default.xkb
-rw-r--r-- 1 root root 11248 Dec 2 23:43 default.xkm
-rwxr-xr-x 1 root root 11054660 Dec 2 23:55 Xvfb
$ cd /var/task/lib
$ ldd ./Xvfb
linux-vdso.so.1 => (0x00007ffdc6f1a000)
libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f10f11ca000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f10f0fc5000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f10f0da9000)
libpixman-1.so.0 => /usr/lib64/libpixman-1.so.0 (0x00007f10f0afe000)
libXfont.so.1 => /usr/lib64/libXfont.so.1 (0x00007f10f08c9000)
libXau.so.6 => /usr/lib64/libXau.so.6 (0x00007f10f06c6000)
libm.so.6 => /lib64/libm.so.6 (0x00007f10f03c4000)
libc.so.6 => /lib64/libc.so.6 (0x00007f10f0001000)
libz.so.1 => /lib64/libz.so.1 (0x00007f10efdeb000)
/lib64/ld-linux-x86-64.so.2 (0x000056118b113000)
libfreetype.so.6 => /usr/lib64/libfreetype.so.6 (0x00007f10efb4f000)
libfontenc.so.1 => /usr/lib64/libfontenc.so.1 (0x00007f10ef947000)
First, set the environment variables for keymap:
$ export XKB_BINDIR=/usr/bin
$ export XKBDIR=/var/task/lib
Fails with keymap error.
$ ./Xvfb :99
[dix] Could not init font path element /usr/share/fonts/X11/misc/, removing from list!
[dix] Could not init font path element /usr/share/fonts/X11/TTF/, removing from list!
[dix] Could not init font path element /usr/share/fonts/X11/OTF/, removing from list!
[dix] Could not init font path element /usr/share/fonts/X11/Type1/, removing from list!
[dix] Could not init font path element /usr/share/fonts/X11/100dpi/, removing from list!
[dix] Could not init font path element /usr/share/fonts/X11/75dpi/, removing from list!
XKB: Failed to compile keymap
Keyboard initialization failed. This could be a missing or incorrect setup of xkeyboard-config.
- I assume the target machine needs
XKBDIR
andXKB_BINDIR
, but since the machine in question doesn't have X11, it doesn't havexkbcomp
, so does that mean I need to compile that from source also? - Font errors above, not sure about that.
@ericdraken Tried setting the env variables (first trying to get it to run on the same container as I'm building it on). No luck. Note that the function mentioned in your original article in
ddxLoad.c
doesn't exist, and I edited the (similar looking) code at the location mentioned above. Wonder if that is a factor. Or it could be something else different between the lambda environment and the CentOS you were originally working with.WIsh I had more experience with how to debug this stuff (even adding printf or something in the source code).
If you do get a chance to look at this any more I would love to send you an AMZ gift-card or something!