Един от недостатъците, които засягат екипите при разработването на софтуер, е споделянето на обща среда, която позволява на всеки в екипа да изгражда спрямо рамки и зависимости.
Едно от решенията на този проблем може да бъде използването на контейнери.
Контейнерите понякога се определят като леки виртуални машини.
Изпълнението на контейнер е подобно на стартирането на виртуална машина с единствената забележима разлика е, че за взаимодействие с него (регистриране, стартиране на команди, стартиране на приложения) обикновено се използва 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 е, че може да не можем да наблюдаваме промените.