Переслать X11 через SSH-соединение с хостом контейнера?
Я хотел бы запустить приложение GUI в контейнере с удаленного компьютера.
Я не хочу решать эту проблему, добавив хост SSH в контейнер, потому что
- У меня уже есть доступ к хост-машине через SSH
- Это добавляет ненужные накладные расходы
- Это делает контейнер непереносимым между удаленным и локальным использованием
Я уже могу успешно запускать приложения с графическим интерфейсом на хосте, но не из контейнера. Вот шаги, которые я предпринял до сих пор:
хозяин
xauth +
(не на длительный срок, но полезно для устранения возможных проблем)docker-user
с идентификатором 501000 на хосте ==docker-user
с uid 1000 в контейнере через функцию пространства имен.Xauthority
файл скопирован вdocker-user
домашняя папка
Dockerfile
- На основе альпийского
- Установлено
xauth
и, для целей тестирования,xterm
- Создает
docker-user
с надлежащей UID / GID
докер-Compose
- Переменная среды
DISPLAY
отправлено в - объем
/home/docker-user/:/home/docker-user/:ro
предоставлять.Xauthority
печенье - объем
/tmp/.X11-unix:/tmp/.X11-unix:ro
обеспечить доступ к сокету X11 - Запускает команду
su - docker-user -c "export DISPLAY=$DISPLAY && xterm"
su
раньше бегал какdocker-user
DISPLAY
перенаправлен вsu
контекст
К сожалению, этого еще недостаточно. В то время как xterm в операционной системе хоста подключается к моему локальному X-серверу без проблем, xterm в контейнере говорит Xt error: Can't open display: localhost:10.0
,
Я подтвердил, что "localhost:10.0" правильный, localhost существует в контейнере /etc/hosts
и cookie и сокет делают это с правильными разрешениями.
Что еще может пойти не так?
3 ответа
Похоже, что вы делаете все то же самое, что и я, за исключением того, что вы делитесь.Xauthority во время создания контейнера. Это означает, что если вы когда-либо создадите ssh -X на своей машине после создания контейнера,.Xauthority больше не будет действительным. Вы не можете ssh -X из другого терминала в ту же машину и вернуться назад и использовать.Xauthority, ssh -X каждый раз меняет.Xauthority для самого последнего терминала. Я только заставил его работать, копируя.Xauthority каждый раз, когда я запускаю ssh -X на свою машину и пытаюсь поделиться экраном с моим контейнером.
примечание: я поделился устройством и идентификатором компьютера, потому что я переадресовал выходные данные веб-камеры
1. Создайте контейнер и сообщите xhost, чтобы разрешить пересылку с идентификатора контейнера:
sudo docker run -it -d \
--net=host \
--env="DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
--device="/dev/video0:/dev/video0" \
--volume="/path/to/your/sharedDockerFiles:/root/sharedDockerFiles" \
--volume="/etc/machine-id:/etc/machine-id" \
yourdockerrepo/image:tag \
bash
export containerId=$(docker ps -l -q)
sudo xhost +local:`sudo docker inspect --format='{{ .Config.Hostname }}' $containerId`
sudo docker start $containerId
2. Скопируйте.Xauthority из домашнего хоста в каталог sharedDockerFiles:
sudo cp ~/.Xauthority /path/to/your/sharedDockerFiles
3.Запустите и прикрепите свой контейнер
4.Скопируйте.Xauthority из вашей общей папки в ваш домашний контейнер
sudo cp /root/sharedDockerFiles/.Xauthority ~/
5.(необходимо один раз): отредактируйте контейнер /etc/ssh/ssh_config в Host *, включив в него:
ForwardX11 yes
X11Forwarding yes
6.Перезапустите свой контейнер, подключите и запустите приложение с графическим интерфейсом.
7.Если у вас все еще есть проблемы, убедитесь, что переменная $DISPLAY в контейнере совпадает с переменной хоста
echo $DISPLAY #do this in the container
exit
echo $DISPLAY #do this in the host, should be the same as container's
#if they aren't equal, start container and:
export DISPLAY= #put the output of your host's $DISPLAY variable here
Скопируйте.Xauthority в контейнер в начале сеанса SSH перед использованием GUI:
sudo docker exec -i container_name bash -c 'cat > ~/.Xauthority' < ~/.Xauthority
Затем вы можете передать DISPLAY, если используете 'docker exec'. Например, чтобы открыть новый Bash:
sudo docker exec -it --env="DISPLAY" container_name bash
Еще 2 возможных причины ошибки: (в дополнение к принятому ответу)
basic: у вас нет ssh-сервера или xauth в контейнере (для ubuntu запустите 'apt install openssh-server xauth')
подлый: Если ваше имя хоста контейнера отличается от имени хоста (например, установите через -h значок в 'docker run'), вы получите ошибку, и вам придется с этим справиться (например, установить то же имя хоста или добавить cookie в Xauth)
Давайте запустим docker с параметром --net=host. Это заставляет контейнер видеть тот же сетевой стек хоста.
Например,
запуск докера --net = хост --rm -ti -u myid -e DISPLAY="$DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix image: тег BINARY