i am attempting to run a windows GUI app in a container on Linux. The intent is to protect an ancient windows app that is no longer supported. So i get a Red Hat developer subscription, install RHEL 8.6 with container tools, run the universal base image 'UBI-INIT', and within the container, i install GNOME desktop with Xrdp, and i successfully render the GUI desktop in a RHEL container.
Now that the container is working well, I commit to an image, but when i run that image, the GUI fails to render. the xrdp session times out as if services are not running and/or ports are not accessible.
Within the container that i ran from the committed image:
i verify that all of the services necessary to support XRDP and GNOME are up and running.
journalctl does not seem to show any errors. There are complaints around rtkit but i see similar errors in the working container.
i see no evidence that an xrdp connection was attempted in the xrdp or xrdp-sesman logs. But i am fairly certain that ports are not the issue because i can ssh to the container.
the commands i used to install and configure the working container are:
podman run -d -v /mnt/share:/share -p 53389:3389 -p 50022:22 --rm --privileged --name ubi-ini registry.access.redhat.com/ubi8/ubi-init;
podman exec -it ubi-ini bash
and within the container i run the following:
timedatectl set-timezone America/New_York
# GNOME desktop GUI
dnf install -y selinux-policy-targeted
dnf groupinstall -y --skip-broken "Server with GUI"
# xrdp
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf install -y xrdp
echo 'if [ "$DISPLAY" !=' "'\"\"' ]; then xhost +; fi;" >> /etc/profile
sed -i '/^port=3389.*/a port=tcp://:3389' /etc/xrdp/xrdp.ini
useradd -g root -p $(echo "jde" | openssl passwd -1 -stdin) jde
usermod -aG wheel jde
systemctl enable xrdp xrdp-sesman gdm
systemctl unmask systemd-logind.service
systemctl restart sshd xrdp xrdp-sesman dbus gdm systemd-logind.service
I commit the image like this:
podman commit ubi-ini ubi-gui
I run the image with this command:
podman run -d -v /mnt/share:/share -p 63389:3389 -p 60022:22 --rm --privileged --name ubi-gui ubi-gui
xrdp communicates with the desktop manager through systemd UBI-INIT is the only linux base container that supports systemd.
i suspect there is something about the processes in the derived container but when i compare the working and non-working container with ps aux, i don't see significant anomolies.
Any ideas?
I have absolutely no idea about 'XRDP' but I see you use a different host port in your second container instance, is that intentional?
Got this to work by disabling firewall and selinux everywhere, meaning the container host abd the base container UBI-INIT as well. Now the image based on the modified container (with Gnome desktop and XRDP and disabled security) results in a container that serves the GUI desktop.
It's working fine except that gdm (gnome desktop manager) does not start even though it is enabled and all the other enabled services are ok. Still working that one out, but the basic question is answered: it was not the software stack but rather it was security configuration. i suspect selinux in the container somehow interfered with inter-process communication, because i am able to ssh on (mapped) port 22 externally.
Related
I need to have acces to windows com port(COM3) form docker linux contianer:
I tried like this:
docker run -d --name test_com_port -p 8090:80 --device=/dev/ttyACM14 --restart always test_com_port
docker run -d --name test_com_port -p 8090:80 –-device=COM3:/dev/ttyS2
--restart always test_com_port
docker run -d --name test_com_port -p 8090:80 –-device=//./COM3:/dev/ttyS2
--restart always test_com_port
but don't have any results. Also I visited microsoft tutorial but it is only for windows containers. Maybe some one have any solutions how to solve it?
hey there I was successfully able to map a windows serial device to a docker container, it was a long and tedious task but in the end I was successful. Any who has access to windows 10 with support for WSL 2 can follow these steps:
1.) Install WSL 2 with Ubuntu distro as it's easier to work with.
2.) On the windows host machine install this software called usbipd through command winget install usbipd for more information use this link
3.)Now we have to configure a few things in the Ubuntu distro so that the interfacing happens for that you will have to follow this link
4.)Once that is done you can now mount the device, before we start the mounting process make sure to plug-in the device to the windows host
5.)Before mounting you can check the list of available devices with usbipd wsl list. You will be able to see all the serial devices connected and now you can
interface or mount or attach using the command usbipd wsl attach --busid=<BUSID>
6.)Once the device is attached you can open the wsl Ububtu use the command lsusb to check all available serial devices which communicate over USB.
7.)Now the final step is to mount the device to docker container with command --device /dev/<available port>; ex doecker run -d --device=/dev/<available ports from liunx ubuntu distro> <container>
My docker version is:
docker --version
Docker version 20.10.2, build 2291f61
My windows version is:
systeminfo
Nom du système d’exploitation: Microsoft Windows 10 Professionnel
Version du système: 10.0.17763 N/A version 17763
Type du système: x64-based PC
My Dockerfile is:
FROM ubuntu:21.04
RUN apt update
RUN apt-get install -y bluez bluetooth usbutils
When I run the following command, I start the 'bluetooth_in_docker' container:
docker build -t bluetooth_in_docker . & docker run --privileged --net=host -it bluetooth_in_docker bash
Inside the container when I run the following, I get an error:
hciconfig dev
Can't open HCI socket.: Address family not supported by protocol
I got it working on Windows from inside WSL2, but it takes a lot of steps.
Follow https://github.com/dorssel/usbipd-win/discussions/310 to get
your bluetooth working inside WSL2. Verify that you can scan for
bluetooth devices inside your WSL2 distro.
modify your dockerfile to install bluetooth as you did (bluez and usb-utils might not be needed)
Now there are 2 options. First option shares bluetooth with container. Second option gives container exclusive control.
Sharing bluetooth between the host and the container is possible by making a volume mount of /var/run/dbus and running it with --privileged:
docker run -v /var/run/dbus/:/var/run/dbus/:z --privileged {containerImage}
Make sure that the dbus and bluetooth services are working in your host when running the container this way.
Giving the container exclusive control: in WSL2 (the host), run a docker container according to https://stackoverflow.com/a/64126744/1114918
run sudo service bluetooth stop to make your bluetooth not "claimed" by the host (the linked answer uses killall, I think sudo service ... stop is cleaner)
use a sh script to start dbus and bluetooth inside the container
run the container using
docker run --rm --net=host --privileged myimage:mytag
I want to disable all outgoing connections that are initiated by docker containers to the outside world. I can do this in linux by adding a rule to the FORWARD chain in linux. How do I do this in Docker for Mac?
I found out that Docker for Mac uses an xhyve vm and that’s where docker0 interface lives. What interface in the host does this connect to? I used nettop on Mac and I see that Docker uses my en0 wireless interface. But, I’m not sure if Docker and xhyve are using the same interface.
Edit: Added docker-for-windows tag because they might have similar solutions (Hoping)
Edit 2: Docker for Mac has changed so the accepted solution changed a bit
Docker
$ docker run --net=host --privileged -ti alpine sh
# apk update && apk add iptables
# iptables -vnL
This and the rules could be turned into a Dockerfile and run with a -- restart option. I think on-failure might work to reapply the rules when Docker for Mac starts up.
Virtual Machine
To get to the linux VM:
mac$ brew install screen
mac$ screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
Since the move to linuxkit, this is not your average linux host, everything's a container:
linuxkit:~# ctr -n services.linuxkit tasks ls
TASK PID STATUS
acpid 925 RUNNING
diagnose 967 RUNNING
host-timesync-daemon 1116 RUNNING
ntpd 1248 RUNNING
vpnkit-forwarder 1350 RUNNING
docker-ce 1011 RUNNING
kubelet 1198 RUNNING
trim-after-delete 1303 RUNNING
vsudd 1398 RUNNING
Use runc to move into the docker-ce (or docker) namespace
linuxkit:~# runc --root /run/containerd/runc/default exec -t docker-ce /bin/sh
docker-ce # iptables -vnL
Note that rules will disappear after a restart of Docker for Mac. I haven't found the secret sauce for persisting system changes yet.
Use ctrl-a then d to exit the screen session otherwise you will bork the terminal.
OSX
For the easy but € option, use Little Snitch and block outbound connections on OSX from com.docker.supervisor via vpnkit.
Try Mac's pfctl command, it's kind of equivalent to iptables.
Here's man page: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man8/pfctl.8.html
I know it's possible by using pulse audio on a Linux host system But paprefs is built for linux not mac.
The Docker-for-Mac VM doesn't have any sound passthrough device, so there isn't anything that you could take advantage of from that angle. By contrast, a virtualbox or vmware fusion VM does have the ability to do passthrough audio.
I was able to get pulseaudio installed and working on OSX with the following command:
brew install pulseaudio
I was able to verify this worked by running the following, hearing sound come out of my speakers:
paplay cockatiel.wav
My next step is to find an image that has a copy of paplay. I found jess/pulseaudio, which appears to be intended to be a pulseaudio server, but I should be able to use it as a client as well.
I found the following guide on the Archlinux Wiki discussing setting up pulseaudio network sound: https://wiki.archlinux.org/index.php/PulseAudio/Examples#PulseAudio_over_network
I was able to adapt it to this situation by doing the following. I edited /usr/local/Cellar/pulseaudio/9.0/etc/pulse/default.pa on my mac, and uncommented the following two lines:
load-module module-esound-protocol-tcp
load-module module-native-protocol-tcp
I reran paplay cockatiel.wav on my mac to make sure my changes still worked. the pulseaudio daemon seems to start on demand, and passes its complaints back to paplay to be printed on my screen if I made a typo. I still have sound with those changes to default.pa, so I'm satisfied that my changes didn't break anything.
Next, I ran the pulseaudio client in a container like this:
docker run --rm -v $HOME:$HOME -w $HOME -it \
-e PULSE_SERVER=192.168.10.23 \
-e HOME=$HOME --entrypoint paplay \
jess/pulseaudio $HOME/cockatiel.wav
What this does is run a container with my local home directory as a volume. This serves two purposes. The first is the fact that my cockatiel.wav is located inside $HOME. The second is because both the client and the server need to have a copy of the same ~/.config/pulse/cookie file (per that archlinux wiki guide).
The PULSE_SERVER environment variable is the en0 IP address of my OSX host, so paplay knows what to connect to.
The HOME environment variable is necessary so paplay can find the same ~/.config/pulse/cookie file.
I was able to play sound from a container running on my docker-for-mac via pulseaudio.
As long as you get the ~/.config/pulse/cookie file to appear in the correct location, you should be able to play sound. You don't have to use a host volume to accomplish this-- you could also do a 'docker cp', or even COPY it into an image.
Install PulseAudio on the Mac:
brew install pulseaudio
Run the daemon:
pulseaudio --load=module-native-protocol-tcp --exit-idle-time=-1 --daemon
In your Docker container:
Install PulseAudio, e.g., apt-get install pulseaudio.
set the following environment variable: ENV PULSE_SERVER=docker.for.mac.localhost
When you run it, share your ~/.config/pulse directory with the container for authentication.
You can run a test to see if it's working like this:
docker run -it -e PULSE_SERVER=docker.for.mac.localhost -v ~/.config/pulse:/home/pulseaudio/.config/pulse --entrypoint speaker-test --rm jess/pulseaudio -c 2 -l 1 -t wav
I want to create a docker image for a GUI application (e.g. Chrome) and I hope this GUI app could run at a bare Linux server without X server installed.
I know it is very easy to create and run a docker image just for X Window Client (The GUI application itself). This needs X server be installed and run at host.
sudo docker run -ti -v /tmp/.X11-unix:/tmp/.X11-unix xorg xterm -display :0
But for me, I need both X client and server run in docker container.
Here's my dockerfile:
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y xorg
And I run the image by command:
sudo docker run -i -t --rm -e DISPLAY=:0 --privileged xorg xinit
The X server could be started and my screen turns black, after a few seconds, the xterm window displays. BUT, I can't use keyboard and mouse. The screen seems like freezen
I have searched and tried many solutions but no one could fix this problem. (the virtual x-server is not I needed)
I have resolved this problem.
At first, I thought maybe x server in docker container cannot access host devices, and I spent much time on LXC/cgroup. For example, I changed the docker exec engine to LXC, and I added option '--lxc-conf='lxc.cgroup.devices.allow = c 13:* rwm', and I also created /dev/input/* in container.
All of these operations are unnecessary.
If we run docker container in privileged mode, all host devices will be added automatically. Or we can use options like '--device=/dev/input/mice' to share host device.
The real problem is that x server could not discovery and add device automatically. I don't know why. But we could modify x server's configuration and customize the device.
add file /etc/X11/xorg.conf.d/10-input.conf
Section "ServerFlags"
Option "AutoAddDevices" "False"
EndSection
Section "ServerLayout"
Identifier "Desktop"
InputDevice "Mouse0" "CorePointer"
InputDevice "Keyboard0" "CoreKeyboard"
EndSection
Section "InputDevice"
Identifier "Keyboard0"
Driver "kbd"
Option "Device" "/dev/input/event2"
EndSection
Section "InputDevice"
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "auto"
Option "Device" "/dev/input/mice"
Option "ZAxisMapping" "4 5 6 7"
EndSection
and run docker container:
docker run -i -t -v /tmp/.X11-unix:/tmp/.X11-unix --rm --privileged ubuntu startx
At first make sure that proper input modules are installed:
RUN DEBIAN_FRONTEND='noninteractive' apt-get install -y --no-install-recommends xserver-xorg-input-evdev xserver-xorg-input-all
In modern Linux udev is responsible for managing device nodes (including USB keyboards) in the /dev tree. It uses /run/udev/data which isn't available inside your container even with -privileged option.
So you need to mount that folder explicitly using -v /run/udev/data:/run/udev/data like this:
docker run -i -t -v /tmp/.X11-unix:/tmp/.X11-unix --rm --privileged -v /run/udev/data:/run/udev/data ubuntu startx