Рабочая станция в Docker контейнере
Для чего? Мне постоянно приходят всякие идеи и некоторые из них сразу хочется попробовать, но рабочая станция не всегда под рукой, поэтому я настраивал IDE на всем что попадется под руку. В итоге устройства начали захламляться, а поддерживать и обновлять их стало тяжело. Что бы решить эту проблему я решил разместить такую «записную книжку» в облаке, и что бы ежедневно обновлялась и удаляла весь накопившийся мусор. А для работы подключаться к нему удаленно.
В итоге, сам того не подозревая, сделал очень удобный инструмент для решения большого количества задач: записная книжка, тестовая площадка, посмотреть то что телефон не показывает, безопасная песочница, запуск скриптов для программ работающие только GUI и мн. др. А в статье хочу поделиться методом создания таких контейнеров.
Для создания такого контейнера необходимо написать свой Dockerfile. А в статье опишу весь процесс его создания. Кто не хочет создавать сам, а хочет взять и попробовать, то внизу статьи будут ссылки на готовые образы.
Операционная система
Подойдет любой линукс. Лично я предпочитаю красивый OpenSuse, но сравнив его потребление памяти с CentOS решил выбрать последний. Ведь чем меньше памяти потребляет контейнер, тем больше можно сэкономить на его хостинге.
Начнем создавать Dockerfile:
FROM centos:7
Удаленный доступ
Для того что бы подключиться к контейнеру на нем необходимо настроить сервер удаленного доступа VNC. Для этого надо понимать два фактора:
- У системы нету монитора. Поэтому его придется эмулировать. Для этого существует специальный сервер x0vncserver.
- 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 "n\r"
set timeout -1
expect eof
Его необходимо положить рядом с Dockefile, позже он будет включен в контейнер и с него будет начинаться запуск программы. В этом файле обязательно необходимо указать разрешение в котором вы планируете работать, например у меня задано 1820×960. Если указать меньше чем размер клиентского окна, то сервер может вылететь из-за нехватки памяти. Если указать больше, то картинку надо будет масштабировать и элементы рабочего стола станут слишком маленькими. Так же в этом скрипте будет задан пароль из переменных, которые будут переданы в параметрах запуска контейнера.
Осталось скопировать этот файл в контейнер и дописать параметры его запуска:
... 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.
После подключения необходимо ввести пароль от пользователя заданный ранее. Так же рекомендуется сразу же его сменить для большей безопасности.
Для включения красивого оформления как в скриншоте выше необходимо зайти в Пуск > 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 Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=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
Теперь в считанные секунды можно разворачивать чистое рабочее окружение.
Репозитории и готовые образы
Если вам нужны готовые репозитории и образы или вы хотите улучшить имеющиеся, например через параметры запуска задать пароль пользователя, разрешения экрана, или сделать рестарт VNC сервера после его падения, то добро пожаловать в мои репозитории.
Базовый образ с рабочим столом GihubDockerhub
Образ с инструментами Typescript и C# Gihub Dockerhub