Krijimi i një zinxhiri CI/CD dhe automatizimi i punës me Docker

Unë shkrova faqet e mia të internetit të para në fund të viteve '90. Në atë kohë ishte shumë e lehtë për t'i vënë ato në gjendje pune. Kishte një server Apache në një host të përbashkët, ju mund të hyni në këtë server nëpërmjet FTP duke shkruar diçka si ftp://ftp.example.com. Pastaj ju duhej të shkruani emrin dhe fjalëkalimin tuaj dhe të ngarkoni skedarët në server. Kishte kohë të ndryshme, gjithçka ishte më e thjeshtë atëherë se tani.

Krijimi i një zinxhiri CI/CD dhe automatizimi i punës me Docker

Në dy dekada që nga ajo kohë, gjithçka ka ndryshuar shumë. Faqet e internetit janë bërë më komplekse; ato duhet të montohen përpara se të lëshohen në prodhim. Një server i vetëm u bë shumë serverë që funksiononin pas balancuesve të ngarkesës dhe përdorimi i sistemeve të kontrollit të versioneve u bë i zakonshëm.

Për projektin tim personal kam pasur një konfigurim të veçantë. Dhe e dija që më duhej aftësia për të vendosur sitin në prodhim duke kryer vetëm një veprim: duke shkruar kodin në një degë master në GitHub. Përveç kësaj, e dija se për të siguruar funksionimin e aplikacionit tim të vogël në internet, nuk doja të menaxhoja një grup të madh Kubernetes, ose të përdorja teknologjinë Docker Swarm, ose të mbaja një flotë serverësh me pods, agjentë dhe të gjitha llojet e tjera. kompleksitetet. Për të arritur qëllimin për ta bërë punën sa më të lehtë, më duhej të njihesha me CI/CD.

Nëse keni një projekt të vogël (në këtë rast, një projekt Node.js) dhe dëshironi të dini se si të automatizoni vendosjen e këtij projekti, duke siguruar që ajo që ruhet në depo të përputhet saktësisht me atë që funksionon në prodhim, atëherë unë mendoni se mund të jeni të interesuar për këtë artikull.

Parakushtet

Lexuesi i këtij artikulli pritet të ketë një kuptim bazë të linjës së komandës dhe shkrimit të skripteve Bash. Përveç kësaj, ai do të ketë nevojë për llogari Travis C.I. и Qendër dokeri.

qëllimet

Nuk do të them që ky artikull mund të quhet pa kushte "tutorial". Ky është më shumë një dokument në të cilin unë flas për atë që kam mësuar dhe përshkruaj procesin që më përshtatet për testimin dhe vendosjen e kodit në prodhim, të kryer në një kalim të automatizuar.

Kjo është ajo që përfundoi në rrjedhën time të punës.

Për kodin e postuar në çdo degë depo përveç master, kryhen veprimet e mëposhtme:

  • Fillon projekti i ndërtuar mbi Travis CI.
  • Kryhen të gjitha testet e njësisë, integrimit dhe nga fundi në fund.

Vetëm për kodin që hyn në master, kryhet si më poshtë:

  • Gjithçka e përmendur më sipër, plus...
  • Ndërtimi i një imazhi Docker bazuar në kodin, cilësimet dhe mjedisin aktual.
  • Vendosja e imazhit në Docker Hub.
  • Lidhja me serverin e prodhimit.
  • Ngarkimi i një imazhi nga Docker Hub në server.
  • Ndalimi i kontejnerit aktual dhe fillimi i një të reje bazuar në imazhin e ri.

Nëse nuk dini asgjë për Docker, imazhet dhe kontejnerët, mos u shqetësoni. Unë do t'ju tregoj gjithçka për të.

Çfarë është CI/CD?

Shkurtesa CI/CD qëndron për "integrim të vazhdueshëm / vendosje të vazhdueshme".

▍Integrimi i vazhdueshëm

Integrimi i vazhdueshëm është një proces në të cilin zhvilluesit angazhohen për depon kryesore të kodit burimor të projektit (zakonisht një degë master). Në të njëjtën kohë, cilësia e kodit sigurohet përmes testimit të automatizuar.

▍Shpërndarja e vazhdueshme

Vendosja e vazhdueshme është vendosja e shpeshtë dhe e automatizuar e kodit në prodhim. Pjesa e dytë e akronimit CI/CD nganjëherë shkruhet si "dorëzimi i vazhdueshëm". Kjo në thelb është e njëjtë me "vendosjen e vazhdueshme", por "dorëzimi i vazhdueshëm" nënkupton nevojën për të konfirmuar manualisht ndryshimet përpara fillimit të procesit të vendosjes së projektit.

Si T'ia Fillohet

Aplikacioni që kam përdorur për të mësuar të gjitha këto quhet Marrë shënim. Ky është një projekt në internet për të cilin jam duke punuar, i krijuar për të mbajtur shënime. Në fillim u përpoqa të bëja JAMStack-projekt, ose thjesht një aplikacion i përparmë pa server, për të përfituar nga aftësitë standarde të pritjes dhe vendosjes së projektit që ofron Netlify. Ndërsa kompleksiteti i aplikacionit rritej, më duhej të krijoja pjesën e tij të serverit, që do të thoshte se do të më duhej të formuloja strategjinë time për integrimin e automatizuar dhe vendosjen e automatizuar të projektit.

Në rastin tim, aplikacioni është një server Express që funksionon në mjedisin Node.js, që shërben një aplikacion React me një faqe dhe mbështet një API të sigurt nga ana e serverit. Kjo arkitekturë ndjek strategjinë që mund të gjendet në dhënë Udhëzues për vërtetimin e stivës së plotë.

u konsultova me shoku, i cili është një ekspert automatizimi, dhe e pyeti atë se çfarë duhej të bëja për t'i bërë të gjitha të funksiononin ashtu siç doja. Ai më dha idenë se si duhet të duket një rrjedhë e automatizuar e punës, e përshkruar në seksionin e Objektivave të këtij artikulli. Të kesh këto qëllime do të thoshte që më duhej të kuptoja se si të përdorja Docker.

prerës

Docker është një mjet që, falë teknologjisë së kontejnerizimit, lejon që aplikacionet të shpërndahen, vendosen dhe ekzekutohen lehtësisht në të njëjtin mjedis, edhe nëse vetë platforma Docker funksionon në mjedise të ndryshme. Së pari, më duhej të merrja në dorë veglat e linjës së komandës Docker (CLI). udhëzim Udhëzuesi i instalimit të Docker nuk mund të quhet shumë i qartë dhe i kuptueshëm, por prej tij mund të mësoni se për të ndërmarrë hapin e parë të instalimit, duhet të shkarkoni Docker Desktop (për Mac ose Windows).

Docker Hub është përafërsisht e njëjta gjë si GitHub për magazinat git, ose regjistrin NPM për paketat JavaScript. Ky është një depo në internet për imazhet e Docker. Kjo është ajo me të cilën lidhet Docker Desktop.

Pra, për të filluar me Docker, duhet të bëni dy gjëra:

Pas kësaj, mund të kontrolloni nëse Docker CLI po funksionon duke ekzekutuar komandën e mëposhtme për të kontrolluar versionin Docker:

docker -v

Më pas, hyni në Docker Hub duke futur emrin e përdoruesit dhe fjalëkalimin tuaj kur ju kërkohet:

docker login

Për të përdorur Docker, duhet të kuptoni konceptet e imazheve dhe kontejnerëve.

▍Imazhet

Një imazh është diçka si një projekt që përmban udhëzime për montimin e kontejnerit. Kjo është një fotografi e pandryshueshme e sistemit të skedarëve dhe cilësimeve të aplikacionit. Zhvilluesit mund të ndajnë lehtësisht imazhe.

# Вывод сведений обо всех образах
docker images

Kjo komandë do të nxjerrë një tabelë me kokën e mëposhtme:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

Më tej do të shikojmë disa shembuj të komandave në të njëjtin format - së pari ka një komandë me një koment, dhe më pas një shembull se çfarë mund të nxjerrë.

▍Kontejnerët

Një kontejner është një paketë e ekzekutueshme që përmban gjithçka që nevojitet për të ekzekutuar një aplikacion. Një aplikacion me këtë qasje do të funksionojë gjithmonë njësoj, pavarësisht nga infrastruktura: në një mjedis të izoluar dhe në të njëjtin mjedis. Çështja është se shembujt e të njëjtit imazh lëshohen në mjedise të ndryshme.

# Перечисление всех контейнеров
docker ps -a
CONTAINER ID     IMAGE     COMMAND     CREATED     STATUS     PORTS     NAMES
---

▍Etiketat

Një etiketë është një tregues i një versioni specifik të një imazhi.

▍Një referencë e shpejtë për komandat e Docker

Këtu është një përmbledhje e disa komandave të përdorura zakonisht të Docker.

Ekip

Kontekst

efekt

ndërtim doker

imazh

Ndërtimi i një imazhi nga një Dockerfile

etiketë docker

imazh

Etiketimi i imazhit

imazhe docker

imazh

Listimi i imazheve

drejtues dokeri

Enë

Drejtimi i një kontejneri bazuar në një imazh

shtytje docker

imazh

Ngarkimi i një imazhi në regjistër

doker tërheq

imazh

Duke ngarkuar një imazh nga regjistri

doket ps

Enë

Listimi i kontejnerëve

Docker system prune

Imazhi/Konteineri

Heqja e kontejnerëve dhe imazheve të papërdorura

▍Dockerfile

Unë e di se si të ekzekutoj një aplikacion prodhimi në nivel lokal. Unë kam një konfigurim Webpack të krijuar për të ndërtuar një aplikacion të gatshëm React. Më pas, kam një komandë që nis një server të bazuar në Node.js në port 5000. Duket kështu:

npm i         # установка зависимостей
npm run build # сборка React-приложения
npm run start # запуск Node-сервера

Duhet të theksohet se nuk kam një aplikim shembull për këtë material. Por këtu, për eksperimente, çdo aplikacion i thjeshtë Node do të bëjë.

Për të përdorur kontejnerin, do t'ju duhet t'i jepni udhëzime Docker. Kjo bëhet përmes një skedari të quajtur Dockerfile, e vendosur në direktorinë rrënjë të projektit. Ky skedar, në fillim, duket mjaft i pakuptueshëm.

Por ajo që përmban vetëm përshkruan, me komanda të veçanta, diçka të ngjashme me ngritjen e një mjedisi pune. Këtu janë disa nga këto komanda:

  • NGA — Kjo komandë nis një skedar. Ai specifikon imazhin bazë mbi të cilin është ndërtuar kontejneri.
  • COPY — Kopjimi i skedarëve nga një burim lokal në një kontejner.
  • DIREKTOR PUNE — Vendosja e drejtorisë së punës për komandat e mëposhtme.
  • RUN - Ekzekutoni komandat.
  • EKSPOZON — Cilësimet e portit.
  • PIKA E HYRJES - Tregimi i komandës që do të ekzekutohet.

Dockerfile mund të duket diçka si kjo:

# Загрузить базовый образ
FROM node:12-alpine

# Скопировать файлы из текущей директории в директорию app/
COPY . app/

# Использовать app/ в роли рабочей директории
WORKDIR app/

# Установить зависимости (команда npm ci похожа npm i, но используется для автоматизированных сборок)
RUN npm ci --only-production

# Собрать клиентское React-приложение для продакшна
RUN npm run build

# Прослушивать указанный порт
EXPOSE 5000

# Запустить Node-сервер
ENTRYPOINT npm run start

Në varësi të imazhit bazë që zgjidhni, mund t'ju duhet të instaloni varësi shtesë. Fakti është se disa imazhe bazë (si Node Alpine Linux) janë krijuar me qëllimin për t'i bërë ato sa më kompakte. Si rezultat, ata mund të mos kenë disa nga programet që prisni.

▍Ndërtimi, etiketimi dhe drejtimi i kontejnerit

Montimi lokal dhe nisja e kontejnerit është pasi kemi Dockerfile, detyrat janë mjaft të thjeshta. Përpara se ta shtyni imazhin në Docker Hub, duhet ta testoni atë në nivel lokal.

▍ Asambleja

Së pari ju duhet të mbledhni imazh, duke specifikuar një emër dhe, sipas dëshirës, ​​një etiketë (nëse një etiketë nuk është specifikuar, sistemi automatikisht do t'i caktojë një etiketë imazhit latest).

# Сборка образа
docker build -t <image>:<tag> .

Pas ekzekutimit të kësaj komande, mund të shikoni Docker-in të ndërtojë imazhin.

Sending build context to Docker daemon   2.88MB
Step 1/9 : FROM node:12-alpine
 ---> ...выполнение этапов сборки...
Successfully built 123456789123
Successfully tagged <image>:<tag>

Ndërtimi mund të zgjasë disa minuta - gjithçka varet nga sa varësi keni. Pasi të përfundojë ndërtimi, mund të ekzekutoni komandën docker images dhe shikoni përshkrimin e imazhit tuaj të ri.

REPOSITORY          TAG               IMAGE ID            CREATED              SIZE
<image>             latest            123456789123        About a minute ago   x.xxGB

▍Nisja

Imazhi është krijuar. Kjo do të thotë që ju mund të përdorni një enë bazuar në të. Sepse dua të jem në gjendje të aksesoj aplikacionin që funksionon në kontejnerin në localhost:5000, unë, në anën e majtë të çiftit 5000:5000 në komandën tjetër të instaluar 5000. Në anën e djathtë është porta e kontejnerit.

# Запуск с использованием локального порта 5000 и порта контейнера 5000
docker run -p 5000:5000 <image>:<tag>

Tani që kontejneri është krijuar dhe funksionon, mund të përdorni komandën docker ps për të parë informacionin rreth këtij kontejneri (ose mund të përdorni komandën docker ps -a, i cili shfaq informacion për të gjithë kontejnerët, jo vetëm për ato që funksionojnë).

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS                    NAMES
987654321234        <image>             "/bin/sh -c 'npm run…"   6 seconds ago        Up 6 seconds                0.0.0.0:5000->5000/tcp   stoic_darwin

Nëse tani shkoni në adresën localhost:5000 — ju mund të shihni një faqe të një aplikacioni të ekzekutuar që duket saktësisht e njëjtë me faqen e një aplikacioni që ekzekutohet në një mjedis prodhimi.

▍Etiketimi dhe publikimi

Për të përdorur një nga imazhet e krijuara në serverin e prodhimit, duhet të jemi në gjendje ta shkarkojmë këtë imazh nga Docker Hub. Kjo do të thotë që së pari duhet të krijoni një depo për projektin në Docker Hub. Pas kësaj, ne do të kemi një vend ku mund të dërgojmë imazhin. Imazhi duhet të riemërtohet në mënyrë që emri i tij të fillojë me emrin e përdoruesit tonë Docker Hub. Kjo duhet të pasohet nga emri i depove. Çdo etiketë mund të vendoset në fund të emrit. Më poshtë është një shembull i emërtimit të imazheve duke përdorur këtë skemë.

Tani mund të ndërtoni imazhin me një emër të ri dhe të ekzekutoni komandën docker push për ta shtyrë atë te depoja e Docker Hub.

docker build -t <username>/<repository>:<tag> .
docker tag <username>/<repository>:<tag> <username>/<repository>:latest
docker push <username>/<repository>:<tag>

# На практике это может выглядеть, например, так:
docker build -t user/app:v1.0.0 .
docker tag user/app:v1.0.0 user/app:latest
docker push user/app:v1.0.0

Nëse gjithçka shkon mirë, imazhi do të jetë i disponueshëm në Docker Hub dhe mund të ngarkohet lehtësisht në server ose të transferohet te zhvilluesit e tjerë.

Hapat e ardhshëm

Deri tani ne kemi verifikuar që aplikacioni, në formën e një kontejneri Docker, po funksionon në nivel lokal. Ne e kemi ngarkuar kontejnerin në Docker Hub. E gjithë kjo do të thotë se tashmë kemi bërë përparim shumë të mirë drejt qëllimit tonë. Tani duhet të zgjidhim dy pyetje të tjera:

  • Vendosja e një mjeti CI për testimin dhe vendosjen e kodit.
  • Vendosja e serverit të prodhimit në mënyrë që ai të shkarkojë dhe ekzekutojë kodin tonë.

Në rastin tonë, ne përdorim Travis C.I.. Si server - DitigalOcean.

Duhet të theksohet se këtu mund të përdorni një kombinim tjetër shërbimesh. Për shembull, në vend të Travis CI, mund të përdorni CircleCI ose Github Actions. Dhe në vend të DigitalOcean - AWS ose Linode.

Ne vendosëm të punojmë me Travis CI, dhe unë tashmë kam diçka të konfiguruar në këtë shërbim. Prandaj, tani do të flas shkurtimisht se si ta përgatisim atë për punë.

Travis C.I.

Travis CI është një mjet për testimin dhe vendosjen e kodit. Nuk do të doja të hyja në ndërlikimet e ngritjes së Travis CI, pasi secili projekt është unik dhe kjo nuk do të sjellë shumë përfitime. Por unë do të mbuloj bazat për t'ju filluar nëse vendosni të përdorni Travis CI. Pavarësisht nëse zgjidhni Travis CI, CircleCI, Jenkins ose diçka tjetër, metoda të ngjashme konfigurimi do të përdoren kudo.

Për të filluar me Travis CI, shkoni te faqe projekta dhe krijoni një llogari. Pastaj integroni Travis CI me llogarinë tuaj GitHub. Kur konfiguroni sistemin, do t'ju duhet të specifikoni depon me të cilën dëshironi të automatizoni punën dhe të mundësoni hyrjen në të. (Unë përdor GitHub, por jam i sigurt se Travis CI mund të integrohet me BitBucket, dhe GitLab dhe shërbime të tjera të ngjashme).

Sa herë që fillon Travis CI, serveri hapet, duke ekzekutuar komandat e specifikuara në skedarin e konfigurimit, duke përfshirë vendosjen e degëve përkatëse të depove.

▍ Cikli jetësor i punës

Thirret skedari i konfigurimit të Travis CI .travis.yml dhe ruhet në direktoriumin rrënjë të projektit, mbështet konceptin e ngjarjeve cikli i jetes detyrat. Këto ngjarje janë renditur sipas radhës në të cilën ndodhin:

  • apt addons
  • cache components
  • before_install
  • install
  • before_script
  • script
  • before_cache
  • after_success или after_failure
  • before_deploy
  • deploy
  • after_deploy
  • after_script

▍Testimi

Në skedarin e konfigurimit do të konfiguroj serverin lokal Travis CI. Zgjodha Node 12 si gjuhë dhe i thashë sistemit të instalonte varësitë e nevojshme për të përdorur Docker.

Gjithçka që është e shënuar në .travis.yml, do të ekzekutohet kur të gjitha kërkesat për tërheqje bëhen në të gjitha degët e depove, përveç nëse specifikohet ndryshe. Ky është një veçori e dobishme sepse do të thotë që ne mund të testojmë të gjithë kodin që vjen në depo. Kjo ju lejon të dini nëse kodi është gati për t'u shkruar në degë. master, dhe nëse do të prishë procesin e ndërtimit të projektit. Në këtë konfigurim global, unë instaloj gjithçka në nivel lokal, ekzekutoj serverin e devijimit të Webpack në sfond (kjo është një veçori e rrjedhës sime të punës) dhe kryej teste.

Nëse dëshironi që depoja juaj të shfaqë distinktivë që tregojnë mbulimin e testit, këtu Ju mund të gjeni udhëzime të shkurtra për përdorimin e Jest, Travis CI dhe Kominoshe për të mbledhur dhe shfaqur këtë informacion.

Pra, këtu është përmbajtja e skedarit .travis.yml:

# Установить язык
language: node_js

# Установить версию Node.js
node_js:
  - '12'

services:
  # Использовать командную строку Docker
  - docker

install:
  # Установить зависимости для тестов
  - npm ci

before_script:
  # Запустить сервер и клиент для тестов
  - npm run dev &

script:
  # Запустить тесты
  - npm run test

Këtu përfundojnë veprimet që kryhen për të gjitha degët e depove dhe për kërkesat për tërheqje.

▍Shpërndarja

Bazuar në supozimin se të gjitha testet e automatizuara përfunduan me sukses, ne mundemi, që është opsionale, të vendosim kodin në serverin e prodhimit. Meqenëse këtë duam ta bëjmë vetëm për kodin nga dega master, ne i japim sistemit udhëzimet e duhura në cilësimet e vendosjes. Përpara se të provoni të përdorni kodin që do të shikojmë më pas në projektin tuaj, do të doja t'ju paralajmëroja se duhet të keni një skript aktual të thirrur për vendosje.

deploy:
  # Собрать Docker-контейнер и отправить его на Docker Hub
  provider: script
  script: bash deploy.sh
  on:
    branch: master

Skripti i vendosjes zgjidh dy probleme:

  • Ndërtoni, etiketoni dhe dërgoni imazhin në Docker Hub duke përdorur një mjet CI (në rastin tonë, Travis CI).
  • Ngarkimi i imazhit në server, ndalimi i kontejnerit të vjetër dhe fillimi i një të reje (në rastin tonë, serveri funksionon në platformën DigitalOcean).

Së pari, duhet të konfiguroni një proces automatik për ndërtimin, etiketimin dhe shtyrjen e imazhit në Docker Hub. E gjithë kjo është shumë e ngjashme me atë që kemi bërë tashmë me dorë, përveç se na duhet një strategji për caktimin e etiketave unike për imazhet dhe automatizimin e hyrjeve. Kisha vështirësi me disa detaje të skriptit të vendosjes, të tilla si strategjia e etiketimit, identifikimi, kodimi i çelësit SSH, vendosja e lidhjes SSH. Por për fat i dashuri im është shumë i mirë me bash, si me shumë gjëra të tjera. Ai më ndihmoi të shkruaj këtë skenar.

Pra, pjesa e parë e skenarit është ngarkimi i imazhit në Docker Hub. Kjo është mjaft e lehtë për t'u bërë. Skema e etiketimit që përdora përfshin kombinimin e një git hash dhe një etiketë git, nëse ekziston. Kjo siguron që etiketa është unike dhe e bën më të lehtë identifikimin e asamblesë në të cilën bazohet. DOCKER_USERNAME и DOCKER_PASSWORD janë variabla të mjedisit të përdoruesit që mund të vendosen duke përdorur ndërfaqen Travis CI. Travis CI do të përpunojë automatikisht të dhënat e ndjeshme në mënyrë që të mos bien në duar të gabuara.

Këtu është pjesa e parë e skenarit deploy.sh.

#!/bin/sh
set -e # Остановить скрипт при наличии ошибок

IMAGE="<username>/<repository>"                             # Образ Docker
GIT_VERSION=$(git describe --always --abbrev --tags --long) # Git-хэш и теги

# Сборка и тегирование образа
docker build -t ${IMAGE}:${GIT_VERSION} .
docker tag ${IMAGE}:${GIT_VERSION} ${IMAGE}:latest

# Вход в Docker Hub и выгрузка образа
echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin
docker push ${IMAGE}:${GIT_VERSION}

Cila do të jetë pjesa e dytë e skenarit varet tërësisht nga ajo host që po përdorni dhe si është organizuar lidhja me të. Në rastin tim, duke qenë se përdor Digital Ocean, përdor komandat për t'u lidhur me serverin doctl. Kur punoni me AWS, do të përdoret programi aws, dhe kështu me radhë.

Vendosja e serverit nuk ishte veçanërisht e vështirë. Pra, vendosa një pikëz bazuar në imazhin bazë. Duhet të theksohet se sistemi që zgjodha kërkon një instalim manual një herë të Docker dhe një lëshim manual një herë të Docker. Kam përdorur Ubuntu 18.04 për të instaluar Docker, kështu që nëse po përdorni edhe Ubuntu për të bërë të njëjtën gjë, thjesht mund të ndiqni kjo udhëzues i thjeshtë.

Nuk po flas këtu për komanda specifike për shërbimin, pasi ky aspekt mund të ndryshojë shumë në raste të ndryshme. Unë thjesht do të jap një plan të përgjithshëm veprimi që do të kryhet pas lidhjes nëpërmjet SSH me serverin në të cilin do të vendoset projekti:

  • Ne duhet të gjejmë kontejnerin që po funksionon aktualisht dhe ta ndalojmë atë.
  • Pastaj ju duhet të nisni një enë të re në sfond.
  • Ju do të duhet të vendosni portin lokal të serverit në 80 - kjo do t'ju lejojë të futni faqen në një adresë si example.com, pa specifikuar portin, në vend që të përdorni një adresë si example.com:5000.
  • Më në fund, duhet të fshini të gjitha kontejnerët dhe imazhet e vjetra.

Këtu është vazhdimi i skenarit.

# Найти ID работающего контейнера
CONTAINER_ID=$(docker ps | grep takenote | cut -d" " -f1)

# Остановить старый контейнер, запустить новый, очистить систему
docker stop ${CONTAINER_ID}
docker run --restart unless-stopped -d -p 80:5000 ${IMAGE}:${GIT_VERSION}
docker system prune -a -f

Disa gjëra për t'u kushtuar vëmendje

Është e mundur që kur të lidheni me serverin nëpërmjet SSH nga Travis CI, do të shihni një paralajmërim që do t'ju pengojë të vazhdoni me instalimin pasi sistemi do të presë përgjigjen e përdoruesit.

The authenticity of host '<hostname> (<IP address>)' can't be established.
RSA key fingerprint is <key fingerprint>.
Are you sure you want to continue connecting (yes/no)?

Mësova se një çelës vargu mund të kodohet në bazën 64 për ta ruajtur atë në një formë në të cilën mund të punohet me lehtësi dhe besueshmëri. Në fazën e instalimit, mund të deshifroni çelësin publik dhe ta shkruani atë në një skedar known_hosts për të hequr qafe gabimin e mësipërm.

echo <public key> | base64 # выводит <публичный ключ, закодированный в base64>

Në praktikë, kjo komandë mund të duket si kjo:

echo "123.45.67.89 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFi9wrf+M7Q== [email protected]" | base64

Dhe ja çfarë prodhon - një varg i koduar me bazë64:

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

Këtu është komanda e përmendur më lart

install:
  - echo < публичный ключ, закодированный в base64> | base64 -d >> $HOME/.ssh/known_hosts

E njëjta qasje mund të përdoret me një çelës privat kur krijoni një lidhje, pasi mund t'ju duhet një çelës privat për të hyrë në server. Kur punoni me çelësin, thjesht duhet të siguroheni që ai të ruhet në mënyrë të sigurt në një ndryshore të mjedisit Travis CI dhe që të mos shfaqet askund.

Një tjetër gjë për t'u theksuar është se mund t'ju duhet të ekzekutoni të gjithë skriptin e vendosjes si një rresht, për shembull - me doctl. Kjo mund të kërkojë disa përpjekje shtesë.

doctl compute ssh <droplet> --ssh-command "все команды будут здесь && здесь"

TLS/SSL dhe balancimi i ngarkesës

Pasi bëra gjithçka që u përmend më lart, problemi i fundit që hasa ishte se serveri nuk kishte SSL. Meqenëse përdor një server Node.js, për të detyruar për të punuar përfaqësuesi i kundërt Nginx dhe Let's Encrypt, ju duhet të ndërhyni shumë.

Unë me të vërtetë nuk doja ta bëja të gjithë këtë konfigurim SSL me dorë, kështu që thjesht krijova një balancues të ngarkesës dhe regjistrova detajet e tij në DNS. Në rastin e DigitalOcean, për shembull, krijimi i një certifikate të vetë-nënshkruar që rinovohet automatikisht në balancuesin e ngarkesës është një procedurë e thjeshtë, falas dhe e shpejtë. Kjo qasje ka përfitimin e shtuar që e bën shumë të lehtë konfigurimin e SSL në serverë të shumtë që funksionojnë pas një balancuesi të ngarkesës nëse është e nevojshme. Kjo i lejon vetë serverët të mos "mendojnë" fare për SSL, por në të njëjtën kohë të përdorin portin si zakonisht 80. Pra, vendosja e SSL në një balancues ngarkese është shumë më e lehtë dhe më e përshtatshme sesa metodat alternative të konfigurimit të SSL.

Tani mund të mbyllni të gjitha portet në server që pranojnë lidhjet hyrëse - përveç portit 80, përdoret për të komunikuar me balancuesin e ngarkesës dhe portin 22 për SSH. Si rezultat, një përpjekje për të hyrë drejtpërdrejt në server në çdo port tjetër përveç këtyre dyve do të dështojë.

Rezultatet e

Pasi bëra gjithçka për të cilën fola në këtë material, as platforma Docker dhe as konceptet e zinxhirëve të automatizuar CI/CD nuk më trembën më. Unë kam qenë në gjendje të krijoj një zinxhir të vazhdueshëm integrimi, gjatë të cilit kodi testohet përpara se të hyjë në prodhim dhe kodi vendoset automatikisht në server. E gjithë kjo është ende relativisht e re për mua dhe jam i sigurt se ka mënyra për të përmirësuar rrjedhën time të automatizuar të punës dhe për ta bërë atë më efikas. Pra, nëse keni ndonjë ide për këtë çështje, ju lutem më tregoni. per mua e di. Shpresoj se ky artikull ju ka ndihmuar në përpjekjet tuaja. Dua të besoj se pasi e lexova, mësove aq sa mësova unë, duke kuptuar gjithçka për të cilën fola në të.

PS Në tonë treg ka një imazh prerës, i cili mund të instalohet me një klik. Ju mund të kontrolloni funksionimin e kontejnerëve në VPS. Të gjithë klientëve të rinj u jepet 3 ditë testim pa pagesë.

Të nderuar lexues! A përdorni teknologjitë CI/CD në projektet tuaja?

Krijimi i një zinxhiri CI/CD dhe automatizimi i punës me Docker

Burimi: www.habr.com

Shto një koment