Unable to open remote display on Mac when running Docker - macos

I have a Dockerfile written as below:
FROM joesan/raspi_opencv_3:latest
RUN apt-get update
RUN sudo apt-get install --no-install-recommends xserver-xorg
RUN sudo apt-get install --no-install-recommends xinit
RUN apt-get install -qqy x11-apps
RUN mkdir -p /raspi_motion_detection/project
WORKDIR /raspi_motion_detection/project
COPY ./ $WORKDIR/
COPY ./requirements.txt $WORKDIR/
ADD . $WORKDIR
CMD xclock
I have a Raspberry Pi to which I ssh from my Mac (running High Sierra).
Here is what I do:
I ssh into the RaspPi from my Mac
I execute the docker command using:
docker run -ti --device=/dev/vcsm \
--device=/dev/vchiq \
-e DISPLAY=$DISPLAY:0 \
-e XAUTHORITY=/.Xauthority \
-v /tmp/.X11-unix:/tmp/.X11-unix \
joesan/motion_detector
I get an error message as below:
Error: Can't open display: localhost:11.0:0
But when I just run xclock directly on the ssh terminal, I can see that the xclock window opens up.
So I could not understand why running xclock from within a Docker container would prevent the display port being opened? Any reasons? I also came across this post here and followed what has been described there, but i could not get it to work!
https://medium.com/#dimitris.kapanidis/running-gui-apps-in-docker-containers-3bd25efa862a

A bit simplified: Each docker container runs inside the docker daemon, which basically provides a stripped down os to each container. That os has no window manager.
That is why the command xclock inside a docker container exits with an error.
When you connect via ssh to your raspberry pi and call xclock it is executed inside the raspberry's os (propably raspian), which has a running window manager.

Ok! So I thinkI found the solution to my problem! Here is what I did!
Re-installed Raspberry Stretch Lite on my SD card. The old one seems to have gotten some stale files! You can skip this step, but for me there was some corrupt files on the old installation, so I decided to get a fresh install!
On my Raspberry Pi, run the following command:
xauth list
I copy the cookie locally to a text editor as I need it later!
Removed the xclock command from the Dockerfile that I originally had!
Build the Dockerfile using the following command:
docker run -it --net=host --device=/dev/vcsm --device=/dev/vchiq -e
DISPLAY -v /tmp/.X11-unix joesan/motion_detector bash
Notice that I'm running a bash command to my Docker run so that I can get a basj prompt from the running image!
The result of step 3 would give me a bash prompt from the container that I just ran at step 3
I need to now install xauth in the image
apt-get install xauth
I then add the xauth cookie from step 0
It is after this Bang! I got what I want!

Related

Docker image based on Playwright image runs on my Mac but don't run on Ubuntu server

When I run this image om my Mac with M1 chip, everything is OK.
But when I try to run on server with Ubuntu, container stops with error "exec /bin/sh: exec format error"
FROM mcr.microsoft.com/playwright:v1.18.1-arm64
RUN apt-get -y update && apt-get -y upgrade
ADD build/libs/program.jar /tmp
WORKDIR /tmp
RUN apt-get -y install openjdk-11-jre-headless && apt-get clean;
CMD java -jar program.jar
This error displays on each first command RUN. Even if the command is like "RUN ls -la", I will get "/bin/sh -c ls -la returned a non-zero code: 1".
I tried to change SHELL["bin/bash","-c"] and image version but there was no effect.
If I use "FROM ubuntu", commands work, but I need exactly image for Playwright with browser dependencies.
You are building an image with ARM architecture (check with docker inspect <your_image> | grep "Archi"). This image cannot be executed on another architecture (probably amd64 for your Ubuntu server).
You should:
use an amd64 base image (mcr.microsoft.com/playwright:v1.18.1-arm64 => mcr.microsoft.com/playwright:v1.18.1-focal for example)
build your image with docker build --platform linux/amd64

Docker is not running when run curl command to create new laravel project

I just start learning laravel, and follow the tutorial from https://laravel.com/docs/8.x/installation "Getting started on Windows" .
I manage to install Docker Desktop and COnfigured to use WSL2 Backend.
When I run the command curl -s https://laravel.build/example-app | bash to create laravel application directory from cmd, this warning come out Docker is not running.
I run curl using command prompt. (cmd).
Update:
So, I run the command in Windows Terminal:.
PS E:\Play> curl -s https://laravel.build/example-app | bash
Here is the response I get:
cmdlet Invoke-WebRequest at command pipeline position 1
Supply values for the following parameters:
Uri:
Any Idea what to do?
Try to explicitly enable integration with your distro in Docker settings:
After that relaunch your WSL2 terminal & try again. That should help.
You can also open https://laravel.build/example-app in a browser & check what commands the script is running: and run them manually to check the output for any errors.
For those who are using Ubuntu or Debian can check this guide out on how to install and configure Docker.
sudo snap install docker
sudo usermod -aG docker $(whoami)
sudo chmod 666 /var/run/docker.sock
You need to install a linux distro, and then in Windows Terminal create a new tab for the linux distro and run the command there, not in a windows powershell tab.
Make sure that you are running curl command on your distro. Use Windows Terminal app and open a new tab as WSL2 (your distro).
sudo chmod 666 /var/run/docker.sock
I guess you are using ubuntu or debian.
chmod will do the trick here.

Can you convert/build a docker image into a full OS image?

I have made a docker container meant with some code for deployment. However, I realised that the structure of the project I'm working with, it's more suitable to deploy a full ISO image, instead of running docker on top of a cloud VM running stock debian, leading to unnecessary layers of virtualization.
I know that dockers are meant to be deployed on kubernetes, but before diving into that route, is there a simple way to convert a deb9 docker image into a full deb9 OS image? Like an opposite of docker import?
You can convert your docker container to an full os image. An Dockerfile debian example would be
FROM debian:stretch
RUN apt-get -y install --no-install-recommends \
linux-image-amd64 \
systemd-sysv
In principal you have to install a kernel and an init system.
Full instructions can be found github
Docker images don't contain a Linux kernel and aren't configured to do things like run a full init system or go out and get their network configuration, so this won't work well.
Put differently: the same mismatch that makes docker import not really work well because the resulting container will have too much stuff and won't be set up for Docker, means you can't export a container or image into a VM and expect it to work in that environment.
But! If you've written a Dockerfile for your image, that's very close to saying "I'm going to start from this base Linux distribution and run this shell script to get an image". Tools like Packer are set up to take a base Linux VM image, run some sort of provisioner, and create a new image. If you have a good Docker setup already, and decide a VM is a better fit, you're probably done a lot of the leg-work already to have an automated build of your VM image.
#info
we can use docker like vm / flatpak / appimge / termux with gui, audio and hardware acceleration :)
how to do it ?
remove old docker
sudo apt-get remove docker docker-engine docker.io containerd runc
===================
install the commponents
sudo apt-get update
sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release
=============================
3.. add docker repo docker
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
================
install docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
=============================
=========================
create docker
docker image
su
cd /home/
kwrite Dockerfile
FROM debian:testing
ARG DEBIAN_FRONTEND=noninteractive­
RUN apt-get update && apt-get -y install midori bash mpv pulseaudio pulseaudio-utils pulsemixer pulseaudio-module-jack apulse neofetch vlc smplayer wget sudo cairo-dock cairo-dock-plug-ins xfce4 xfce4-goodies falkon kde-full xfce4-whiskermenu-plugin gnome tigervnc-standalone-server openssh-server openssh-client network-manager net-tools iproute2 gerbera openjdk-11-jdk mediainfo dcraw htop gimp krita libreoffice python3-pip terminator uget alsa-utils
ENV PULSE_SERVER=tcp:host.docker.internal:4713
CMD bash
save it
the run interminal
sudo docker build -t supersifobian .
how to use gui
xhost +
run image gui
sudo apt-get -y install xpra xserver-xephyr xinit xauth
xclip x11-xserver-utils x11-utils
run docker
sudo docker run -ti --net=host --device=/dev/dri:/dev/dri -e DISPLAY=:0 --privileged --cap-add=ALL --device /dev/snd --volume /dev:/dev -v /dev:/dev --group-add audio -v /var/run/docker.sock:/host/var/run/doc -e PULSE_SERVER=tcp:$P ULSE_SERVER -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /media:/host/media:ro -v /home:/host/home:ro imageid / image name
nb
enter container
docker exec -it nama/id container bash
add user
adduser namauser
make use as sudo
usermod -aG sudo username
add group audio
usermod -aG audio username
=========================
audio in docker cli
using prafer
a. install paprefs
apt-get install paprefs
b.choose network in prafers
c. how to know the pulse audio port, we can type
pax11publish
d. export to terminal in docker
export "PULSE_SERVER=tcp:192.168.43.135:37721"
==================================
save docker
docker commit idcontainer nameimage:version
========================
check images
docker images
==================================
thanks :)

How to expose audio from Docker container to a Mac?

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

Keyboard/Mouse are unresponsable when running x-org in a docker container

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

Resources