1. Подготовка
ВАЖНО: В разных дистрибутивах Linux политика доступа к сокету ‘/tmp/.X11-unix/X0’ разнится, если приложение внутри docker-контейнера выдает ошибку, что не может подключиться к дисплею ‘:0’, то перед запуском контейнера на машине пользователя нужно выполнять команду:
$ sudo xhost +si:localuser:<user>
Где - имя пользователя docker-хоста, от имени которого будет запускаться контейнер. Данная настройка действует только до следующей перезагрузки системы!
Также, если в контейнере предполагается использование VPN-соединений хоста, то нужно подымать эти соединения то того, как стартует контейнер, так как docker прокидывает с хоста файл /etc/resolv.conf и кэширует его.
2. Установка
Под установкой понимается сборка docker-образа и последующий его запуск, собственно 3 команды:
$ ip a
$ env UID=$UID HOST_IP=192.168.1.10 HOST_USER_PASS=<user_pass> ./install.sh
# где:
# - HOST_IP - IP адрес внешнего интерфейса машины docker_host, можно посмотреть командой ip a
# - HOST_USER_PASS - пароль пользователя, с которым прокидывался туннель на docker_host
$ ./start.sh
Полностью удалить контейнер из системы можно командой:
$ ./uninstall.sh
Скрипт для остановки контейнера не нужен, так как после закрытия GUI контейнер остановится автоматически. Если же по каким-то причинам нужно принудительно остановить контейнер, то можно выполнить:
$ docker-compose stop
3. Пояснения
Образ alpine был выбран потому, что он минималистический и не имеет предустановленного пользователя UID=1000. В то время как, например, образ Ubuntu, имеет предустановленного пользователя [ubuntu:uid:1000].
В контейнере намеренно создается пользователь с тем же именем и uid, от имени которого работает пользователь хоста. Это делается с той целью, чтобы не было проблем доступа из контейнера к файловой системе хоста и к X-сокету.
При сборке параметр env UID=$UID задается явно (в отличие, например, от $USER) потому, что он отсутствует в переменных среды. Но он присутствует в переменных оболочки, echo $UID выведет имя пользователя.
Переменные среды UID, HOST_IP, HOST_USER_PASS нужны только для сборки образа. А переменная среды DISPLAY нужна только для старта, она захардкоджена в скрипте start.sh.
Изнутри докера для GUI приложений прокидывается прямой туннель на хост к X-сокету.
$ sshpass -p $ENV_HOST_USER_PASS ssh -o StrictHostKeyChecking=no -CNL localhost:6000:/tmp/.X11-unix/X0 $ENV_HOST_USER@$ENV_HOST_IP
Прокидка X-сервера пользователя через unix-сокет /tmp/.X11-unix/X0 делается потому, что локальные подключения к нему от имени текущего пользователя на распространенных Linux-станций не требуют аутентификации. Иначе бы пришлось выполнять многочисленные танцы с бубном вокруг ~/Xauthority, xauth и/или xhost.
Значение DISPLAY в start.sh, менять не нужно, так как оно используется внутри контейнера и не меняется при прокидке (порт 6000 прямого туннеля).