CI/CD շղթայի ստեղծում և Docker-ի հետ աշխատանքի ավտոմատացում

Իմ առաջին կայքերը գրել եմ 90-ականների վերջին: Այն ժամանակ շատ հեշտ էր դրանք գործի մեջ դնել։ Որոշ ընդհանուր հոստինգի վրա կար Apache սերվեր, դուք կարող եք մուտք գործել այս սերվեր FTP-ի միջոցով՝ գրելով նման բան. ftp://ftp.example.com. Այնուհետև դուք պետք է մուտքագրեք ձեր անունը և գաղտնաբառը և վերբեռնեք ֆայլերը սերվեր: Տարբեր ժամանակներ են եղել, այն ժամանակ ամեն ինչ ավելի պարզ էր, քան հիմա։

CI/CD շղթայի ստեղծում և Docker-ի հետ աշխատանքի ավտոմատացում

Դրանից հետո երկու տասնամյակի ընթացքում ամեն ինչ շատ է փոխվել։ Կայքերն ավելի բարդ են դարձել, դրանք պետք է հավաքվեն մինչև արտադրության դուրս գալը: Մեկ սերվերը դարձավ բազմաթիվ սերվերներ, որոնք աշխատում էին բեռի հավասարակշռողների հետևում, և տարբերակների կառավարման համակարգերի օգտագործումը սովորական դարձավ:

Իմ անձնական նախագծի համար ես ունեի հատուկ կոնֆիգուրացիա: Եվ ես գիտեի, որ ինձ անհրաժեշտ է կայքն արտադրությունում տեղակայելու կարողություն՝ կատարելով ընդամենը մեկ գործողություն՝ կոդ գրել մասնաճյուղին: master GitHub-ում: Բացի այդ, ես գիտեի, որ իմ փոքրիկ վեբ հավելվածի շահագործումն ապահովելու համար ես չէի ուզում կառավարել Kubernetes-ի հսկայական կլաստերը, կամ օգտագործել Docker Swarm տեխնոլոգիան կամ պահպանել սերվերների նավատորմը pods-ով, գործակալներով և բոլոր տեսակի այլ սարքերով: բարդությունները. Աշխատանքը հնարավորինս հեշտացնելու նպատակին հասնելու համար ինձ անհրաժեշտ էր ծանոթանալ CI/CD-ին:

Եթե ​​դուք ունեք փոքր նախագիծ (այս դեպքում՝ Node.js նախագիծ) և կցանկանայիք իմանալ, թե ինչպես ավտոմատացնել այս նախագծի տեղակայումը, միևնույն ժամանակ համոզվելով, որ պահեստում պահվածը ճիշտ համընկնում է արտադրության մեջ աշխատողի հետ, ապա ես կարծում եմ, որ ձեզ կարող է հետաքրքրել այս հոդվածը:

Նախադրյալներ

Ակնկալվում է, որ այս հոդվածի ընթերցողը հիմնական հասկացողություն կունենա հրամանի տողի և Bash սցենարներ գրելու մասին: Բացի այդ, նրան հաշիվներ են պետք Թրևիս CI и Docker հանգույց.

Նպատակը

Չեմ ասի, որ այս հոդվածն անվերապահորեն կարելի է անվանել «ուղեցույց»: Սա ավելի շատ փաստաթուղթ է, որում ես խոսում եմ իմ իմացածի մասին և նկարագրում եմ այն ​​գործընթացը, որն ինձ հարմար է արտադրության մեջ կոդ փորձարկելու և տեղակայելու համար, որն իրականացվում է մեկ ավտոմատացված անցումով:

Սա այն է, ինչ ավարտվեց իմ աշխատանքային հոսքը:

Կոդի համար, որը տեղադրված է պահեստի ցանկացած մասնաճյուղում, բացառությամբ master, կատարվում են հետևյալ գործողությունները.

  • Սկսվում է Travis CI-ի վրա հիմնված նախագիծը:
  • Կատարվում են միավորի, ինտեգրման և վերջից մինչև վերջ բոլոր թեստերը:

Միայն կոդի համար, որը մտնում է master, կատարվում է հետևյալը.

  • Այն ամենը, ինչ վերը նշված է, գումարած...
  • Ներկայիս կոդի, կարգավորումների և միջավայրի հիման վրա Docker պատկերի կառուցում:
  • Պատկերի տեղակայում Docker Hub-ում:
  • Միացում արտադրության սերվերին:
  • Docker Hub-ից պատկերի վերբեռնում սերվեր:
  • Ընթացիկ կոնտեյների դադարեցում և նոր պատկերի հիման վրա նորը սկսելու համար:

Եթե ​​դուք բացարձակապես ոչինչ չգիտեք Docker-ի, պատկերների և բեռնարկղերի մասին, մի անհանգստացեք: Ես ձեզ ամեն ինչ կասեմ դրա մասին:

Ի՞նչ է CI/CD-ն:

CI/CD հապավումը նշանակում է «շարունակական ինտեգրում/շարունակական տեղակայում»:

▍Շարունակական ինտեգրում

Շարունակական ինտեգրումը գործընթաց է, որի ընթացքում ծրագրավորողները պարտավորություններ են ստանձնում նախագծի հիմնական կոդերի պահեստի (սովորաբար մասնաճյուղի) նկատմամբ master) Միաժամանակ ծածկագրի որակն ապահովվում է ավտոմատացված թեստավորման միջոցով։

▍Շարունակական տեղակայում

Շարունակական տեղակայումը կոդի հաճախակի ավտոմատացված տեղակայումն է արտադրության մեջ: CI/CD հապավումի երկրորդ մասը երբեմն գրված է որպես «շարունակական առաքում»: Սա հիմնականում նույնն է, ինչ «շարունակական տեղակայումը», բայց «շարունակական առաքումը» ենթադրում է փոփոխությունները ձեռքով հաստատելու անհրաժեշտություն՝ նախքան նախագծի տեղակայման գործընթացը սկսելը:

Ինչից սկսել

Հավելվածը, որով սովորել եմ այս ամենը, կոչվում է TakeNote. Սա վեբ-նախագիծ է, որի վրա ես աշխատում եմ, որը նախատեսված է գրառումներ անելու համար: Սկզբում ես փորձեցի անել JAMStack-նախագիծ կամ պարզապես առանց սերվերի ֆրոնտային հավելված՝ օգտվելու ստանդարտ հոսթինգի և նախագծի տեղակայման հնարավորություններից, որոնք այն առաջարկում է Netlify. Քանի որ հավելվածի բարդությունը մեծանում էր, ես պետք է ստեղծեի դրա սերվերի մասը, ինչը նշանակում էր, որ ես պետք է ձևակերպեի իմ սեփական ռազմավարությունը ավտոմատացված ինտեգրման և նախագծի ավտոմատացված տեղակայման համար:

Իմ դեպքում հավելվածը էքսպրես սերվեր է, որն աշխատում է Node.js միջավայրում, որը սպասարկում է մեկ էջից բաղկացած React հավելված և աջակցում է սերվերի կողմից ապահով API: Այս ճարտարապետությունը հետևում է այն ռազմավարությանը, որը կարելի է գտնել տրված Ամբողջական փաթեթի նույնականացման ուղեցույց:

Ես խորհրդակցել եմ другом, ով ավտոմատացման փորձագետ է, և հարցրեց նրան, թե ինչ պետք է անեի, որպեսզի ամեն ինչ աշխատի այնպես, ինչպես ես էի ուզում: Նա ինձ գաղափար տվեց, թե ինչպիսին պետք է լինի ավտոմատացված աշխատանքային հոսքը, որը նկարագրված է այս հոդվածի Նպատակներ բաժնում: Այս նպատակներն ունենալը նշանակում էր, որ ես պետք է պարզեի, թե ինչպես օգտագործել Docker-ը:

դոկեր

Docker-ը գործիք է, որը կոնտեյներացման տեխնոլոգիայի շնորհիվ թույլ է տալիս հավելվածները հեշտությամբ բաշխվել, տեղակայվել և գործարկվել նույն միջավայրում, նույնիսկ եթե Docker պլատֆորմն ինքն աշխատում է տարբեր միջավայրերում: Նախ, ինձ պետք էր ձեռքս ձեռք բերել Docker հրամանի տող գործիքները (CLI): հրահանգ Docker տեղադրման ուղեցույցը չի կարելի անվանել շատ պարզ և հասկանալի, բայց դրանից դուք կարող եք իմանալ, որ տեղադրման առաջին քայլը կատարելու համար անհրաժեշտ է ներբեռնել Docker Desktop-ը (Mac-ի կամ Windows-ի համար):

Docker Hub-ը մոտավորապես նույնն է, ինչ GitHub git պահեստների կամ ռեեստրի համար npm JavaScript փաթեթների համար: Սա Docker պատկերների առցանց պահոց է: Սա այն է, ինչին միանում է Docker Desktop-ը:

Այսպիսով, Docker-ով սկսելու համար դուք պետք է անեք երկու բան.

Դրանից հետո դուք կարող եք ստուգել, ​​թե արդյոք Docker CLI-ն աշխատում է՝ գործարկելով հետևյալ հրամանը՝ Docker տարբերակը ստուգելու համար.

docker -v

Հաջորդը, մուտք գործեք Docker Hub՝ մուտքագրելով ձեր օգտանունը և գաղտնաբառը, երբ հարցնում են.

docker login

Docker-ն օգտագործելու համար դուք պետք է հասկանաք պատկերների և բեռնարկղերի հասկացությունները:

▍Պատկերներ

Պատկերը նախագծման նման մի բան է, որը պարունակում է բեռնարկղը հավաքելու հրահանգներ: Սա հավելվածի ֆայլային համակարգի և կարգավորումների անփոփոխ պատկերն է: Մշակողները կարող են հեշտությամբ կիսվել պատկերներով:

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

Այս հրամանը կթողարկի աղյուսակ հետևյալ վերնագրով.

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

Հաջորդը մենք կդիտարկենք հրամանների մի քանի օրինակներ նույն ձևաչափով. նախ կա մեկնաբանություն ունեցող հրաման, այնուհետև օրինակ, թե ինչ կարող է այն թողարկել:

▍Բեռնարկղեր

Կոնտեյները գործարկվող փաթեթ է, որը պարունակում է այն ամենը, ինչ անհրաժեշտ է հավելվածը գործարկելու համար: Այս մոտեցմամբ հավելվածը միշտ նույնն է աշխատելու՝ անկախ ենթակառուցվածքից՝ մեկուսացված միջավայրում և նույն միջավայրում: Բանն այն է, որ նույն պատկերի օրինակները գործարկվում են տարբեր միջավայրերում:

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

▍Տեգեր

Պիտակը պատկերի որոշակի տարբերակի ցուցում է:

▍ Արագ հղում Docker հրամաններին

Ահա որոշ Docker հրամանների ընդհանուր ակնարկ:

Թիմ

Համատեքստ

ազդեցություն

դոկերի կառուցում

Պատկեր

Պատկերի կառուցում Dockerfile-ից

դոկեր պիտակ

Պատկեր

Պատկերի պիտակավորում

դոկտոր պատկերներ

Պատկեր

Պատկերների ցուցակագրում

docker վազում

Բեռնարկղ

Պատկերի վրա հիմնված կոնտեյների վարում

դոկեր հրում

Պատկեր

Պատկերի վերբեռնում գրանցամատյանում

դոկերի քաշում

Պատկեր

Պատկերի բեռնում ռեեստրից

դոկտոր ps

Բեռնարկղ

Տարաների ցուցակագրում

docker system prune

Պատկեր/կոնտեյներ

Չօգտագործված տարաների և պատկերների հեռացում

▍Dockerfile

Ես գիտեմ, թե ինչպես գործարկել արտադրական հավելվածը տեղում: Ես ունեմ Webpack կոնֆիգուրացիա, որը նախատեսված է պատրաստի React հավելված ստեղծելու համար: Հաջորդը, ես հրաման ունեմ, որը նավահանգստում սկսում է Node.js-ի վրա հիմնված սերվերը 5000. Այն կարծես այսպիսին է.

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

Հարկ է նշել, որ այս նյութի համար օրինակելի դիմում չունեմ։ Բայց այստեղ, փորձերի համար, ցանկացած պարզ Node հավելված կարող է անել:

Բեռնարկղն օգտագործելու համար դուք պետք է հրահանգներ տաք Docker-ին: Դա արվում է ֆայլի միջոցով, որը կոչվում է Dockerfile, որը գտնվում է նախագծի արմատական ​​գրացուցակում: Այս ֆայլը սկզբում բավականին անհասկանալի է թվում։

Բայց այն, ինչ այն պարունակում է, միայն նկարագրում է, հատուկ հրամաններով, աշխատանքային միջավայր ստեղծելու նման մի բան: Ահա այս հրամաններից մի քանիսը.

  • - ԻՑ — Այս հրամանը սկսում է ֆայլ: Այն նշում է բազային պատկերը, որի վրա կառուցված է կոնտեյները:
  • COPY — Ֆայլերի պատճենում տեղական աղբյուրից կոնտեյներ:
  • ԱՇԽԱՏԱՆՔԱՅԻՆ ԴԻՐ — Աշխատանքային գրացուցակի կարգավորում հետևյալ հրամանների համար:
  • RUN - Գործարկել հրամանները:
  • ԲԱՑԱՀԱՅՏԵԼ - Նավահանգստի կարգավորումներ:
  • ՄՈՒՏՔԻ ԿԵՏ — Կատարվելիք հրամանի նշում:

Dockerfile կարող է նման բան թվալ.

# Загрузить базовый образ
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

Կախված ձեր ընտրած բազային պատկերից, ձեզ կարող է անհրաժեշտ լինել տեղադրել լրացուցիչ կախվածություններ: Փաստն այն է, որ որոշ բազային պատկերներ (ինչպես Node Alpine Linux-ը) ստեղծվում են՝ դրանք հնարավորինս կոմպակտ դարձնելու նպատակով: Արդյունքում, նրանք կարող են չունենալ որոշ ծրագրեր, որոնք դուք ակնկալում եք:

▍ Կոնտեյների կառուցում, պիտակավորում և գործարկում

Բեռնարկղի տեղական հավաքումը և գործարկումը տեղի է ունենում այն ​​բանից հետո, երբ մենք ունենք Dockerfile, առաջադրանքները բավականին պարզ են. Նախքան պատկերը Docker Hub-ին մղելը, դուք պետք է փորձարկեք այն տեղական մակարդակում:

▍Հավաքում

Նախ պետք է հավաքել նկարը, նշելով անուն և, ըստ ցանկության, պիտակ (եթե պիտակը նշված չէ, համակարգը ավտոմատ կերպով պիտակ կհատկացնի պատկերին latest).

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

Այս հրամանը գործարկելուց հետո դուք կարող եք դիտել Docker-ի կառուցման պատկերը:

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

Կառուցումը կարող է տևել մի քանի րոպե. ամեն ինչ կախված է նրանից, թե որքան կախվածություն ունեք: Կառուցումն ավարտվելուց հետո կարող եք գործարկել հրամանը docker images և նայեք ձեր նոր պատկերի նկարագրությանը:

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

▍ Գործարկել

Պատկերը ստեղծվել է։ Սա նշանակում է, որ դուք կարող եք գործարկել կոնտեյներ դրա հիման վրա: Որովհետև ես ուզում եմ, որ կարողանամ մուտք գործել կոնտեյներով աշխատող հավելված localhost:5000, ես, զույգի ձախ կողմում 5000:5000 հաջորդ տեղադրված հրամանում 5000. Աջ կողմում կոնտեյների նավահանգիստն է:

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

Այժմ, երբ կոնտեյները ստեղծվել և աշխատում է, կարող եք օգտագործել հրամանը docker ps այս կոնտեյների մասին տեղեկությունները դիտելու համար (կամ կարող եք օգտագործել հրամանը docker ps -a, որը ցուցադրում է տեղեկատվություն բոլոր բեռնարկղերի մասին, ոչ միայն գործարկվողների):

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

Եթե ​​հիմա գնաք հասցեով localhost:5000 — դուք կարող եք տեսնել գործող հավելվածի էջը, որը ճիշտ նույն տեսքն ունի, ինչ արտադրական միջավայրում աշխատող հավելվածի էջը:

▍ Նշում և հրապարակում

Ստեղծված պատկերներից մեկը արտադրության սերվերում օգտագործելու համար մենք պետք է կարողանանք ներբեռնել այս պատկերը Docker Hub-ից։ Սա նշանակում է, որ դուք նախ պետք է ստեղծեք շտեմարան նախագծի համար Docker Hub-ում: Դրանից հետո մենք կունենանք մի տեղ, որտեղ մենք կարող ենք ուղարկել պատկերը: Պատկերը պետք է վերանվանվի այնպես, որ դրա անունը սկսվի մեր Docker Hub օգտանունով: Դրան պետք է հաջորդի պահեստի անվանումը: Ցանկացած պիտակ կարող է տեղադրվել անվան վերջում: Ստորև բերված է այս սխեմայի օգտագործմամբ պատկերների անվանման օրինակ:

Այժմ դուք կարող եք կառուցել պատկերը նոր անունով և գործարկել հրամանը docker push այն դեպի 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

Եթե ​​ամեն ինչ լավ ընթանա, պատկերը հասանելի կլինի Docker Hub-ում և հեշտությամբ կարող է վերբեռնվել սերվեր կամ փոխանցվել այլ մշակողների:

Հաջորդ քայլերը

Մինչ այժմ մենք հաստատել ենք, որ հավելվածը, Docker կոնտեյների տեսքով, աշխատում է տեղական մակարդակում: Մենք բեռնարկղը վերբեռնել ենք Docker Hub: Այս ամենը նշանակում է, որ մենք արդեն շատ լավ առաջընթաց ենք գրանցել դեպի մեր նպատակը։ Այժմ մենք պետք է լուծենք ևս երկու հարց.

  • Կոդերի փորձարկման և տեղակայման համար CI գործիքի ստեղծում:
  • Արտադրության սերվերի կարգավորում, որպեսզի այն կարողանա ներբեռնել և գործարկել մեր կոդը:

Մեր դեպքում մենք օգտագործում ենք Թրևիս CI. Որպես սերվեր - DitigalOcean.

Հարկ է նշել, որ այստեղ դուք կարող եք օգտվել ծառայությունների մեկ այլ համակցությունից: Օրինակ, Travis CI-ի փոխարեն կարող եք օգտագործել CircleCI կամ Github Actions: Իսկ DigitalOcean-ի փոխարեն՝ AWS կամ Linode:

Մենք որոշեցինք աշխատել Travis CI-ի հետ, և ես արդեն ինչ-որ բան կարգավորել եմ այս ծառայության մեջ: Հետեւաբար, հիմա ես համառոտ կխոսեմ այն ​​մասին, թե ինչպես պատրաստել այն աշխատանքի համար:

Թրևիս CI

Travis CI-ն կոդի փորձարկման և տեղակայման գործիք է: Ես չէի ցանկանա մտնել Travis CI-ի ստեղծման բարդությունների մեջ, քանի որ յուրաքանչյուր նախագիծ եզակի է, և դա մեծ օգուտ չի բերի: Բայց ես կանդրադառնամ հիմունքներին՝ սկսելու համար, եթե որոշեք օգտագործել Travis CI-ն: Անկախ նրանից, թե դուք ընտրում եք Travis CI, CircleCI, Jenkins կամ որևէ այլ բան, նման կազմաձևման մեթոդները կօգտագործվեն ամենուր:

Travis CI-ի հետ սկսելու համար այցելեք կայքի պրոեկտ և ստեղծել հաշիվ: Այնուհետև ինտեգրեք Travis CI-ն ձեր GitHub հաշվի հետ: Համակարգը կարգավորելիս դուք պետք է նշեք այն պահոցը, որով ցանկանում եք ավտոմատացնել աշխատանքը և միացնել մուտքը դեպի այն: (Ես օգտագործում եմ GitHub, բայց վստահ եմ, որ Travis CI-ն կարող է ինտեգրվել BitBucket-ի, GitLab-ի և նմանատիպ այլ ծառայությունների հետ):

Ամեն անգամ, երբ Travis CI-ն գործարկվում է, սերվերը գործարկվում է՝ կատարելով կազմաձևման ֆայլում նշված հրամանները, ներառյալ պահեստի համապատասխան ճյուղերի տեղակայումը:

▍Աշխատանքի կյանքի ցիկլը

Զանգված է Travis CI կազմաձևման ֆայլը .travis.yml և պահվում է նախագծի արմատական ​​գրացուցակում, աջակցում է իրադարձությունների հայեցակարգին կյանքի ցիկլ առաջադրանքներ. Այս իրադարձությունները թվարկված են այն հաջորդականությամբ, որով դրանք տեղի են ունենում.

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

▍Թեստավորում

Կազմաձևման ֆայլում ես պատրաստվում եմ կարգավորել տեղական Travis CI սերվերը: Ես ընտրեցի Node 12-ը որպես լեզու և համակարգին ասացի տեղադրել Docker-ի օգտագործման համար անհրաժեշտ կախվածությունները:

Այն ամենը, ինչ նշված է .travis.yml, կկատարվի, երբ բոլոր pull հարցումները կատարվեն պահեստի բոլոր մասնաճյուղերին, եթե այլ բան նախատեսված չէ: Սա օգտակար հատկություն է, քանի որ դա նշանակում է, որ մենք կարող ենք ստուգել բոլոր ծածկագրերը, որոնք մտնում են պահեստ: Սա թույլ է տալիս ձեզ իմանալ, թե արդյոք կոդը պատրաստ է մասնաճյուղում գրվելու համար: master, և արդյոք դա կխախտի նախագծի կառուցման գործընթացը: Այս գլոբալ կոնֆիգուրացիայի մեջ ես ամեն ինչ տեղադրում եմ տեղում, գործարկում եմ Webpack մշակող սերվերը հետին պլանում (սա իմ աշխատանքային հոսքի առանձնահատկությունն է) և կատարում թեստեր:

Եթե ​​ցանկանում եք, որ ձեր պահոցը ցուցադրի կրծքանշաններ, որոնք ցույց են տալիս թեստի ծածկույթը, այստեղ Այս տեղեկատվությունը հավաքելու և ցուցադրելու համար կարող եք գտնել կարճ հրահանգներ Jest, Travis CI և Coveralls-ի օգտագործման վերաբերյալ:

Այսպիսով, ահա ֆայլի բովանդակությունը .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

Այստեղ ավարտվում են այն գործողությունները, որոնք կատարվում են պահեստի բոլոր մասնաճյուղերի և pull հարցումների համար:

▍Տեղակայում

Ելնելով այն ենթադրությունից, որ բոլոր ավտոմատացված թեստերը հաջողությամբ ավարտվել են, մենք կարող ենք, որը պարտադիր չէ, կոդը տեղակայել արտադրության սերվերում: Քանի որ մենք ուզում ենք դա անել միայն մասնաճյուղի կոդի համար master, մենք համակարգին տալիս ենք համապատասխան հրահանգներ տեղակայման կարգավորումներում: Նախքան փորձեք օգտագործել կոդը, որը մենք կդիտարկենք հաջորդիվ ձեր նախագծում, ես կցանկանայի զգուշացնել ձեզ, որ դուք պետք է ունենաք իրական սկրիպտ, որը կոչվում է տեղակայման համար:

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

Տեղակայման սցենարը լուծում է երկու խնդիր.

  • Կառուցեք, նշեք և ուղարկեք պատկերը Docker Hub-ին՝ օգտագործելով CI գործիք (մեր դեպքում՝ Travis CI):
  • Պատկերը սերվերի վրա բեռնելը, հին կոնտեյների դադարեցումը և նորը սկսելը (մեր դեպքում սերվերն աշխատում է DigitalOcean հարթակում):

Նախ, դուք պետք է ստեղծեք ավտոմատ գործընթաց՝ պատկերը կառուցելու, հատկորոշելու և դեպի Docker Hub մղելու համար: Այս ամենը շատ նման է նրան, ինչ մենք արդեն արել ենք ձեռքով, բացառությամբ, որ մեզ անհրաժեշտ է պատկերներին եզակի պիտակներ հատկացնելու և մուտքերն ավտոմատացնելու ռազմավարություն: Ես դժվարանում էի տեղակայման սցենարի որոշ մանրամասների հետ, ինչպիսիք են հատկորոշման ռազմավարությունը, մուտքը, SSH ստեղնաշարի կոդավորումը, SSH կապի հաստատումը: Բայց, բարեբախտաբար, իմ ընկերը շատ լավ է բաշի հետ, ինչպես շատ այլ բաների հետ: Նա օգնեց ինձ գրել այս սցենարը:

Այսպիսով, սցենարի առաջին մասը պատկերի վերբեռնումն է Docker Hub: Սա բավականին հեշտ է անել: Իմ օգտագործած հատկորոշման սխեման ներառում է git hash-ի և git tag-ի համադրումը, եթե այդպիսիք գոյություն ունեն: Սա երաշխավորում է, որ պիտակը եզակի է և հեշտացնում է այն համախումբը, որի վրա հիմնված է: DOCKER_USERNAME и DOCKER_PASSWORD օգտագործողի միջավայրի փոփոխականներ են, որոնք կարող են սահմանվել՝ օգտագործելով Travis CI ինտերֆեյսը: Travis CI-ն ավտոմատ կերպով կմշակի զգայուն տվյալները, որպեսզի դրանք չհայտնվեն սխալ ձեռքերում:

Ահա սցենարի առաջին մասը 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}

Թե ինչպիսին կլինի սցենարի երկրորդ մասը, ամբողջովին կախված է նրանից, թե ինչ հոսթ եք օգտագործում և ինչպես է կազմակերպվում կապը դրա հետ: Իմ դեպքում, քանի որ ես օգտագործում եմ Digital Ocean, ես օգտագործում եմ հրամանները սերվերին միանալու համար դոկտլ. AWS-ի հետ աշխատելիս կոմունալը կօգտագործվի aws, և այլն։

Սերվերի կարգավորումն առանձնապես դժվար չէր: Այսպիսով, ես ստեղծեցի մի կաթիլ, որը հիմնված է բազային պատկերի վրա: Պետք է նշել, որ իմ ընտրած համակարգը պահանջում է Docker-ի մեկանգամյա ձեռքով տեղադրում և Docker-ի մեկանգամյա ձեռքով գործարկում: Ես օգտագործել եմ Ubuntu 18.04 Docker-ը տեղադրելու համար, այնպես որ, եթե դուք նույնպես օգտագործում եք Ubuntu-ն նույնն անելու համար, կարող եք պարզապես հետևել այս պարզ ուղեցույց.

Ես այստեղ չեմ խոսում ծառայության հատուկ հրամանների մասին, քանի որ այս ասպեկտը կարող է շատ տարբեր լինել տարբեր դեպքերում: Ես պարզապես կտամ գործողությունների ընդհանուր պլան, որը պետք է իրականացվի SSH-ի միջոցով սերվերին միանալուց հետո, որի վրա կտեղակայվի նախագիծը.

  • Մենք պետք է գտնենք ներկայումս աշխատող կոնտեյները և կանգնեցնենք այն:
  • Ապա դուք պետք է գործարկեք նոր կոնտեյներ հետին պլանում:
  • Դուք պետք է կարգավորեք սերվերի տեղական նավահանգիստը 80 - սա թույլ կտա մուտք գործել կայք այնպիսի հասցեով, ինչպիսին է example.com, առանց նավահանգիստը նշելու, այլ ոչ թե նման հասցե օգտագործելու example.com:5000.
  • Վերջապես, դուք պետք է ջնջեք բոլոր հին բեռնարկղերը և պատկերները:

Ահա սցենարի շարունակությունը.

# Найти 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

Որոշ բաներ, որոնց վրա պետք է ուշադրություն դարձնել

Հնարավոր է, որ երբ դուք միանում եք սերվերին SSH-ի միջոցով Travis CI-ից, կտեսնեք նախազգուշացում, որը կխանգարի ձեզ շարունակել տեղադրումը, քանի որ համակարգը կսպասի օգտատիրոջ պատասխանին:

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)?

Ես իմացա, որ լարային ստեղնը կարող է կոդավորվել base64-ում, որպեսզի այն պահպանվի այնպիսի ձևով, որով կարելի է հարմար և հուսալի աշխատել: Տեղադրման փուլում դուք կարող եք վերծանել հանրային բանալին և գրել այն ֆայլում known_hosts վերը նշված սխալից ազատվելու համար։

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

Գործնականում այս հրամանը կարող է այսպիսի տեսք ունենալ.

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

Եվ ահա թե ինչ է այն արտադրում՝ base64 կոդավորված տող.

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

Ահա վերը նշված հրամանը

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

Նույն մոտեցումը կարող է օգտագործվել մասնավոր բանալիով կապ հաստատելիս, քանի որ ձեզ կարող է անհրաժեշտ լինել մասնավոր բանալի՝ սերվեր մուտք գործելու համար: Բանալին աշխատելիս պարզապես պետք է համոզվեք, որ այն ապահով կերպով պահվում է Travis CI միջավայրի փոփոխականում, և որ այն որևէ տեղ չի ցուցադրվում:

Մեկ այլ բան, որ պետք է նշել, այն է, որ ձեզ կարող է անհրաժեշտ լինել գործարկել ամբողջ տեղակայման սցենարը որպես մեկ տող, օրինակ՝ հետ doctl. Սա կարող է պահանջել լրացուցիչ ջանքեր:

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

TLS/SSL և բեռի հավասարակշռում

Այն բանից հետո, երբ ես արեցի վերը նշված ամեն ինչ, վերջին խնդիրը, որ հանդիպեցի, այն էր, որ սերվերը չուներ SSL: Քանի որ ես օգտագործում եմ Node.js սերվեր, ստիպելու համար աշխատանքը հակադարձ վստահված անձ Nginx-ը և Let’s Encrypt-ը, դուք պետք է շատ բան անեք:

Ես իսկապես չէի ուզում SSL-ի այս ամբողջ կոնֆիգուրացիան ձեռքով անել, այնպես որ ես պարզապես ստեղծեցի բեռի հավասարակշռող սարք և գրանցեցի դրա մանրամասները DNS-ում: DigitalOcean-ի դեպքում, օրինակ, բեռնվածքի հավասարակշռիչի վրա ավտոմատ թարմացվող ինքնաստորագրված վկայագրի ստեղծումը պարզ, անվճար և արագ ընթացակարգ է: Այս մոտեցումն ունի հավելյալ առավելություն, որ այն շատ հեշտ է դարձնում SSL-ի կարգավորումը մի քանի սերվերների վրա, որոնք աշխատում են բեռի հավասարակշռողի հետևում, անհրաժեշտության դեպքում: Սա թույլ է տալիս սերվերներին ընդհանրապես «չմտածել» SSL-ի մասին, բայց միևնույն ժամանակ օգտագործել պորտը, ինչպես միշտ: 80. Այսպիսով, SSL-ի տեղադրումը ծանրաբեռնվածության հավասարակշռողի վրա շատ ավելի հեշտ և հարմար է, քան SSL-ի տեղադրման այլընտրանքային մեթոդները:

Այժմ դուք կարող եք փակել սերվերի բոլոր նավահանգիստները, որոնք ընդունում են մուտքային կապերը, բացի նավահանգստից 80, օգտագործվում է բեռի հավասարակշռիչի և պորտի հետ հաղորդակցվելու համար 22 SSH-ի համար. Արդյունքում, այս երկու նավահանգիստներից բացի սերվեր ուղղակիորեն մուտք գործելու փորձը չի հաջողվի:

Արդյունքները

Այն բանից հետո, երբ ես արեցի այն ամենը, ինչի մասին խոսեցի այս նյութում, ոչ Docker հարթակը, ոչ էլ ավտոմատացված CI/CD շղթաների գաղափարներն այլևս չէին վախեցնում ինձ: Ես կարողացա ստեղծել շարունակական ինտեգրման շղթա, որի ընթացքում կոդը փորձարկվում է նախքան արտադրության մեջ մտնելը, և կոդը ավտոմատ կերպով տեղադրվում է սերվերի վրա: Այս ամենը դեռևս համեմատաբար նոր է ինձ համար, և ես վստահ եմ, որ կան ուղիներ՝ բարելավելու իմ ավտոմատացված աշխատանքային հոսքը և այն ավելի արդյունավետ դարձնելու համար: Այսպիսով, եթե դուք ունեք որևէ գաղափար այս հարցի վերաբերյալ, խնդրում եմ տեղեկացրեք ինձ: ինձ իմանալ. Հուսով եմ, որ այս հոդվածը օգնել է ձեզ ձեր ջանքերում: Ես ուզում եմ հավատալ, որ այն կարդալուց հետո դու սովորեցիր այնքան, որքան ես սովորեցի՝ պարզելով այն ամենը, ինչի մասին ես խոսեցի դրանում:

PS Մեր շուկա կա պատկեր դոկեր, որը կարող է տեղադրվել մեկ սեղմումով։ Դուք կարող եք ստուգել բեռնարկղերի աշխատանքը այստեղ VPS. Բոլոր նոր հաճախորդներին տրվում է 3 օր անվճար թեստավորում:

Հարգելի ընթերցողներ: Դուք կիրառու՞մ եք CI/CD տեխնոլոգիաներ ձեր նախագծերում:

CI/CD շղթայի ստեղծում և Docker-ի հետ աշխատանքի ավտոմատացում

Source: www.habr.com

Добавить комментарий