воскресенье, 18 октября 2020 г.

Как запустить Linux GUI приложения из докер-контейнера



Признаюсь сразу,  мне было интересно попробовать это из "спортивного" интереса но я не вижу большого практического смысла в этом. В таком случае использование виртуальной машины считаю более целесообразным. В статье я расскажу про самый простой способ – запуск докер-контейнера из специально подготовленного докер-имиджа с Docker Hub. 

Если тексту с картинками вы предпочитаете видео, то вот мой обзор на YouTube.



Принцип работы с такими докер-контейнерами единый
  1. Запускаем подходящий докер-контейнер. В статье я опишу несколько из них.
  2. Подключаем приложение для удаленной работы с рабочим столом системы, работающей в контейнере. Это может быть VNC или  Remote Desktop. На Маке VNC клиент встроен в Finder, а Remote Desktop можно скачать из AppStore. На Windows ситуация обратная. В большинстве случаев приложение Remote Desktop входит в состав операционной системы, а VNC клиента можно скачать.
Рассмотрим работу с таким контейнером на примере одного из самых функциональных докер-имиджей - https://hub.docker.com/r/manishfoodtechs/xfcefulldesktop_ubuntu20.4

Данный имидж базируется на ubuntu 20.4 и имеет из коробки больше всего предустановленного софта – Firefox, LibreOffice и много других утилит. Автор докер-имиджа предлагает работать с контейнером через RDP. По тому команда для запуска контейнера будет иметь следующий вид. 

docker run -it -p 9096:3389 -e 3389 --shm-size 2g manishfoodtechs/xfcefulldesktop_ubuntu20.4

В этой команде «пробрасывается» порт для работы с контейнером через RDP – 3389. Поэтому, после старта контейнера нужно запустить сервер удаленного рабочего стола на основе протокола RDP

/etc/init.d/xrdp restart


Все. Теперь можно запускать Remote Desktop и подключаться к рабочему столу в контейнере. 
Я  приведу скриншоты с Remote Desktop на Маке. При подключении Remote Desktop пожалуется, что мне знает такого компьютера. Для продолжения нажмите кнопку Connect.
В качестве имени компьютера (PC Name) надо указать 127.0.0.1:9096, Username: root и Password: 123456

Не пугайтесь, иконки в системе стилизованы под Windows. Не знаю зачем, но даже иконка Firefox сделана как иконка Microsoft Edge, a иконки приложений LibreOffice стилизованы под Microsoft Office.

Можно в команду запуска докер-контейнера добавить ключ  -v $(pwd):/host  и тогда  можно  работать  с файлами из текущего директория их докер-контейнера. Полностью команда для запуска докер-контейнера будет выглядеть так

docker run -it -p 9096:3389 -e 3389 -v $(pwd):/host --shm-size 2g manishfoodtechs/xfcefulldesktop_ubuntu20.4

Если по каким-то причинам вы не хотите работать через RDP, то можно настроить контейнер для работы через VNC. В простейшем варианте, чтобы не делать свой докер-имидж это может выглядеть так.

Запускаем контейнер с открытием дефолтного порта для VNC – 5901 (вместо 3389)

docker run -it -p 5901:5901 -v $(pwd):/host --shm-size 2g manishfoodtechs/xfcefulldesktop_ubuntu20.4

Далее, после старта контейнера в контейнере через терминал устанавливаем VNC server

sudo apt install tightvncserver
 
и запускаем VNC server

sudo vncserver

VNC server при запуске попросит создать и подтвердить пароль для удаленного доступа к рабочему столу. На вопрос  "Would you like to enter a view-only password (y/n)?". Отвечаем “n”.

Все приготовления сделаны. Теперь можно подключать VNC клиента. На Маке VNC клиент встроен в Finder (Go->Connect to Server). В качестве стоки подключения нужно указать vnc://127.0.0.1:5901
В окне ввода пароля указываем тот пароль, который придумали на этапе запуска vncserver.
Если вам понравилась эта тема, то на Docker Hub есть и другие имиджи на Linux c GUI которые стоит попробовать. Могу посоветовать 
  1. https://hub.docker.com/r/dorowu/ubuntu-desktop-lxde-vnc - есть разные версии Ubuntu. 20, 18, 16, 14. Что весьма удобно, с десктопом можно как через VNC клиента, так и есть веб-интерфейс, т.е. можно работать из браузера.
  2. https://hub.docker.com/r/queeno/ubuntu-desktop/ - «голая» Ubunut 16.04. Работа через VNC
  3. https://hub.docker.com/r/cyverse/ubuntu18-xfce-desktop - «голая» Ubunut 18.04. Работать с контейнером можно  как при помощи веб-интерфейса, так и через VNC  клиента.

среда, 7 октября 2020 г.

Отладка сборки докер-имиджа

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

Если тексту с картинками вы предпочитаете видео, то вот мой обзор отладки докер-имижа на YouTube

Как известно, сборка докер-имиджа разбита на этапы и каждый такой этап выполняется в отдельном докер-контейнере, который потом формирует промежуточный докер-имидж. Самый первый контейнер  формируется из команды FROM в Dockerfile. Вот скриншот сборки для моего довольно простого докер-файла и в нем команда docker image build создала семь промежуточных докер-имиджей, а восьмой - стал финальным.


Промежуточные докер-имиджи не удаляются, а сохраняются. Их можно посмотреть командой 

docker image ls -a

Теперь переходим к самому интересному. Если сборка докер-имиджа идет не так как вы ожидали или вы не понимаете, почему докер-имидж получился таким каким получился, то можно  запустить контейнер на основе промежуточного имиджа, запустить на  нем терминал и проверить его содержимое и состояние. Сделать  это можно вот такой командой

 docker run --rm -it 09db5a1c9e94 sh

здесь

  • 09db5a1c9e94 - это ID докер-имиджа который я хочу проверить. 
  • флаг  --rm создаст временный докер-контейнер, который будет автоматически удален при выходе из  него.
  • флаг -it переведет контейнер в интерактивный режим.





























Кстати, чтобы удалить все эти промежуточные докер-имиджи можно воспользоваться командой 

docker image purne

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

Удачной и легкой вам отладки!


пятница, 2 октября 2020 г.

Отладка Node.js приложения в докер-контейнере

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

Весть процесс, с большего, состоит из 3-х шагов.

  1. Надо изменить запуск Node.js, чтобы он работал с включенным режимом отладки.
  2. Открыть доступ к порту, указанному при включении режима отладки в Node.js.
  3. Настроить инструмент для отладки. Это может быть любая IDE. Многие разработчики пользуются VS Code, я им тоже пользуюсь, на его примере я и покажу в этой статье как это сделать.
Если тексту с картинками вы предпочитаете видео, то вот мой обзор отладки Node.js приложения в докер-контейнере на YouTube

 

Я этого примера создал простое Node.js приложение и докер-файл для него. Полный пример Node.js приложения и Dockerfile к нему можно посмотреть в репозитории на GitHub.

const express = require("express");
const app = new express();

app.get("/", function(req, res){
res.send("Hello, World!");
});

const PORT = 8080;
app.listen(PORT, function(){
console.log("Listening on port " + PORT);
});

app.js

FROM node:14-alpine

WORKDIR /node-app

COPY package.json .
RUN npm install
RUN mv /node-app/node_modules /node_modules

COPY . .

CMD [ "node", "app.js" ]

EXPOSE 8080

Dockerfile

Шаг 1. Запускаем NodeJS в режиме отладки

Первое что надо сделать - это запустить Node.js в докер-контейнере в режиме отладки. Делается это передачей ключа --inspect при старте Node (вот здесь можно почитать подробнее). В Dockerfile у нас уже есть инструкция по запуску Node и переопределить настройки запуска Nods в контейнере можно разными способами - например, параметрами команды docker container run или можно создать файл для docker-compose и там переопределить ряд параметров. Вариант с docker-compose мне кажется более удобным.

version: '3.4'

services:
nodeapp:
build: .
ports:
- 8080:8080
command: node --inspect=0.0.0.0:9229 app.js
docker-compose.yml (not finished)


Шаг 2. Открываем доступ к порту

Теперь, дополнительно к порту на котором работает приложение нам надо открыть доступ к порту через который работает инспектор. Для этого обновляем docker-compose файл, чтобы открыть доступ к порту 9229, который мы указали в параметрах инспектора.

Зачастую так же удобно переопределить и путь к коду Node.js приложения, чтобы можно было внести изменения в код и убедиться, что приложение работает так как ожидается. Финальная версия docker-compose файла так же находится в репозитории на GitHub.

version: '3.4'

services:
nodeapp:
build: .
ports:
- 8080:8080
- 9229:9229
volumes:
- .:/node-app
command: node --inspect=0.0.0.0:9229 app.js

docker-compose.yml (final)

Запускаем docker-compose с флагом  --build :
docker-compose up --build

Шаг 3. Настраиваем VS Code и запускаем отладку

Теперь подключаем VS Code. Для этого надо добавить конфигурацию отладки в VS Code.
Для  начала надо перейти на панель отладки в VS Code
Далее, если launch.json есть, то надо добавить новую конфигурацию, 
Если launch.json еще не был создан, то его надо создать, кликнув на линку "create a launch.json file"

В появившемся списке шаблонов конфигураций можно выбрать "Node.js: Attach to Remote Program" а если такой нет, то любую и заменить ее на мой пример (файл на GitHub).

{
"address": "127.0.0.1",
"localRoot": "${workspaceFolder}",
"name": "Attach to Remote",
"port": 9229,
"remoteRoot": "/node-app",
"request": "attach",
"skipFiles": [
"<node_internals>/**"
],
"type": "pwa-node"
}


На что здесь важно  обратить внимание
  • address - IP-адрес машины где запущен докер-контейнер. 
  • port - порт через который работает Node Inspector. Он должен быть такой же как мы указывали в ключе --inspect.
  • remoteRoot - путь в докер-контейнере, где находится код приложения.
Теперь можно запускать отладчик. Для этого нужно нажать кнопку "Start Debugging". 


В коде приложения можно ставить точки останова (breakpoints), проверять значения переменных и  полей объектов и пр.

Что можно сделать еще

Если пойти дальше и модифицировать немного Dockerfile можно с эпизодической отладки приложения перейти на полноценную разработку в Docker-контейнере. Это может быть удобно в случае когда надо разрабатывать и поддерживать приложения на разных версиях Node.js. Для этого нужно установить в docker-контейнер forever или любое другое приложение, которое  будет перезапускать Node при изменении кода и соответственно у нас немного изменится команда для запуска приложения. Новый докер-файл (я его назвал Dockerfile.dev) и docker-compose.dev.yml будут выглядеть так. 

FROM node:14-alpine

WORKDIR /node-app

RUN npm install -g forever

COPY package.json .
RUN npm install
RUN mv /node-app/node_modules /node_modules

COPY . .

CMD [ "forever", "-w", "app.js" ]

EXPOSE 8080

Dockerfile.dev


version: '3.4'

services:
nodeapp:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- 8080:8080
- 9229:9229
volumes:
- .:/node-app
command: forever -w -c "node --inspect=0.0.0.0:9229" app.js

docker-compose.dev.yml

Поскольку у нового docker-compose файла имя отличное от дефолтного, то запускать его надо с немного другой командой

docker-compose -f docker-compose.dev.yml up --build