mviereck / x11docker Goto Github PK
View Code? Open in Web Editor NEWRun GUI applications and desktops in docker and podman containers. Focus on security.
License: MIT License
Run GUI applications and desktops in docker and podman containers. Focus on security.
License: MIT License
This may be a naive or dumb question, but what are your thoughts on running X or Wayland entirely within a container? Assuming this is possible, it seems that you could eliminate virtually all host requirements (aside from Docker itself, of course) for x11docker. Some light Googling on the subject indicates that folks have had some success running X in a (privileged) container.
As a non-expert on X or Wayland, I think it would be incredibly convenient to not have to worry about which packages I need on the host. This could also lead to some really neat compose files that would fire up GUI apps with essentially no host requirements.
Does that make sense? Thoughts?
x11docker ERROR: Docker startup seems to have failed!
Last lines of docker.log:
27 export TERM=xterm
28 export HOME=/home/jan
29
30 env > /x11docker/environment
31 sed -i "/\(PWD=\|_=\)/d" /x11docker/environment
32
33 cd "$HOME"
34
35 exec $Dbus /usr/bin/kaptain /x11docker.kaptn >>/x11docker/stdout 2>>/x11docker/stderr
36 # Ready for docker run
Last lines of xterm.log:
Error: No such container: x11docker_X0_284fda_x11docker_kaptain
x11docker: container not ready on 8. attempt, trying again.
Error: No such container: x11docker_X0_284fda_x11docker_kaptain
x11docker: container not ready on 9. attempt, trying again.
Error: No such container: x11docker_X0_284fda_x11docker_kaptain
x11docker: container not ready on 10. attempt, trying again.
Error response from daemon: no such image: x11docker_X0_284fda_x11docker_kaptain: invalid reference format: repository name must be lowercase
x11docker: container IP:
x11docker: container PID:
Error: No such container: x11docker_X0_284fda_x11docker_kaptain
Docker daemon messages:
Error response from daemon: Container 97c6d821f537ff2e6822c05444409cdbd4f6eae22495e439811b521575a80125 is not running
docker: Error response from daemon: exec: "docker-init": executable file not found in $PATH.
Error response from daemon: no such image: x11docker_X0_284fda_x11docker_kaptain: invalid reference format: repository name must be lowercase
Coming #49.
On Windows 10, I start Xming from a MINGW64 (MSYS2) shell:
XMING_PATH="/c/Program\ Files\ \(x86\)/Xming/Xming.exe"
$XMING_PATH -ac -multiwindow -clipboard
Then, I can execute containers with GUI apps:
docker run -e DISPLAY="`ipconfig | grep 'IPv4' | grep -o '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' | grep "^10\.0\.*"`:0" 11384eb/sozi sozi
Or, just to make it cleaner:
DOCKER_DISPLAY="`ipconfig | grep 'IPv4' | grep -o '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' | grep "^10\.0\.*"`:0"
docker run -e DISPLAY="$DOCKER_DISPLAY" 11384eb/sozi sozi
So, I tried using x11docker:
export DISPLAY="`ipconfig | grep 'IPv4' | grep -o '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' | grep "^10\.0\.*"`:0"
x11docker 11384eb/sozi sozi
But this is the output I get:
$ ./x11docker 11384eb/sozi sozi
./x11docker: line 1146: pstree: command not found
./x11docker: line 1255: /etc/os-release: No such file or directory
x11docker ERROR: Could not find user 'my_user_name' in /etc/passwd.
Type 'x11docker --help' for usage information
For debugging, run x11docker in terminal and/or enable option '--verbose'
or look afterwards at logfile
Please report issues at https://github.com/mviereck/x11docker
./x11docker: line 453: pstree: command not found
x11docker note: Found remaining container process. Most probably the X session was
interrupted. Can not stop container because x11docker does not run as root.
Will wait up to 10 seconds for docker to finish.
x11docker note: Waiting for container to terminate ...
x11docker note: Waiting for container to terminate ...
...
x11docker note: Container did not terminate as it should.
Will not clean cache to avoid file permission issues.
You can remove the new container with command:
docker rm -f
Afterwards, remove cache files with:
rm -R
or let x11docker do the cleanup work for you:
x11docker --cleanup
Adding --hostdiplay
didn't help. The error is produced because /etc/passwd
does not exist. What's the suggested approach?
I tried docker run's --detach
but it doesn't detach
x11docker --hostdisplay -- "--detach --cap-add=SYS_PTRACE" my_image my-command.sh
Or tricks like adding &
at the end of command, disown
, nohup
should work fine?
thx for you tip, but it does not work for me. I get this error message :(
xf86OpenConsole: Cannot open virtual console 8 (Permission denied)
when i run
/x11docker -v -exec xeye
full log->
Distributor ID: Ubuntu
Description: Ubuntu 16.04.1 LTS
Release: 16.04
Codename: xenial
Linux ntb-sodd 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Containers: 3
Running: 1
Paused: 0
Stopped: 2
Images: 81
Server Version: 1.13.0
Storage Driver: btrfs
Build Version: Btrfs v4.4
Library Version: 101
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 03e5862ec0d8d3b3f750e19fca3ee367e13c090e
runc version: 2f7393a47307a16f8cee44a37b262e8b81021e3e
init version: 949e6fa
Security Options:
apparmor
seccomp
Profile: default
Kernel Version: 4.4.0-62-generic
Operating System: Ubuntu 16.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 15.56 GiB
Name: ntb-tejr
ID: ACEB:5UDC:2WVO:H7HV:EVH2:5CVD:DW7F:PT2J:PAV3:SW6L:RKK4:FKEV
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
./x11docker -v -exec xeye
x11docker WARNING: could not find VirtualGL.
It has to be installed on host to use option --virtualgl.
You can get in here: http://www.virtualgl.org/
Fallback: disabling option --virtualgl
x11docker WARNING: could not find executable 'xpra'.
Try 'apt-get install xpra' to install xpra.
Fallback: x11docker will try to use Xephyr (option --xephyr)
x11docker WARNING: could not find executable 'Xephyr'.
Try 'apt-get install xephyr' to install Xephyr.
Fallback: x11docker will try to use core X (option --X11)
x11docker WARNING: Need a window manager, but not found.
Will look for another one. Look at 'x11docker --help' to see a list
of recommended window managers.
x11docker WARNING: Will use window manager '/usr/bin/xfwm4'
x11docker WARNING: Cannot share clipboard. Need package 'xclip' to be
installed. Try installing xclip with command: 'apt-get install xclip'
x11docker: Found free display :1
x11docker: As X server will be used: X11
x11docker: IP of docker interface is 172.17.0.1/16
x11docker: As display for the container :1 will be used
x11docker: Created docker command:
# dontrundocker xeye
x11docker: Created X server command:
/usr/bin/X :1 vt8 +extension Composite +extension RANDR +extension RENDER +extension GLX +extension XVideo +extension DOUBLE-BUFFER +iglx +extension X-Resource +extension SECURITY +extension DAMAGE -auth /home/sodd/.cache/x11docker/X1/Xservercookie -retro -extension MIT-SHM -nolisten tcp +extension XFree86-DRI +extension XFree86-DGA +extension XFree86-VidModeExtension -verbose -extension XTEST
x11docker: Found window manager: '/usr/bin/xfwm4'
x11docker: Created xinitrc: #! /bin/bash
set -x # make bash verbose
BGPIDFILE=/home/sodd/.cache/x11docker/X1/backgroundpids
storepid ()
{
echo $1 $2 >> $BGPIDFILE
}
# set X variables to host display
export DISPLAY=:0.0
export XAUTHORITY=/home/sodd/.Xauthority
no_xhost ()
{
xhost | tail -n +2 /dev/stdin | while read LINE; do
xhost -$LINE;
done;
xhost -
}
# create empty Xcookie file
:> /home/sodd/.cache/x11docker/X1/Xclientcookie
# set X variables to new display
export DISPLAY=:1
export XAUTHORITY=/home/sodd/.cache/x11docker/X1/Xclientcookie
# set background color of root window. #7F7F7F is color of xfwm4 background
xsetroot -solid "#7F7F7F"
# create new XAUTHORITY cookies
xauth generate :1 . untrusted
cp /home/sodd/.cache/x11docker/X1/Xclientcookie /home/sodd/.cache/x11docker/X1/Xservercookie
xauth list
# start window manager, if defined
/usr/bin/xfwm4 &
WINDOWMANAGERPID=$!
storepid $! xfwm4
# disable any possible access to new X server granted by xhost
no_xhost
# run host application (window manager is already running)
xeye &
storepid $! xeye
wait $!
# clean up background jobs
# ( can already be empty, see case onlyX above. maybe window manager wasn't running at all)
XINITJOBSTOKILL="$XINITJOBSTOKILL $WINDOWMANAGERPID"
for ARGUMENT in $XINITJOBSTOKILL ; do kill $ARGUMENT ; done
# set X variables back to host display
export DISPLAY=:0.0
export XAUTHORITY=/home/sodd/.Xauthority
cat: /home/sodd/.cache/x11docker/X1/xtermrc: No such file or directory
x11docker: Created xtermrc:
x11docker: Logfiles are:
/home/sodd/.cache/x11docker/X1/xinit.log
/home/sodd/.cache/x11docker/X1/xpraserver.log
/home/sodd/.cache/x11docker/X1/xterm.log
/home/sodd/.cache/x11docker/X1/docker.log
x11docker: Running X server X11 on display :1 now ...
==> /home/sodd/.cache/x11docker/X1/xinit.log <==
X.Org X Server 1.18.4
Release Date: 2016-07-19
X Protocol Version 11, Revision 0
Build Operating System: Linux 4.4.0-45-generic x86_64 Ubuntu
Current Operating System: Linux ntb-sodd 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017 x86_64
Kernel command line: BOOT_IMAGE=/vmlinuz-4.4.0-62-generic.efi.signed root=UUID=640c3f5a-1887-4faf-bf8f-7b72286f179f ro rootflags=subvol=@
Build Date: 02 November 2016 10:06:10PM
xorg-server 2:1.18.4-0ubuntu0.2 (For technical support please see http://www.ubuntu.com/support)
Current version of pixman: 0.33.6
Before reporting problems, check http://wiki.x.org
to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
(++) from command line, (!!) notice, (II) informational,
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: "/home/sodd/.local/share/xorg/Xorg.1.log", Time: Sat Feb 11 19:39:33 2017
(==) Using system config directory "/usr/share/X11/xorg.conf.d"
(==) No Layout section. Using the first Screen section.
(==) No screen section available. Using defaults.
(**) |-->Screen "Default Screen Section" (0)
(**) | |-->Monitor "<default monitor>"
(==) No monitor specified for screen "Default Screen Section".
Using a default monitor configuration.
(==) Automatically adding devices
(==) Automatically enabling devices
(==) Automatically adding GPU devices
(==) Max clients allowed: 256, resource mask: 0x1fffff
(WW) The directory "/usr/share/fonts/X11/cyrillic" does not exist.
Entry deleted from font path.
(WW) The directory "/usr/share/fonts/X11/100dpi/" does not exist.
Entry deleted from font path.
(WW) The directory "/usr/share/fonts/X11/75dpi/" does not exist.
Entry deleted from font path.
(WW) The directory "/usr/share/fonts/X11/100dpi" does not exist.
Entry deleted from font path.
(WW) The directory "/usr/share/fonts/X11/75dpi" does not exist.
Entry deleted from font path.
(==) FontPath set to:
/usr/share/fonts/X11/misc,
/usr/share/fonts/X11/Type1,
built-ins
(==) ModulePath set to "/usr/lib/x86_64-linux-gnu/xorg/extra-modules,/usr/lib/xorg/extra-modules,/usr/lib/xorg/modules"
(II) The server relies on udev to provide the list of input devices.
If no devices become available, reconfigure udev or disable AutoAddDevices.
(++) using VT number 8
(II) systemd-logind: logind integration requires -keeptty and -keeptty was not provided, disabling logind integration
(II) xfree86: Adding drm device (/dev/dri/card0)
(EE) /dev/dri/card0: failed to set DRM interface version 1.4: Permission denied
(II) config/udev: Ignoring already known drm device (/dev/dri/card0)
(--) PCI:*(0:0:2:0) 8086:1616:1028:062c rev 9, Mem @ 0xf6000000/16777216, 0xe0000000/268435456, I/O @ 0x0000f000/64
(II) Loading /usr/lib/xorg/modules/extensions/libglx.so
(II) Module glx: vendor="X.Org Foundation"
compiled for 1.18.4, module version = 1.0.0
(==) AIGLX enabled
(==) Matched intel as autoconfigured driver 0
(==) Matched modesetting as autoconfigured driver 1
(==) Matched fbdev as autoconfigured driver 2
(==) Matched vesa as autoconfigured driver 3
(==) Assigned the driver to the xf86ConfigLayout
(II) Loading /usr/lib/xorg/modules/drivers/intel_drv.so
(II) Module intel: vendor="X.Org Foundation"
compiled for 1.18.4, module version = 2.99.917
(II) Loading /usr/lib/xorg/modules/drivers/modesetting_drv.so
(II) Module modesetting: vendor="X.Org Foundation"
compiled for 1.18.4, module version = 1.18.4
(II) Loading /usr/lib/xorg/modules/drivers/fbdev_drv.so
(II) Module fbdev: vendor="X.Org Foundation"
compiled for 1.18.1, module version = 0.4.4
(II) Loading /usr/lib/xorg/modules/drivers/vesa_drv.so
(II) Module vesa: vendor="X.Org Foundation"
compiled for 1.18.1, module version = 2.3.4
(II) intel: Driver for Intel(R) Integrated Graphics Chipsets:
i810, i810-dc100, i810e, i815, i830M, 845G, 854, 852GM/855GM, 865G,
915G, E7221 (i915), 915GM, 945G, 945GM, 945GME, Pineview GM,
Pineview G, 965G, G35, 965Q, 946GZ, 965GM, 965GME/GLE, G33, Q35, Q33,
GM45, 4 Series, G45/G43, Q45/Q43, G41, B43
(II) intel: Driver for Intel(R) HD Graphics: 2000-6000
(II) intel: Driver for Intel(R) Iris(TM) Graphics: 5100, 6100
(II) intel: Driver for Intel(R) Iris(TM) Pro Graphics: 5200, 6200, P6300
(II) modesetting: Driver for Modesetting Kernel Drivers: kms
(II) FBDEV: driver for framebuffer: fbdev
(II) VESA: driver for VESA chipsets: vesa
(EE)
Fatal server error:
(EE) xf86OpenConsole: Cannot open virtual console 8 (Permission denied)
(EE)
(EE)
Please consult the The X.Org Foundation support
at http://wiki.x.org
for help.
(EE) Please also check the log file at "/home/sodd/.local/share/xorg/Xorg.1.log" for additional information.
(EE)
(WW) xf86CloseConsole: KDSETMODE failed: Bad file descriptor
(WW) xf86CloseConsole: VT_GETMODE failed: Bad file descriptor
(EE) Server terminated with error (1). Closing log file.
xinit: giving up
xinit: unable to connect to X server: Connection refused
xinit: server error
./x11docker: line 457: 2581 Terminated tail --retry -n +1 -F $XTERMLOGFILE $DOCKERLOGFILE $XPRALOGFILE $XINITLOGFILE 2> /dev/null
If i run x11docker --update, it looks like the installation works but it never exits.
the last lines are:
- Newdisplaynumber for xorg starts with 8
- xinitrc: XPRA_OPENGL_DOUBLE_BUFFERED=1 to avoid xpra bug 1469
- check and set XDG_RUNTIME_DIR for weston and Xwayland
### Removed
and after that i have a blinking cursor for almost an hour now.
I am running x11docker inside a chroot environment (Debian 9)
everything worked fine when i ran the command the last time (about one week ago)
This command runs a workable xpra window:
james@librem:~$ x11docker --clipboard atom &
[1] 19014
james@librem:~$ Warning: invalid option: 'shadow-fullscreen'
x11docker note: Using X server option --xpra
x11docker WARNING: Your host X server seems to run without cookie authorisation.
x11docker note: Stay tuned, xpra will start soon.
The same command from a script runs a weston-xwayland (showing me 2 title bars):
james@librem:~$ echo 'x11docker --clipboard atom &' > tmp.sh
james@librem:~$ sh ./tmp.sh
james@librem:~$ x11docker note: Using X server option --weston-xwayland
x11docker note: Sharing picture clips with option --clipboard
is only possible with options --xpra, --xpra-xwayland and --hostdisplay.
x11docker WARNING: Your host X server seems to run without cookie authorisation.
x11docker note: Looking for windowmanager linked with x-window-manager.
You can set the default one detected in auto mode with
update-alternatives --config x-window-manager
x11docker note: Using host window manager /usr/bin/xfwm4
Why does the same command behave differently when ran from a script?
bash ./tmp.sh
choose weston-xwayland..
Will this app work on a raspberry pi? How do I install it ? Do you have any installation instructions?
Thanks
The recent change that made /dev/dri readonly borked up hardware acceleration for me. It was never able to open the device and so reverted to hardware rendering.
I just changed this line (2080) back and it fixed it:
[ "$Gpu" = "yes" ] && Dockercommand="$Dockercommand --device=/dev/dri"
I trying doing a new docker image (docker-bspwm on arch linux). But i don't know why, the key released don't seem work. I have installed a key-mon
for showing the key, not result, but if i use xev
, i can see the key code
Have you a good method for debuging the keyboard issue ?
I use
docker build --rm -f docker-bspwm/Dockerfile -t bspwm docker-bspwm
x11docker --xephyr --user=root --pulseaudio --desktop bspwm xterm
#x11docker --xephyr --user=root --pulseaudio --desktop bspwm startx
I have tested this on currently xorg and physical terminal
A user of ehough/docker-kodi
reported that they couldn't change the timezone in Kodi. After a little digging, I found that Kodi relies on the presence of the /usr/share/zoneinfo
directory to allow the user to select their country and timezone. Manually bind-mounting this directory (read-only) into the container resolves the issue.
Do you think this would be worthwhile adding as a default feature for x11docker
, much like is already with /etc/localtime
? I'd guess that a number of other GUI apps (especially desktop environments?) would rely on reading this directory, and I can't think of any obvious drawbacks.
Thoughts?
npm start
seems to loose its WORKDIR and think I'm in $HOME. I see this error:
x11docker: copy of environment stored in /x11docker/environment
x11docker: running image command: /tini -- npm start
Last lines of command stderr:
npm ERR! syscall open
npm ERR! enoent ENOENT: no such file or directory, open '/fakehome/jcalfee/package.json'
It is odd that I can go into the container and run this command without x11docker and it works better:
root@2f5168a2b14d:/esteem-surfer# npm start
> [email protected] start /esteem-surfer
> node build/start.js
Is there a way I can look around? It would be helpful to run this container in x11docker but instead of using the npm start
entrypoint I could run bash
in "-i" interactive mode so I can look around?
For example:
# Creates error: Error: No such container: x11docker_X404_f8243a_esteem-surfer
x11docker $XDOCK --clipboard --homedir $HOME/.x11docker/esteem-surfer\
-- "-i --entrypoint bash"\
esteem-surfer
Regardless, is there something about the x11docker environment that I can tweak to get npm start working?
This is the Dockerfile I'm working with:
FROM ubuntu:bionic
RUN apt-get update &&\
apt-get install -y --no-install-recommends\
ca-certificates git nodejs npm
RUN git clone https://github.com/eSteemApp/esteem-surfer &&\
cd esteem-surfer &&\
git checkout tags/1.0.0 &&\
npm install --no-optional &&\
npm install -g bower
WORKDIR /esteem-surfer
RUN mv src/config.example.js src/config.js
RUN apt-get install -y libgtk2.0-0 libx11-xcb1 libxtst6 libxss1 libgconf-2-4 libnss3 libasound2
ENTRYPOINT [ "npm", "start" ]
$ x11docker --clipboard --home --sharedir /home/james/Downloads keybase
This creates a permission denied error:
x11docker: Created container.rootsetup.sh:
61 echo "james:sac19FwGGTx/A:17293:0:99999:7:::" >> /etc/shadow
x11docker ERROR: Container startup seems to have failed!
Last lines of container.log:
mkdir: created directory '/tmp/.font-unix'
lrwxrwxrwx 1 root root 5 Jun 30 01:05 /tmp/.X11-unix/X500 -> /X500
sed: can't read /etc/shadow: Permission denied
/x11docker/container.rootsetup.sh: line 57: /etc/shadow: Permission denied
sed: can't read /etc/shadow: Permission denied
/x11docker/container.rootsetup.sh: line 61: /etc/shadow: Permission denied
rm: cannot remove '/etc/sudoers.d': No such file or directory
rm: cannot remove '/etc/sudoers': No such file or directory
rm: cannot remove '/etc/pam.d/sudo': No such file or directory
mkdir: created directory '/tmp/XDG_RUNTIME_DIR'
Last lines of command stderr:
[FATAL tini (71)] exec -v failed: No such file or directory
Type 'x11docker --help' for usage information
For debugging, run x11docker in terminal and/or enable option '--verbose'
or look afterwards at logfile /home/james/.cache/x11docker/x11docker.log
Please report issues at https://github.com/mviereck/x11docker
Environment
FROM fedora
RUN yum install -y gtk2 libX11-devel libXtst GConf2 alsa-lib https://prerelease.keybase.io/keybase_amd64.rpm
COPY keybase /
CMD run_keybase
$ docker build -t keybase .
$ x11docker --clipboard --home --sharedir /home/james/Downloads keybase
Here is a place where you can leave any feedback or ask questions if you fear to open our own issue.
As I spend a lot of time with x11docker development, I'm happy to see and read more than some download statistics ...
Feel free to comment. :)
Edit: This thread is very long already. Please just open a new issue, I am pleased of every feedback!
I just did a snap docker install on Debian 9 ..
The docker-init file is here:
/snap/docker/179/bin/docker-init
x11docker script does not find it:
$ x11docker
x11docker note: Using X server option --xephyr
x11docker note: Did not find container init system 'tini'.
This is a bug in your distributions docker package.
Normally, docker provides init system tini as '/usr/bin/docker-init'.
x11docker uses tini for clean process handling and fast container shutdown.
To provide tini yourself, please download tini-static:
https://github.com/krallin/tini/releases/download/v0.18.0/tini-static
Store it in one of:
/home/james/.local/share/x11docker/
/usr/local/share/x11docker/
Hi
I've just tested x11docker with lxde, with
./x11docker --desktop --size 1920x1080 --xorg --gpu --vt 4 x11docker/lxde --home
unfortunately, in this image, I found no way of sudoing and install packages.
A really cool application would be to switch between several desktop distros and test the latest ones with all gpu acceleration, and home dir shared. This is like https://github.com/ustuehler/lxc-desktop (which unfortunately doesn't work for me in xenial)
I wouldn't really care about security. This seems like a very cool application.
GPU acceleration with option --gpu
using core X11 can have rendering glitches. These glitches can be avoided with option --ipc
. Then the new X socket is shared (instead of accessing X over tcp).
Same problems can occure with option --hostdisplay
, independent from option --gpu
. Option --hostdisplay
uses shared X socket, too.
Option --ipc
sets docker run option --ipc=host
. The docker run reference says:
--ipc=host: use the host's IPC namespace inside the container
IPC (POSIX/SysV IPC) namespace provides separation of named shared memory segments, semaphores and message queues.
Shared memory segments are used to accelerate inter-process communication at memory speed, rather than through pipes or through the network stack. Shared memory is commonly used by databases and custom-built (typically C/OpenMPI, C++/using boost libraries) high performance applications for scientific computing and financial services industries. If these types of applications are broken into multiple containers, you might need to share the IPC mechanisms of the containers.
x11docker recommends to use this option only with option --hostuser
enabled to minimize risks. This way the container does not have root access to interprocess communication and shared memory. However, I'm not sure which risks are left.
I would like to find a more restricted solution to get GPU acceleration accessing X over shared X socket.
I've already tested docker run ... --add-cap=ALL
and --privileged
to check if one of those capabilities could do the trick, but they don't.
Running x11docker-gui -d
shows some additional developer options. Enabling options --sharegpu
and --xsocket
has the same effect as official option --gpu
.
Maybe someone has a good idea how to improve container isolation in this case. Any help is appreciated. Also, any assessment about security implications using --ipc=host
(as root or as user in container) is welcome.
in x11docker file You use 2017 year instead 2018
I see that everything runs around IMAGE
. You provide an image, x11docker creates a container with proper GUI configuration and runs the app inside.
How about this scenario:
I have docker environment configured for my development project. A container for compiling the project, a container for database, a container for database management app. All these containers are managed with docker-compose. I would like x11docker to work like this: I specify a container and a command to start my IDE. Then x11docker will check if that container has the right configurations and will start successfully the command or will show me what I have to change in container parameters in order to fix the problem. Then I will add the required parameters in my docker-compose.yml
, recreate the container and start my IDE via x11docker.
Does this make sense?
At the moment I set up my IDE to work inside docker container by mounting my home directory, /tmp/.X11-unix
, sharing ${DISPLAY}
and starting it with docker exec
(I sometime execute xhost +
if it shows an error).
I just found this solution on internet and I have no idea how it works (x11 noob).
Is my solution ok and I should continue using it or x11docker has to offer something better?
Just an observation, not critical:
Script leaves the ":" in the container name which makes the resulting command fail on -v option.
Looks like you are already converting the "/" to "-" in the container name for the home directory name, maybe the ":" can be converted also.
Official LearnOpenGL examples project has just accepted using x11docker for building the examples
JoeyDeVries/LearnOpenGL#107
As you can see after starting IDE in docker you have to docker exec
in temp container to install video drivers. It's not possible to hardcode video driver in Dockerfile
because it will be used on different systems and distros.
It would be nice if after container start the video driver will be installed automagically on any distro. We have to know if it's nvidia/amd and the major driver version (e.g. 390).
This task looks too complicated for me that's why I am consulting you.
If there is nothing you can do just close this issue.
Hi,
Thanks for the x11docker project! On my Ubuntu 17.10 box that is running on Wayland session, I have got errors with the flag --weston-xwayland
. --xephyr
seems to run fine.
Have run with --verbose
and got the following as the resulting log. Do you have any ideas/pointers on what could be the culprit? Thanks.
x11docker: Sun Dec 10 07:06:21 GMT 2017 Ubuntu 17.10
Command: /opt/x11docker/x11docker --weston-xwayland --desktop --gpu -- x11docker/mate
Parsed options: --weston-xwayland --desktop --gpu -- '' 'x11docker/mate '
x11docker WARNING: Option --gpu degrades container isolation.
Container gains access to GPU hardware.
This allows reading host window content (palinopsia leak)
and GPU rootkits (compare proof of concept: jellyfish).
x11docker note: Hardware acceleration (option --gpu) works quite well with open
source drivers (radeon, nouveau, intel ...) on host and OpenGL/MESA in image.
If you have closed source drivers on your host, you need to install
the very same driver version in your image to get hardware acceleration.
x11docker: Host system: ubuntu
x11docker: X or Wayland server option: --weston-xwayland
x11docker: Virtual screen size: 1820x980
x11docker: Real screen size: Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 8192 x 8192
x11docker: Environment variables:
DISPLAY=:250 XAUTHORITY=/home/user/.cache/x11docker/X250-x11docker-mate/share/Xclientcookie XSOCKET=/tmp/.X11-unix/X250 XPRA_XSHM=0 X11DOCKER_CACHE=/home/user/.cache/x11docker/X250-x11docker-mate
x11docker: Image name: x11docker/mate
x11docker: Image command:
x11docker: Users and terminal:
x11docker was started by: user
As host user serves (running X, storing cache): user
Container user will be: user
Container user password: x11docker
Getting permission to run docker with: bash -c
Running X and other user commands with: bash -c
Terminal for password frontend: bash -c
Terminal to show docker pull progress: xterm -e
Running on console: no
x11docker: Current cache folder: /home/user/.cache/x11docker/X250-x11docker-mate
x11docker: Created X server command:
/usr/bin/Xwayland :250 \
-nolisten tcp -dpms -retro \
+extension Composite +extension RANDR +extension RENDER +extension GLX +iglx \
+extension XVideo +extension DOUBLE-BUFFER \
-extension X-Resource +extension SECURITY +extension DAMAGE \
-extension XINERAMA -xinerama -extension MIT-SHM \
-auth /home/user/.cache/x11docker/X250-x11docker-mate/Xservercookie -dpi 96
x11docker: Created compositor command:
weston --socket=wayland-250 --config='/home/user/.cache/x11docker/X250-x11docker-mate/weston.ini' --backend=wayland-backend.so
x11docker: Created docker command:
docker run --rm --name=x11docker_X250_fc50a7_x11docker_mate \
--cap-drop=ALL \
--security-opt=no-new-privileges \
--init \
--user 1000:1000 --env USER=user --group-add video \
-v /home/user/.cache/x11docker/X250-x11docker-mate/passwd:/etc/passwd:ro \
-v /home/user/.cache/x11docker/X250-x11docker-mate/shadow:/etc/shadow:ro \
--read-only \
--tmpfs /tmp --tmpfs /run --tmpfs /var/tmp \
--entrypoint=env \
-v /home/user/.cache/x11docker/X250-x11docker-mate/share:/x11docker:rw \
-v /tmp/.X11-unix/X250:/x11docker/X250:rw \
--device=/dev/dri:/dev/dri:rw \
-- x11docker/mate /bin/sh /x11docker/x11docker.CMD.sh
x11docker: IP of docker interface: 172.17.0.1/16
x11docker: Created dockerrc:
1 #! /bin/bash
2 verbose ()
3 {
4 [ -e "$Logfile" ] && echo "x11docker: $*
5 " >> "$Logfile";
6 return 0
7 }
8 waitforfilecreation ()
9 {
10 local Zeit Warten;
11 Zeit=$(date +%s);
12 verbose "Waiting for file creation of ${1:-}";
13 case $2 in
14 "")
15 Warten=15
16 ;;
17 infinity | inf)
18 Warten=32000
19 ;;
20 *)
21 Warten=${2:-}
22 ;;
23 esac;
24 while [ ! "$(find "${1:-}" 2>/dev/null)" ]; do
25 sleep 0.2;
26 [ $Warten -lt $(expr $(date +%s) - $Zeit) ] && return 1;
27 [ -e "$Timetosaygoodbye" ] && return 1;
28 done;
29 verbose "Found newly created file ${1:-}";
30 return 0
31 }
32 waitforfilecontent ()
33 {
34 local Zeit;
35 Zeit=$(date +%s);
36 verbose "Waiting for file content in ${1:-}";
37 while [ ! -s "${1:-}" ]; do
38 sleep 0.1;
39 [ 15 -lt $(expr $(date +%s) - $Zeit) ] && return 1;
40 [ -e "$Timetosaygoodbye" ] && return 1;
41 done;
42 verbose "Found file content in ${1:-}";
43 return 0
44 }
45 Imagename='x11docker/mate'
46 Imagecommand=''
47 # check if image is available locally
48 docker inspect --type=image x11docker/mate > /dev/null 2>&1 || {
49 xterm -e /bin/bash /home/user/.cache/x11docker/X250-x11docker-mate/pullrc
50 waitforfilecreation /home/user/.cache/x11docker/X250-x11docker-mate/pullready
51 docker inspect --type=image x11docker/mate > /dev/null 2>&1 || {
52 echo ''
53 echo "ERROR: Image 'x11docker/mate' not found locally and not pulled from docker hub. " >&2
54 exit 1
55 }
56 }
57 # check CMD
58 [ -z "$Imagecommand" ] && {
59 # extract image command from image if not given on cli
60 Imagecommand=$(docker inspect --format='{{.Config.Cmd}}' x11docker/mate)
61 Imagecommand=${Imagecommand#[}
62 Imagecommand=${Imagecommand#/bin/sh -c }
63 Imagecommand=${Imagecommand%]}
64 }
65 # check ENTRYPOINT
66 Entrypoint=$(docker inspect --format='{{.Config.Entrypoint}}' x11docker/mate)
67 Entrypoint=${Entrypoint#[}
68 Entrypoint=${Entrypoint#/bin/sh -c }
69 Entrypoint=${Entrypoint%]}
70 [ -z "$Imagecommand$Entrypoint" ] && echo 'x11docker WARNING: No image command specified and no CMD or ENTRYPOINT found in image.'|tee -a /tmp/x11docker.fc50a7.log
71 Dbus=''
72
73 # create x11docker.CMD.sh (shared with container and given as image command on docker run)
74 { echo '#! /bin/sh'
75 echo '# created startscript for docker run: x11docker.CMD.sh'
76 echo Imagecommand="\"$Imagecommand\""
77 echo Entrypoint="\"$Entrypoint\""
78 echo ''
79 echo export USER=user
80 echo export HOME="\"/tmp/fakehome\""
81 echo 'mkdir -p "$HOME" && cd "$HOME"'
82 echo 'touch "$HOME/.xinitrc" '
83 echo 'mkdir -p /tmp/.ICE-unix'
84 echo ''
85 echo '# link X socket into right folder /tmp/.X11-unix.'
86 echo '# Was not directly shared to provide .X11-unix with rw-access. '
87 echo '# Needed for X created in container like with startplasmacompositor'
88 echo 'mkdir -p /tmp/.X11-unix'
89 [ -e '/tmp/.X11-unix/X250' ] && echo 'ln -s /x11docker/X250 /tmp/.X11-unix/X250'
90 echo 'export DISPLAY=:250'
91 echo 'export XAUTHORITY=/x11docker/Xclientcookie'
92 echo ''
93 echo '# xpra environment settings'
94 echo 'export UBUNTU_MENUPROXY= QT_X11_NO_NATIVE_MENUBAR=1 MWNOCAPTURE=true MWNO_RIT=true MWWM=allwm'
95 echo ''
96 echo '[ -e "$XDG_RUNTIME_DIR" ] || {'
97 echo ' # XDG_RUNTIME_DIR must be owned by user'
98 echo ' mkdir -p /tmp/XDG_RUNTIME_DIR'
99 echo ' export XDG_RUNTIME_DIR=/tmp/XDG_RUNTIME_DIR'
100 echo '}'
101 echo 'echo "x11docker: XDG_RUNTIME_DIR in container is $XDG_RUNTIME_DIR" >&2'
102 echo 'export XDG_SESSION_TYPE=x11'
103 echo ''
104 echo 'export SHELL=/bin/bash'
105 echo 'export TERM=xterm'
106 echo ''
107 echo 'cd "$HOME"'
108 echo ''
109 echo "exec $Dbus $Entrypoint $Imagecommand >>/x11docker/stdout 2>>/x11docker/stderr"
110 echo '# Ready for docker run'
111 } >> /home/user/.cache/x11docker/X250-x11docker-mate/share/x11docker.CMD.sh
112
113 cat /home/user/.cache/x11docker/X250-x11docker-mate/share/x11docker.CMD.sh | nl -ba >> /home/user/.cache/x11docker/X250-x11docker-mate/docker.log
114
115 nohup setsid docker run --rm --name=x11docker_X250_fc50a7_x11docker_mate \
116 --cap-drop=ALL \
117 --security-opt=no-new-privileges \
118 --init \
119 --user 1000:1000 --env USER=user --group-add video \
120 -v /home/user/.cache/x11docker/X250-x11docker-mate/passwd:/etc/passwd:ro \
121 -v /home/user/.cache/x11docker/X250-x11docker-mate/shadow:/etc/shadow:ro \
122 --read-only \
123 --tmpfs /tmp --tmpfs /run --tmpfs /var/tmp \
124 --entrypoint=env \
125 -v /home/user/.cache/x11docker/X250-x11docker-mate/share:/x11docker:rw \
126 -v /tmp/.X11-unix/X250:/x11docker/X250:rw \
127 --device=/dev/dri:/dev/dri:rw \
128 -- x11docker/mate /bin/sh /x11docker/x11docker.CMD.sh >>/home/user/.cache/x11docker/X250-x11docker-mate/docker.log 2>&1 & echo $! >> /home/user/.cache/x11docker/X250-x11docker-mate/docker.pid
129 for Count in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
130 sleep 0.1
131 docker exec x11docker_X250_fc50a7_x11docker_mate sh -c : && { verbose 'container x11docker_X250_fc50a7_x11docker_mate is ready' ; break ; } || verbose "container not ready on $Count. attempt, trying again"
132 done
x11docker: Created xtermrc:
1 #! /bin/bash
2 touchxtermready() {
3 bash -c 'touch /home/user/.cache/x11docker/X250-x11docker-mate/xtermready'
4 }
5 trap touchxtermready EXIT
6 export TERM=xterm SHELL=/bin/bash
7 bash -c "bash /home/user/.cache/x11docker/X250-x11docker-mate/dockerrc" >>/home/user/.cache/x11docker/X250-x11docker-mate/xterm.log 2>&1
8 exit
x11docker: Created xinitrc:
1 #! /bin/sh
2 storepid ()
3 {
4 echo ${1:-} ${2:-} >> $Bgpidfile;
5 verbose "stored background pid ${1:-} of ${2:-}"
6 }
7 mywatch ()
8 {
9 env TERM=linux watch --interval 1 --chgexit --no-title -- "sh -c '${1:-}'" > /dev/null 2>&1
10 }
11 no_xhost ()
12 {
13 local Line;
14 xhost;
15 xhost | tail -n +2 /dev/stdin | while read -r Line; do
16 xhost -$Line;
17 done;
18 xhost -;
19 [ "$(xhost | wc -l)" -gt "1" ] && {
20 warning "Remaining xhost permissions found on display $DISPLAY
21 $(xhost)";
22 return 1
23 };
24 return 0
25 }
26 warning ()
27 {
28 echo "$(tput setaf 3)x11docker WARNING:$(tput sgr0) $*" 1>&3;
29 echo "" 1>&3;
30 [ -e "$Logfile" ] && echo "x11docker WARNING: $*
31 " >> "$Logfile";
32 return 0
33 }
34 verbose ()
35 {
36 [ -e "$Logfile" ] && echo "x11docker: $*
37 " >> "$Logfile";
38 return 0
39 }
40 note ()
41 {
42 echo "$(tput setaf 2)x11docker note:$(tput sgr0) $*" 1>&3;
43 echo "" 1>&3;
44 [ -e "$Logfile" ] && echo "x11docker note: $*
45 " >> "$Logfile";
46 return 0
47 }
48 Bgpidfile=/home/user/.cache/x11docker/X250-x11docker-mate/backgroundpids
49 export Hostxenv='DISPLAY=:0 XAUTHORITY= XSOCKET=/tmp/.X11-unix/X0 WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000'
50 export Newxenv='DISPLAY=:250 XAUTHORITY=/home/user/.cache/x11docker/X250-x11docker-mate/share/Xclientcookie XSOCKET=/tmp/.X11-unix/X250 XPRA_XSHM=0 X11DOCKER_CACHE=/home/user/.cache/x11docker/X250-x11docker-mate '
51 # set X variables to new display
52 # create new XAUTHORITY cookies
53 :> /home/user/.cache/x11docker/X250-x11docker-mate/share/Xclientcookie
54 xauth -v -f /home/user/.cache/x11docker/X250-x11docker-mate/share/Xclientcookie generate :250 . trusted timeout 3600
55 [ -s '/home/user/.cache/x11docker/X250-x11docker-mate/share/Xclientcookie' ] || {
56 [ 'trusted' = 'untrusted' ] && note 'Could not create untrusted cookie.
57 Maybe your X server misses extension SECURITY.'
58 }
59 [ -s '/home/user/.cache/x11docker/X250-x11docker-mate/share/Xclientcookie' ] || {
60 # still no cookie? try to create one without extension security
61 xauth -f /home/user/.cache/x11docker/X250-x11docker-mate/share/Xclientcookie add :250 . 3f50694958c70662ebb6dae1c7e3915e
62 }
63 # create prepared cookie with localhost identification disabled by ffff, needed if X socket is shared. ffff means 'familiy wild'
64 Cookie=$(xauth -f /home/user/.cache/x11docker/X250-x11docker-mate/share/Xclientcookie nlist | sed -e 's/^..../ffff/')
65 echo $Cookie | xauth -v -f /home/user/.cache/x11docker/X250-x11docker-mate/share/Xclientcookie nmerge -
66 cp /home/user/.cache/x11docker/X250-x11docker-mate/share/Xclientcookie /home/user/.cache/x11docker/X250-x11docker-mate/Xservercookie
67 [ -s '/home/user/.cache/x11docker/X250-x11docker-mate/share/Xclientcookie' ] || warning 'Cookie creation failed! --weston-xwayland runs without cookie authentication.'
68 export $Newxenv
69 verbose "Created cookie: $(xauth list)"
70 verbose 'disabling any possible access to new X server possibly granted by xhost'
71 no_xhost
72 export $Newxenv
73 getscreensize() {
74 CurrentXaxis=$(xrandr | grep primary | cut -d' ' -f4 | cut -dx -f1 )
75 CurrentYaxis=$(xrandr | grep primary | cut -d' ' -f4 | cut -dx -f2 | cut -d+ -f1)
76 }
77 checkscreensize() {
78 getscreensize
79 [ "$Xaxis" = "$CurrentXaxis" ] || return 1
80 [ "$Yaxis" = "$CurrentYaxis" ] || return 1
81 return 0
82 }
83 getprimary() {
84 xrandr | grep -q primary || xrandr --output $(xrandr | grep ' connected' | head -n1 | cut -d' ' -f1) --primary
85 echo $(xrandr | grep primary | cut -d' ' -f1)
86 }
87 Output=$(getprimary)
88 verbose "Output of xrandr on :250
89 $(xrandr)"
90 touch /home/user/.cache/x11docker/X250-x11docker-mate/Xready
91 mywatch 'ls /home/user/.cache/x11docker/X250-x11docker-mate/share/timetosaygoodbye'
x11docker: Created weston.ini:
1
2 [core]
3 shell=desktop-shell.so
4 idle-time=0
5 [shell]
6 panel-location=none
7 panel-position=none
8 locking=false
9 background-color=0xff002244
10 animation=fade
11 startup-animation=fade
12 [keyboard]
13 keymap_layout=
14
15 [output]
16 name=WL1
17 mode=1820x980
18
x11docker: Logfiles are:
/home/user/.cache/x11docker/X250-x11docker-mate/xinit.log
/home/user/.cache/x11docker/X250-x11docker-mate/xpraserver.log
/home/user/.cache/x11docker/X250-x11docker-mate/xpraclient.log
/home/user/.cache/x11docker/X250-x11docker-mate/compositor.log
/home/user/.cache/x11docker/X250-x11docker-mate/xterm.log
/home/user/.cache/x11docker/X250-x11docker-mate/docker.log
Summary logfile: /home/user/.cache/x11docker/X250-x11docker-mate/share/x11docker.log
In container: /x11docker/x11docker.log
After finish: /home/user/.cache/x11docker/x11docker.log
x11docker: Running X server --weston-xwayland on display :250 now ...
==> /home/user/.cache/x11docker/X250-x11docker-mate/xterm.log <==
==> /home/user/.cache/x11docker/X250-x11docker-mate/docker.log <==
==> /home/user/.cache/x11docker/X250-x11docker-mate/xpraserver.log <==
==> /home/user/.cache/x11docker/X250-x11docker-mate/xpraclient.log <==
==> /home/user/.cache/x11docker/X250-x11docker-mate/xinit.log <==
==> /home/user/.cache/x11docker/X250-x11docker-mate/compositor.log <==
==> /home/user/.cache/x11docker/X250-x11docker-mate/docker.log <==
==> /home/user/.cache/x11docker/X250-x11docker-mate/share/stdout <==
==> /home/user/.cache/x11docker/X250-x11docker-mate/share/stderr <==
x11docker: Waiting for file creation of /home/user/.cache/x11docker/X250-x11docker-mate/Xready
==> /home/user/.cache/x11docker/X250-x11docker-mate/compositor.log <==
Date: 2017-12-10 GMT
[07:06:22.288] weston 1.12.0
http://wayland.freedesktop.org
Bug reports to: https://bugs.freedesktop.org/enter_bug.cgi?product=Wayland&component=weston&version=1.12.0
Build: 1.11.94-2-ga08dff5 configure.ac: bump to version 1.12.0 for the official release (2016-09-20 12:22:46 -0700)
[07:06:22.288] Command line: weston --socket=wayland-250 --config=/home/user/.cache/x11docker/X250-x11docker-mate/weston.ini --backend=wayland-backend.so
[07:06:22.288] OS: Linux, 4.13.0-19-generic, #22-Ubuntu SMP Mon Dec 4 11:58:07 UTC 2017, x86_64
[07:06:22.288] Using config file '/home/user/.cache/x11docker/X250-x11docker-mate/weston.ini'
[07:06:22.288] Output repaint window is 7 ms maximum.
[07:06:22.288] Loading module '/usr/lib/x86_64-linux-gnu/libweston-1/wayland-backend.so'
x11docker: waiting since 0s for weston to be ready...
[07:06:22.297] Loading module '/usr/lib/x86_64-linux-gnu/libweston-1/gl-renderer.so'
[07:06:22.301] EGL client extensions: EGL_EXT_client_extensions
EGL_EXT_platform_base EGL_KHR_client_get_all_proc_addresses
EGL_KHR_debug EGL_EXT_platform_wayland EGL_EXT_platform_x11
EGL_MESA_platform_gbm EGL_MESA_platform_surfaceless
EGL_KHR_platform_mir
x11docker: waiting since 0s for weston to be ready...
x11docker: waiting since 0s for weston to be ready...
x11docker: waiting since 0s for weston to be ready...
x11docker: waiting since 1s for weston to be ready...
x11docker: waiting since 1s for weston to be ready...
x11docker: waiting since 1s for weston to be ready...
x11docker: waiting since 1s for weston to be ready...
x11docker: waiting since 2s for weston to be ready...
x11docker: waiting since 2s for weston to be ready...
x11docker: waiting since 2s for weston to be ready...
x11docker: waiting since 2s for weston to be ready...
x11docker: waiting since 2s for weston to be ready...
x11docker: waiting since 3s for weston to be ready...
x11docker: waiting since 3s for weston to be ready...
x11docker: waiting since 3s for weston to be ready...
x11docker: waiting since 3s for weston to be ready...
x11docker: waiting since 3s for weston to be ready...
x11docker: waiting since 4s for weston to be ready...
x11docker: waiting since 4s for weston to be ready...
x11docker: waiting since 4s for weston to be ready...
x11docker: waiting since 4s for weston to be ready...
x11docker: waiting since 5s for weston to be ready...
x11docker: waiting since 5s for weston to be ready...
x11docker: waiting since 5s for weston to be ready...
x11docker: waiting since 5s for weston to be ready...
x11docker: waiting since 5s for weston to be ready...
x11docker: waiting since 6s for weston to be ready...
x11docker: waiting since 6s for weston to be ready...
x11docker: waiting since 6s for weston to be ready...
x11docker: waiting since 6s for weston to be ready...
x11docker: waiting since 6s for weston to be ready...
x11docker: waiting since 7s for weston to be ready...
x11docker: waiting since 7s for weston to be ready...
x11docker: waiting since 7s for weston to be ready...
x11docker: waiting since 7s for weston to be ready...
x11docker: waiting since 8s for weston to be ready...
x11docker: waiting since 8s for weston to be ready...
x11docker: waiting since 8s for weston to be ready...
x11docker: waiting since 8s for weston to be ready...
x11docker: waiting since 8s for weston to be ready...
x11docker: waiting since 9s for weston to be ready...
x11docker: waiting since 9s for weston to be ready...
x11docker: waiting since 9s for weston to be ready...
x11docker: waiting since 9s for weston to be ready...
x11docker: waiting since 9s for weston to be ready...
x11docker: waiting since 10s for weston to be ready...
x11docker: waiting since 10s for weston to be ready...
x11docker: waiting since 10s for weston to be ready...
x11docker: waiting since 10s for weston to be ready...
x11docker: waiting since 11s for weston to be ready...
x11docker: waiting since 11s for weston to be ready...
x11docker: waiting since 11s for weston to be ready...
x11docker: waiting since 11s for weston to be ready...
x11docker: waiting since 11s for weston to be ready...
x11docker: waiting since 12s for weston to be ready...
x11docker: waiting since 12s for weston to be ready...
x11docker: waiting since 12s for weston to be ready...
x11docker: waiting since 12s for weston to be ready...
x11docker: waiting since 13s for weston to be ready...
x11docker: waiting since 13s for weston to be ready...
x11docker: waiting since 13s for weston to be ready...
x11docker: waiting since 13s for weston to be ready...
x11docker: waiting since 13s for weston to be ready...
x11docker: waiting since 14s for weston to be ready...
x11docker: waiting since 14s for weston to be ready...
x11docker: waiting since 14s for weston to be ready...
x11docker: waiting since 14s for weston to be ready...
x11docker: waiting since 14s for weston to be ready...
x11docker: waiting since 15s for weston to be ready...
x11docker: waiting since 15s for weston to be ready...
x11docker: waiting since 15s for weston to be ready...
x11docker: waiting since 15s for weston to be ready...
x11docker ERROR: Startup of X server --weston-xwayland failed.
Last lines of xinit logfile:
Type 'x11docker --help' for usage information
For debugging, run x11docker in terminal and/or enable option '--verbose'
and look afterwards at logfile /home/user/.cache/x11docker/x11docker.log
If you think this is a bug in x11docker,
please report at https://github.com/mviereck/x11docker
x11docker: Creating /home/user/.cache/x11docker/X250-x11docker-mate/share/timetosaygoodbye
x11docker ERROR: Weston startup failed. Can not run --weston-xwayland.
Last lines of weston log:
[07:06:22.288] OS: Linux, 4.13.0-19-generic, #22-Ubuntu SMP Mon Dec 4 11:58:07 UTC 2017, x86_64
[07:06:22.288] Using config file '/home/user/.cache/x11docker/X250-x11docker-mate/weston.ini'
[07:06:22.288] Output repaint window is 7 ms maximum.
[07:06:22.288] Loading module '/usr/lib/x86_64-linux-gnu/libweston-1/wayland-backend.so'
[07:06:22.297] Loading module '/usr/lib/x86_64-linux-gnu/libweston-1/gl-renderer.so'
[07:06:22.301] EGL client extensions: EGL_EXT_client_extensions
EGL_EXT_platform_base EGL_KHR_client_get_all_proc_addresses
EGL_KHR_debug EGL_EXT_platform_wayland EGL_EXT_platform_x11
EGL_MESA_platform_gbm EGL_MESA_platform_surfaceless
EGL_KHR_platform_mir
Type 'x11docker --help' for usage information
For debugging, run x11docker in terminal and/or enable option '--verbose'
and look afterwards at logfile /home/user/.cache/x11docker/x11docker.log
If you think this is a bug in x11docker,
please report at https://github.com/mviereck/x11docker
x11docker: Creating /home/user/.cache/x11docker/X250-x11docker-mate/share/timetosaygoodbye
x11docker: terminating x11docker ...
x11docker: Creating /home/user/.cache/x11docker/X250-x11docker-mate/share/timetosaygoodbye
Installing multiple desktop environments is a challenging and on some OSes an even impossible task. What if you could install and run the DEs from x11docker? (Instead of like, IDK sddm or lightdm)(Is that even possible?)
This would unlock many possibilities like multiple DEs at once! (Not sure why would anyone want that, but it at least sounds cool.)
When I run it, I got:
x11docker ERROR Could not find user 'eussam' in /etc/passwd.
By checking if the option NOPASSWD:ALL existing with --sudouser
option
I could see that this one existed in 2015 and document code
Why this function is disabled (i think for security reason :) )? Can we add new option (ex: --nopassword
or --sudonopass
, etc ..) or must we be dot it in our Dockerfile ?
GPU acceleration with option --gpu
using core X11 can have rendering glitches. These glitches can be avoided with option --net
. Then X over tcp is used. Option --net
sets docker run option --net=host
. The docker networking reference only says:
The host network adds a container on the hosts network stack. You’ll find the network configuration inside the container is identical to the host.
x11docker recommends to use this option only with option --hostuser
enabled to minimize risks. This way the container does not have root access to host network stack. However, I'm not sure which risks are left.
I would like to find a more restricted solution to get GPU acceleration with X over tcp.
I've already tested docker run ... --add-cap=ALL
and --privileged
to check if one of those capabilities could do the trick, but they don't.
I've also tried to force indirect rendering with environment variable LIBGL_ALWAYS_INDIRECT=1
, but then glxgears rotated about 1 time per minute ... however, this environment variable is already deprecated.
Running x11docker-gui -d
shows some additional developer options. Enabling options --sharegpu
and --sharenewxsocket
are a good starting point for tests.
Maybe someone has a good idea how to improve container isolation in this case. Any help is appreciated. Also, any assessment about security implications using --net=host
(as root or as user in container) is welcome.
I've encountered an issue regarding x11docker
and Kodi and I'm hoping you could provide some guidance on how to fix it.
When a termination signal is sent to x11docker
, like Ctrl-C
or kill -SIGTERM
, the container running Kodi usually crashes instantly. Looking through the logs, it seems that this is due to the fact that the X server goes down before the container running Kodi. Apparently Kodi doesn't handle a vanishing X server very well.
If, on the other hand, I use docker stop
to stop the Kodi container then everything shuts down cleanly. This is a little annoying, though, because I have to look up and/or calculate the name of the container to stop it. It would be a heck of a lot easier to simply send a SIGTERM
to x11docker
and be done with it.
Perhaps a solution would be for x11docker
to stop the container and then stop the remaining supporting processes? The teardown process in x11docker
is a little hard for me to follow, so I'm not sure I can offer up a PR.
Here are some debug logs:
The second log is really big, but if you search for xinit: connection to X server lost
you can see where the crash starts.
Appreciate any guidance you can offer. Thank you.
I know git saves the file executable flags (I have some bash scripts in one of my projects)
First of all, dpkg-reconfigure x11-common does not have expected result on Ubuntu 16.10 because Xwrapper is not present. It can be installed with xserver-xorg-legacy package, but still x11docker doesn't work as expected.
I've got non-root user that's a member of "docker" group.
When I try to start x11docker with verbose option, I see following message:
" xf86OpenConsole: Cannot open virtual console 7 (Permission denied)"
Also I needed to change every occurence of ' GETROOT="" ' to ' GETROOT="bash -c " ' because of another issue (when GETROOT variable is empty, x11docker says "file not found" because whole command is quoted and bash treats it as a file).
Thank you very much for this awesome project. It looks very promising. 👍
Have you tried to use a non desktop Linux on host and automatically let start a desktop environment via x11docker on bootup? And then use this desktop container to start other applications like Google Chrome via x11docker on host?
I'm curious if this makes sense or should I use a desktop GUI on host to start other applications via x11docker? What do you think?
I made my image production ready, thus with minimal packages. I moved all GUI related packes to x11docker IDE script:
#!/bin/bash
[ -n "$(which x11docker)" ] \
|| { echo "x11docker is required"; exit 1; }
CMD=${@}
[ -n "${CMD}" ] \
|| { echo "Command is required"; exit 1; }
SCRIPT_DIR=$(dirname $(readlink -f "$0"))
PROJECT_DIR=$(dirname ${SCRIPT_DIR})
IMAGE=defacto_php
NETWORK=defacto_default
[ -n "$(docker images -q --filter=reference="${IMAGE}")" ] \
|| docker build -t ${IMAGE} ${SCRIPT_DIR}
[ -n "$(docker network ls -q --filter name=${NETWORK})" ] \
|| docker-compose -f ${SCRIPT_DIR}/docker-compose.yml up -d
x11docker \
--hostdisplay \
--homedir ${HOME} \
--clipboard \
--stdout --stderr \
--cap-default \
--no-init \
--workdir ${PROJECT_DIR} \
--runasroot "apt-get update && apt-get install -y \
libgtk2.0-0 libcanberra-gtk-module libxext-dev libxrender-dev \
libxtst-dev libxslt-dev dmz-cursor-theme \
git wget htop zip unzip nano" \
-- "--cap-add=SYS_PTRACE --publish=80:8080 --network ${NETWORK}" \
${IMAGE} ${CMD}
The startup takes a while, so some logs showing what's happening will be useful.
kmuehlbauer wrote:
Sorry, if this is the wrong place to ask.
I'm using docker on my host machine with my user being in the "docker"-group. So I can initiate
docker run
-commands without using passwords. At the moment I'm stuck with x11docker complaining about:x11docker ERROR x11docker ERROR: docker did not start successfully.
and a missing
docker.pid
-file.Unfortunately I did not find anything related. Hope you can shed some light.
Update: I'm now using -P switch, but now I get some permission problems.
x11docker.log:
x11docker.txt
@ugallu wrote:
Is there any way to restart stopped containers with x11docker, instead of images? (I tried committing containers as images and running them, but it failed)
For some reasons I decided to work with images only instead of restarting containers. Most important, docker expects mounted volumes to exist on host even for stopped containers; this becomes an issue with X sockets in /tmp/.X11-unix
. Those sockets only exist while the X server is up and running. After a reboot, docker misses this X socket and creates a useless and annoying folder in /tmp/.X11-unix
as a replacement.
If you wish to have persistant changes in user configuration and files, x11docker provides options --home
and --homedir
. For changes in the system itself, especially installing additional applications, I recommend to create a new image. Example dockerfile:
FROM x11docker/xfce
RUN apt-get update
RUN apt-get install -y firefox
Build a new image based on this dockerfile, and you have a good and maintainable base.
A possibility I did not test out well:
While the container is up and running, you can create a new image from the container with docker commit containernumber mynewimage
. This new image can be started with x11docker.
Is there a special reason why you want to reuse containers instead of creating new ones?
Command run: x11docker --xpra --sudo --verbose -- ' ' firefox /usr/bin/firefox
Docker file: firefox.txt
x11docker log file: x11docker.txt
I've tried multiple config options, but if I use --xpra or --xorg, I get this error. Seems Xorg is not happy with -config being an absolute location.
Hi , I dont know if it is right place to ask this question but I really need help.
I am trying to build a project and I basicly need a docker image and build that has HW accelared docker container with audio installed a Firefox browser that can be controlled from a browser via HTML5 websockets ( both visual and sound access ) , I have been searching for this and I found your project that has these features i guess , but I am not sure what build commands that I should use. Or can I do this without any additional tools by only using docker ? if so I really appreciate your suggestions thanks for this project really great job
please add https://www.deepin.org/en/dde/
I'm using deepin Linux
x11docker --desktop --user=root --size 320x240 x11docker/lxde
Unable to start successfully
Apologies in advance if this is a simple fix.
I'm running x11docker with
sudo ./x11docker -acpdf --hostipc --size="1920x1080" --homedir="myhomedir" --user="myuser" -- "-p 1935:1935" myimagename
(--hostipc
seems to be required for using the x11grab input in ffmpeg, not sure if that's correct but it's a separate issue.)
My dockerfile extends x11docker/xfce
, with the relevant lines being:
RUN sed -i "s/buster main/buster main contrib non-free/" /etc/apt/sources.list
RUN echo "deb http://http.debian.net/debian buster main contrib non-free" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y ffmpeg pulseaudio-utils pavucontrol
When I run x11docker as above, pavucontrol in the container tries unsuccessfully to connect to pulseaudio in the host, repeating every 5s.
In the container I have
$ echo $PULSE_SERVER
unix:/pulse/native
$ cat /etc/pulse/client.conf
# Connect to the host's server using the mounted UNIX socket
default-server = unix:/pulse/native
# Prevent a server running in the container
autospawn = no
daemon-binary = /bin/true
# Prevent the use of shared memory
enable-shm = false
as expected.
In the host I have
$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7482c40e7de 063534af197c "env /bin/sh - /x11d…" 27 minutes ago Up 27 minutes 0.0.0.0:1935->1935/tcp x11docker_X101_04c384_mycontainername
$ getent group audio video
audio:x:29:pulse
video:x:44:
$ sudo docker inspect -f '{{ .Mounts }}' a7482c40e7de
[{bind ~~~/x11docker/myhomedir /home/myuser rw true rprivate}\
{bind /tmp/.X11-unix/X101 /X101 rw true rprivate}\
{bind /run/user/1000/pulse /pulse rw true rprivate}\
{bind /~~~/.cache/x11docker/X101-myimagename/pulseclient.conf /etc/pulse/client.conf rw true rprivate}\
{bind /usr/bin/docker-init /x11docker/tini ro false rprivate}\
{bind /~~~/.cache/x11docker/X101-myimagename/share /x11docker rw true rprivate}]
$ sudo docker inspect -f '{{ .HostConfig.GroupAdd }}' a7482c40e7de
[29 44]
$ sudo docker inspect -f '{{ .HostConfig.Devices }}' a7482c40e7de
[]
I add the devices info because of the comment here, but as I expected, adding "--device /dev/snd"
after --
in the x11docker args doesn't change anything.
Running pulseaudio -k
in the host after the container is up doesn't change anything.
The line load-module module-native-protocol-unix
is in /etc/pulse/system.pa
in both host and container.
Not sure what else could be the problem...
Hey
First of all i wanted to say that x11docker is absolutely great!
I am currently using x11docker to start a chromium container from a Debian host system. The Debian i am using is custom built and only has xserver-xorg-video-fbdev and xorg installed. The container i am running is started from terminal only (not booting into any desktop environment) Now i am facing the following issue: the display turns off after 5 or 10 minutes and goes completly black.
What i am currently trying to do is to move the mouse with xdotool every 240 seconds so the screen wont go black but this is not very easy (i managed to get this running with a firefox container but not with the nwjs (chrome) container i am currently using).
Is there any way or possibility to achieve that the display wont ever go black? Maybe there is a configuration for xorg or x11docker.
I'm curious if you've given any thought to any of the following versioning tools:
keeping a separate changelog, either in a CHANGELOG
file or via GitHub's Releases feature (see next bullet point)
Semantic versioning, though it looks like you may already be adhering to this?
As a user, I expect and find it convenient to see a separate changelog, and I found it a little unusual to see one embedded within the script. Was there any reason you went that route?
I tried to run an image with x11docker and a mostly grey window opens. Foolishly I tried out the ctrl + shift for mouse and keyboard grab. How can I undo that in order to close the window?
Is there catch-all command to display the application regardless of the window system it uses or other attributes that may or may not be known to the user?
Any ideas on how to proceed with the brave browser?
x11docker note: Using X server option --nxagent
x11docker ERROR: Docker startup seems to have failed!
Last lines of docker.log:
QT_X11_NO_NATIVE_MENUBAR=1
SHELL=/bin/bash
TERM=xterm
UBUNTU_MENUPROXY=
USER=jcalfee
XAUTHORITY=/x11docker/Xclientcookie
XDG_RUNTIME_DIR=/tmp/XDG_RUNTIME_DIR
XDG_SESSION_TYPE=x11
container=docker
x11docker: copy of environment stored in /x11docker/environment
Last lines of command stderr:
[8:72:0507/152124.370976:ERROR:bus.cc(394)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
ATTENTION: default value of option force_s3tc_enable overridden by environment.
[91:91:0507/152124.499940:ERROR:gl_surface_glx.cc(431)] GLX 1.3 or later is required.
[91:91:0507/152124.499968:ERROR:gl_initializer_x11.cc(157)] GLSurfaceGLX::InitializeOneOff failed.
[91:91:0507/152124.501728:ERROR:viz_main_impl.cc(195)] Exiting GPU process due to errors during initialization
[103:103:0507/152124.535774:ERROR:gl_implementation.cc(292)] Failed to load /usr/lib/brave/swiftshader/libGLESv2.so: /usr/lib/brave/swiftshader/libGLESv2.so: cannot open shared object file: No such file or directory
[103:103:0507/152124.537043:ERROR:viz_main_impl.cc(195)] Exiting GPU process due to errors during initialization
[8:70:0507/152124.540659:ERROR:browser_gpu_channel_host_factory.cc(119)] Failed to launch GPU process.
[8:8:0507/152124.851609:ERROR:process_singleton_posix.cc(323)] The profile appears to be in use by another Chromium process (7) on another computer (7b94c120690d). Chromium has locked the profile so that it doesn't get corrupted. If you are sure no other processes are using this profile, you can unlock the profile and relaunch Chromium.
Type 'x11docker --help' for usage information
For debugging, run x11docker in terminal and/or enable option '--verbose'
and look afterwards at logfile /home/jcalfee/.cache/x11docker/x11docker.log
Please report issues at https://github.com/mviereck/x11docker
./brave
set -o errexit
rel=xenial
function build() {
dir=$(dirname "$0")
docker build -t brave -f "$dir/brave.Dockerfile" "$dir" --build-arg REL=$rel
}
function install() {
set -o xtrace
deps="ca-certificates curl apt-transport-https"
apt-get update
apt-get install -y --no-install-recommends $deps
curl https://s3-us-west-2.amazonaws.com/brave-apt/keys.asc | apt-key add -
echo "deb [arch=amd64] https://s3-us-west-2.amazonaws.com/brave-apt $rel main" | tee -a /etc/apt/sources.list.d/brave-$rel.list
apt update
apt install -y brave
apt-get purge -y --auto-remove $deps
#rm -rf /var/lib/apt/lists/*
}
"${@-build}"
brave.Dockerfile
ARG REL=xenial
FROM ubuntu:$REL
RUN apt-get update
COPY brave /tmp
RUN bash /tmp/brave install
RUN apt-get install -y libasound2
RUN rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["brave"]
CMD [ "--user-data-dir=/data" ]
I found an issue with pulseaudio support. When it pulls the docker IP range to use from grepping the ip command, it gets "172.17.0.1/16", which it then uses to authorize pulseaudio. This results in the following error:
May 29 02:47:40 hermes pulseaudio[7973]: [pulseaudio] ipacl.c: Host part of ACL entry '172.17.0.1/16' is not zero!
The last number in the allowed IP mask needs to be 0. e.g.
pacmd load-module module-native-protocol-tcp port=35744 auth-ip-acl=172.17.0.0/16
This works correctly, however I did have to disable my firewall (ufw).
I'm running Ubuntu 17.04.
PS—I love this script! I was trying to do the same thing using LXD and not having much luck. This really makes it super easy.
Could I run x11docker on a ubuntu server installation with docker and dependencies installed? How could I create more than one instance on different VNC ports?
I have a freshly installed Fedora 28 (vanilla, i.e., with Gnome Shell). After I start docker with systemctl start docker
, I can run e.g. docker run --rm -it debian:buster-slim bash
:
$ docker run --rm -it debian:buster-slim bash
Unable to find image 'debian:buster-slim' locally
Trying to pull repository docker.io/library/debian ...
sha256:158fd8073d5e6319ffd8cae2a41cdde95a98ec572fa314f6154facd3232eb97d: Pulling from docker.io/library/debian
ff0d602f5a3a: Pull complete
Digest: sha256:158fd8073d5e6319ffd8cae2a41cdde95a98ec572fa314f6154facd3232eb97d
Status: Downloaded newer image for docker.io/debian:buster-slim
root@1b3511e3151a:/# exit
exit
However, when I try with x11docker I get:
$ ./x11docker debian:buster-slim bash
x11docker note: Using X server option --xorg
x11docker WARNING: Your configuration does not allow to start
a second core Xorg server from within X. Option --xorg will probably fail.
(As a default configuration, only root or console users can do that).
Recommended easy solution: install one of nested X servers
'nxagent', 'Xephyr' or 'Xnest'.
Solution with --gpu support: install 'Weston' and 'Xwayland'.
Or you can switch to console tty1...tty6 with <CTRL><ALT><F1>...<F6>
and start x11docker there.
Setup to start a second Xorg X server from within already running X:
Edit file '/etc/X11/Xwrapper.config' and replace line:
allowed_users=console
with lines
allowed_users=anybody
needs_root_rights=yes
If the file does not exist already, you can create it.
On Ubuntu 16.04 and debian 9 you need package xserver-xorg-legacy.
x11docker note: Did not find a nice solution to run a seamless application
on your desktop. (Only insecure option --hostdisplay would work).
It is recommended to install nxagent or xpra.
x11docker note: Could not find Xephyr, Xnest, nxagent,
xpra, weston+Xwayland or kwin_wayland+Xwayland to run a nested X server.
Consider to install one of them.
x11docker note: You can switch between X servers and console terminals
with [CTRL][ALT][F1]...[F12].
x11docker WARNING: On debian 9, switching often between multiple X servers can
cause a crash of one X server. This bug may be debian specific and is
probably some sort of race condition. If you know more about this or it
occurs on other systems, too, please report.
x11docker note: Could not detect a host window manager.
Please specify one with option --wm=WINDOWMANAGER or install one of
amiwm blackbox cinnamon compiz ctwm enlightenment fluxbox flwm fvwm jwm kwin lxsession mate-session mate-wm marco metacity notion olwm olvwm openbox ororobus pekwm sawfish twm wmaker w9wm xfwm4
x11docker WARNING: Although x11docker starts Xorg as unprivileged user,
most system setups wrap Xorg to give it root permissions (setuid).
Evil containers may try to abuse this.
Other x11docker X server options like --xephyr are more secure at this point.
x11docker ERROR: Please make sure docker daemon is running.
Try as root: 'systemctl start docker'
Type 'x11docker --help' for usage information
For debugging, run x11docker in terminal and/or enable option '--verbose'
or look afterwards at logfile ~/.cache/x11docker/x11docker.log
Please report issues at https://github.com/mviereck/x11docker
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
I tried with --hostdisplay
too:
$ ./x11docker --hostdisplay debian:buster-slim bash
x11docker note: Your X server does not support untrusted cookies.
Have to use trusted cookies and to enable insecure option --hostipc.
Consider to use options --nxagent or --xpra instead of --hostdisplay.
x11docker WARNING: Option --hostdisplay with trusted cookies provides
QUITE BAD CONTAINER ISOLATION !
Keylogging and controlling host applications is possible!
x11docker WARNING: Security risk:
Option --hostipc causes severe reduction of container isolation!
Drawback: IPC namespace remapping is disabled.
Advantage: X extension MIT-SHM is possible.
x11docker ERROR: Please make sure docker daemon is running.
Try as root: 'systemctl start docker'
Type 'x11docker --help' for usage information
For debugging, run x11docker in terminal and/or enable option '--verbose'
or look afterwards at logfile ~/.cache/x11docker/x11docker.log
Please report issues at https://github.com/mviereck/x11docker
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
I also tried running x11docker with sudo and installing nxagent
. But I get the same result.
$ ./x11docker --nxagent btdi/texstudio bash
x11docker ERROR: Please make sure docker daemon is running.
Try as root: 'systemctl start docker'
Type 'x11docker --help' for usage information
For debugging, run x11docker in terminal and/or enable option '--verbose'
or look afterwards at logfile ~/.cache/x11docker/x11docker.log
Please report issues at https://github.com/mviereck/x11docker
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
The verbose option does not produce any output. The log file is empty.
Previously I was successfully using this script in Fedora 25, Fedora 26 and Windows 10 (with Xming). Therefore, I don't mind using the least secure options that x11docker provides (for now). What's the most straightforward solution to achieve it?
My target, after a simple image works, is to run image btdi/texstudio
.
BATS or another TAPS compliant framework could integrate nicely with the script and make it easier to diagnose issues on different platforms.
I have docker binaries in my home directory and I start docker like this
#!/bin/bash
sudo env PATH=/sbin:$PATH dockerd \
--group $(id -g) \
--config-file /home/o/docker/config.json \
--data-root /home/o/docker/data \
--exec-root /home/o/docker/run
Also in .bashrc
in configured the PATH
variable
I do this because my root partition is small (only for system and installed programs) but docker images require a lot of space that's why I made it store all docker related data in my /home partition.
This command doesn't detect my running docker daemon
Line 1109 in 6b46a8a
It works when I replace it with
Dockerdaemon="$(pidof dockerd)" # how docker daemon has been started
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.