Един от недостатъците, които засягат екипите при разработването на софтуер, е споделянето на обща среда, която позволява на всеки в екипа да изгражда спрямо рамки и зависимости.

Едно от решенията на този проблем може да бъде използването на контейнери.

Контейнерите понякога се определят като леки виртуални машини.

Изпълнението на контейнер е подобно на стартирането на виртуална машина с единствената забележима разлика е, че за взаимодействие с него (регистриране, стартиране на команди, стартиране на приложения) обикновено се използва Docker CLI.

Подобно на виртуалните машини, контейнерите имат изображения, които могат да бъдат създадени и стартирани.

Съдържа абстрактни оперативни системи, а не хардуер.

Контейнерите са решение на проблема как софтуерът да работи надеждно, когато се премества от една компютърна среда в друга. Това може да бъде от лаптоп на програмист до тестова среда, от среда за етапи в производство и може би от физическа машина в център за данни до виртуална машина в частен или публичен облак.



В тази публикация ще докеризирам приложение на React.

Докер

Първата стъпка ще бъде изтеглянето и инсталирането на Docker Desktop.



Docker е проектиран като клиент/сървър решение. Предоставя се CLI от страна на клиента, който позволява взаимодействие с демон, работещ на вашия компютър.

Можете да изберете операционната система, която искате вашите контейнери да изпълняват, Windows и Linux контейнери са налични към днешна дата.

Ще използвам контейнери на Windows в тази статия.

Докеризираното приложение се състои от своя изходен код и Dockerfile. Dockerfile позволява да взаимодействате с Docker и да инструктирате как да създадете и стартирате контейнер и изображението в него.

В Dockerfile, в най-простата му форма, човек обикновено би:

  • Изберете изображение за контейнера от регистър или от публично достъпните в Docker Hub. Например в тази публикация ще се използва следното изображение:


  • Конфигурирайте средата според това, което трябва да направи дадено приложение (например отваряне на портове).
  • Стартирайте вашите изпълними файлове вътре в контейнера. В тази стъпка човек може да посочи команда за стартиране на двигателя.

За справка това би бил типичен Dockerfile:

FROM mcr.microsoft.com/dotnet/core/runtime:3.1-nanoserver-1909
WORKDIR /app
ENTRYPOINT ["dotnet", "website.dll"]

ОТ

Инструкцията FROM инициализира нов етап на изграждане и задава Базово изображение за последващи инструкции. Като такъв, валиден Dockerfile трябва да започва с инструкция FROM. Изображението може да бъде всяко валидно изображение – особено лесно е да започнете, като изтеглите изображение от Публични хранилища.



WORKDIR

Инструкцията WORKDIR задава работната директория за всички инструкции RUN, CMD, ENTRYPOINT, COPY и ADD, които я следват в Dockerfile.



ВХОДНА ТОЧКА

ENTRYPOINT ви позволява да конфигурирате контейнер, който ще работи като изпълним файл.



Накратко, ENTRYPOINT [“dotnet”, “website.dll”]би било подобно на стартиране на вашия контейнер с помощта на конфигурираното изображение, влезте в него и въведете „dotnet website.dll”.

Dockerise a React Frontend

За да създам тривиално уеб приложение с помощта на React, последвах този хубав урок за започване на работа от няколко части:



Взех и работния код от официалното начало:



Опростих малко конфигурацията на webpack, която се предлага:

Накратко, премахнах предложената папка за изход и запазих папката dist, която се използва по подразбиране.

Също така, от webpack 4 вече няма нужда да задавате входна точка, доколкото е в /src/index.js.

Също така промених index.js, за да използвам JSX, синтаксисното разширение на JavaScript.

В класически сценарий, нов разработчик, работещ върху този код, ще трябва да инсталира възел на своята машина. Те също ще трябва да инсталират всички възлови модули.

Тези стъпки могат да бъдат автоматизирани с помощта на „Dockerfile“, това е този, който използвах:

FROM node:latest
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 80
ENTRYPOINT npx webpack-dev-server --host 0.0.0.0 --port 80

Трябваше изрично да помоля на webpack-dev-server да слуша на IP 0.0.0.0, тъй като иначе получавах грешка EMPTY_RESPONSE. Контейнерът автоматично пренасочва повикванията, идващи отвън към 0.0.0.0 IP, докато webpack-dev-сървърът е конфигуриран да се свързва с localhost, 127.0.0.1.



За да създадете изображение, командата, която трябва да бъде предадена на Docker CLI, е:

docker build . -t frontend

Новоизграденото изображение вече ще се вижда работещо:

docker images
REPOSITORY     TAG       IMAGE ID            CREATED        SIZE
frontend       latest    52159d9a7188        5 days ago     1.05GB
node           latest    07e774543bdf        2 weeks ago    939MB

Две изображения са налични локално, едното съдържа инсталацията на Node.js, а другото е създадено, започвайки от това с нашия изходен код в папката „/usr/src/app“.

Следващото време е да стартирате контейнера, следната команда ще направи това:

docker run -p 49160:80 -d frontend

Работи:

docker ps

Ще покаже информация за работещия контейнер.

Началото на React също ще може да се разглежда.

Работи на HTTPS

Изпълнението на HTTPS при разработка ще изисква SSL сертификат да бъде надежден и монтиран в обем вътре в контейнера.

Dockerfile ще трябва да се промени, тъй като „webpack-dev-server“ ще трябва да бъде конфигуриран да използва новосъздадения сертификат.

FROM node:latest
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 80
ENTRYPOINT npx webpack-dev-server --host 0.0.0.0 --https --port 443 --pfx=/etc/ssl/certs/backend.pfx --pfx-passphrase=**yourpassword**

Промените, които направих, където:

  • Портът вече е 443
  • Препращаме към сертификат, наречен „backend.pfx“
  • Предаваме парола за достъп до него

След като модифицираме Dockerfile, ще трябва да възстановим изображението:

docker build . -t frontend

Един от начините за генериране и доверие на самоподписан сертификат може да бъде използването на OpenSSL. Днес обаче ще използвам инструмента „dotnet dev-certs“.

Стъпките за създаване и доверие на самоподписан сертификат са описани тук:



След като .pfx файлът бъде експортиран в папката „$Env:USERPROFILE\.aspnet\https“, той може да бъде монтиран като том чрез предаване на следната опция към командата „docker run“:

  • -v $Env:USERPROFILE\.aspnet\https:/etc/ssl/certs/ frontend:последен

Крайната команда ще бъде:

docker run --rm -it -p 443:443 -v $Env:USERPROFILE\.aspnet\https:/etc/ssl/certs/ frontend:latest

Ръчно компилиране на JSX

Ако сте любопитни да видите какво прави Бабел под дървото, вижте този страхотен отговор:



Инсталирах Babel CLI:

npm install babel-cli --save-dev

След това преобразувах JSX файла ръчно:

npx babel --plugins transform-react-jsx .\src\index.js

Това беше резултатът:

Резюме

Преминаването към контейнери в разработка позволява на приложението да работи изолирано от избраната от тях операционна система.

Едно голямо ограничение на разработването на приложение от предния край с помощта на Docker е, че може да не можем да наблюдаваме промените.