Рабочая станция в Docker контейнере

в 17:46, , рубрики: containers, devops, docker, remote desktop, tigervnc, vnc

Для чего? Мне постоянно приходят всякие идеи и некоторые из них сразу хочется попробовать, но рабочая станция не всегда под рукой, поэтому я настраивал IDE на всем что попадется под руку. В итоге устройства начали захламляться, а поддерживать и обновлять их стало тяжело. Что бы решить эту проблему я решил разместить такую «записную книжку» в облаке, и что бы ежедневно обновлялась и удаляла весь накопившийся мусор. А для работы подключаться к нему удаленно.

image

В итоге, сам того не подозревая, сделал очень удобный инструмент для решения большого количества задач: записная книжка, тестовая площадка, посмотреть то что телефон не показывает, безопасная песочница, запуск скриптов для программ работающие только GUI и мн. др. А в статье хочу поделиться методом создания таких контейнеров.

Для создания такого контейнера необходимо написать свой Dockerfile. А в статье опишу весь процесс его создания. Кто не хочет создавать сам, а хочет взять и попробовать, то внизу статьи будут ссылки на готовые образы.

Операционная система

Подойдет любой линукс. Лично я предпочитаю красивый OpenSuse, но сравнив его потребление памяти с CentOS решил выбрать последний. Ведь чем меньше памяти потребляет контейнер, тем больше можно сэкономить на его хостинге.

Начнем создавать Dockerfile:

FROM centos:7

Удаленный доступ

Для того что бы подключиться к контейнеру на нем необходимо настроить сервер удаленного доступа VNC. Для этого надо понимать два фактора:

  1. У системы нету монитора. Поэтому его придется эмулировать. Для этого существует специальный сервер x0vncserver.
  2. VNC Server должен быть не прихотлив к ресурсам. Ведь за них надо платить. А лаги в передачи сигнала должны быть минимальны, иначе они вызывают дискомфорт.

Для решения обоих проблем я выбрал TigerVNC Server для сервера и TightVNC для клиента. TigerVNC Server входит в поставку любого линукса, легкий, быстрый, а также поддерживает работу без монитора через x0vncserver. TightVNC клиент обеспечивает настолько быструю передачу картинки, что создается ощущение что это не удаленное подключение, а программа запущенная на компьютере.

Дополним Dockerfile:

FROM centos:7

RUN yum install -y epel-release dnf 
        && 
        dnf install -y 
            tigervnc-server 
        && 
        yum clean all && dnf clean all 
        && 
        rm -rf /var/cache/yum/* && rm -rf /var/cache/dnf/*

После установки программ очищаем кеш для облегчения веса образа.

Рабочий стол

Я очень люблю KDE с темой Breeze, но KDE очень прожорливый рабочий стол. Gnome и его производные оказались еще более прожорливыми. Xfce, Ice слишком уж не красивые. К счастью решение есть — рабочий стол LXQT с темой Kde-Plasma.

Доустанавливаем рабочий стол:

FROM centos:7

RUN yum install -y epel-release dnf 
        && 
        dnf install -y 
            tigervnc-server 
            openbox obconf-qt 
            lxqt-about lxqt-common lxqt-config lxqt-globalkeys lxqt-notificationd 
            lxqt-openssh-askpass lxqt-panel lxqt-policykit lxqt-qtplugin lxqt-runner 
            lxqt-session pcmanfm-qt 
            dejavu-sans-mono-fonts 
            xterm nano htop expect sudo 
        && 
        yum clean all && dnf clean all 
        && 
        rm -rf /var/cache/yum/* && rm -rf /var/cache/dnf/*

Еще чуть чуть и можно запускать.

Создание пользователя

В контейнере необходимо работать от какого то пользователя. Для этого его надо создать и задать пароль, а так же задать пароль пользователю root:

... Dockerfile

ENV HOME=/home/headless

RUN /bin/dbus-uuidgen --ensure && 
        useradd headless && 
        echo "centos" | passwd --stdin root && 
        echo "centos" | passwd --stdin headless

Здесь headless это пользователь которого мы создаем и от которого будем работать, «centos» это пароль заданный пользователю и руту. Его лучше передавать из внешних параметров при запуске контейнера, но даже в таком виде контейнер не будет уязвим, т.к. соединение будет запаролено в VNC через пароль в аргументах.

Настройка запуска vnc сервера

Для запуска понадобиться вспомогательный скрипт который настроит наш VNC Server:

#!/usr/bin/expec

spawn /usr/bin/vncserver :1 -fg -geometry 1820x960
expect "Password:"
send "$env(password)r"
expect "Verify:"
send "$env(password)r"
expect "Would you like to enter a view-only password (y/n)?"
send "nr"

set timeout -1
expect eof

Его необходимо положить рядом с Dockefile, позже он будет включен в контейнер и с него будет начинаться запуск программы. В этом файле обязательно необходимо указать разрешение в котором вы планируете работать, например у меня задано 1820x960. Если указать меньше чем размер клиентского окна, то сервер может вылететь из-за нехватки памяти. Если указать больше, то картинку надо будет масштабировать и элементы рабочего стола станут слишком маленькими. Так же в этом скрипте будет задан пароль из переменных, которые будут переданы в параметрах запуска контейнера.

Осталось скопировать этот файл в контейнер и дописать параметры его запуска:

... Dockerfile

COPY ./startup.sh ${HOME}
RUN mkdir -p ${HOME}/.vnc 
        && 
        echo '#!/bin/sh' > ${HOME}/.vnc/xstartup && 
        echo 'exec startlxqt' >> ${HOME}/.vnc/xstartup && 
        chmod 775 ${HOME}/.vnc/xstartup 
        && 
        chown headless:headless -R ${HOME}


WORKDIR ${HOME}
USER headless
ENTRYPOINT ["expect", "./startup.sh"]

Вообщем то и все, можно запускать. Если запутались в составлении Dockerfile, то его полную версию можно найти у меня в репозитории, а готовый контейнер в docker hub.

Для запуска готового контейнера необходимо выполнить команду

docker run -it --rm -e password='YOUR_VNC_PASSWORD' -p5901:5901 labeg/centos-lxqt-vnc

И подключиться используя клиент TightVNC.
image

После подключения необходимо ввести пароль от пользователя заданный ранее. Так же рекомендуется сразу же его сменить для большей безопасности.
Для включения красивого оформления как в скриншоте выше необходимо зайти в Пуск > Preferences > Appearance > LXQt Theme и выбрать тему Kde-plasma.

Программы для работы

Теперь можно создать второй образ с рабочими программами. Для этого достаточно взять за основу образ созданный выше и дополнить его скриптами для установки пакетов:

FROM labeg/centos-lxqt-vnc:latest

USER root

# dotnet vscode monodevelop nodejs git2
RUN rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm 
        && 
        rpm --import https://packages.microsoft.com/keys/microsoft.asc && 
        sh -c 'echo -e "[code]nname=Visual Studio Codenbaseurl=https://packages.microsoft.com/yumrepos/vscodenenabled=1ngpgcheck=1ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/vscode.repo' 
        && 
        rpm --import "http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF" && 
        su -c 'curl https://download.mono-project.com/repo/centos7-vs.repo | tee /etc/yum.repos.d/mono-centos7-vs.repo' 
        && 
        yum install -y https://centos7.iuscommunity.org/ius-release.rpm 
        && 
        curl -sL https://rpm.nodesource.com/setup_13.x | bash - 
        && 
        dnf install -y geany git2u git2u-gui code monodevelop firefox dotnet-sdk-3.1 nodejs gnome-terminal gnome-system-monitor 
        && 
        npm install -g gulp typescript npm-check-updates 
        && 
        chown headless:headless -R ${HOME}

USER headless

RUN code --install-extension ms-vscode.vscode-typescript-tslint-plugin && 
    code --install-extension dbaeumer.vscode-eslint && 
    code --install-extension mrmlnc.vscode-scss && 
    code --install-extension visualstudioexptteam.vscodeintellicode && 
    code --install-extension ms-dotnettools.csharp && 
    code --install-extension joelday.docthis && 
    code --install-extension mrmlnc.vscode-remark && 
    code --install-extension eamodio.gitlens

В скрипте устанавливаются инструменты для Typescript и C# разработки под линуксом. Это NodeJS, VS Code с необходимым расширениями и Monodevelop (он же Visual Studio for Mac).

Запускается так же просто как и предыдущий образ

docker run -it --rm -e password='YOUR_VNC_PASSWORD' -p5901:5901 labeg/devpc

Теперь в считанные секунды можно разворачивать чистое рабочее окружение.
image

Репозитории и готовые образы

Если вам нужны готовые репозитории и образы или вы хотите улучшить имеющиеся, например через параметры запуска задать пароль пользователя, разрешения экрана, или сделать рестарт VNC сервера после его падения, то добро пожаловать в мои репозитории.
Базовый образ с рабочим столом Gihub Dockerhub
Образ с инструментами Typescript и C# Gihub Dockerhub

Автор: Евгений Лабутин

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js