CI/CD շղթայի ստեղծում և Docker-ի հետ աշխատանքի ավտոմատացում
Իմ առաջին կայքերը գրել եմ 90-ականների վերջին: Այն ժամանակ շատ հեշտ էր դրանք գործի մեջ դնել։ Որոշ ընդհանուր հոստինգի վրա կար Apache սերվեր, դուք կարող եք մուտք գործել այս սերվեր FTP-ի միջոցով՝ գրելով նման բան. ftp://ftp.example.com. Այնուհետև դուք պետք է մուտքագրեք ձեր անունը և գաղտնաբառը և վերբեռնեք ֆայլերը սերվեր: Տարբեր ժամանակներ են եղել, այն ժամանակ ամեն ինչ ավելի պարզ էր, քան հիմա։
Դրանից հետո երկու տասնամյակի ընթացքում ամեն ինչ շատ է փոխվել։ Կայքերն ավելի բարդ են դարձել, դրանք պետք է հավաքվեն մինչև արտադրության դուրս գալը: Մեկ սերվերը դարձավ բազմաթիվ սերվերներ, որոնք աշխատում էին բեռի հավասարակշռողների հետևում, և տարբերակների կառավարման համակարգերի օգտագործումը սովորական դարձավ:
Իմ անձնական նախագծի համար ես ունեի հատուկ կոնֆիգուրացիա: Եվ ես գիտեի, որ ինձ անհրաժեշտ է կայքն արտադրությունում տեղակայելու կարողություն՝ կատարելով ընդամենը մեկ գործողություն՝ կոդ գրել մասնաճյուղին: 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
---
Ես գիտեմ, թե ինչպես գործարկել արտադրական հավելվածը տեղում: Ես ունեմ Webpack կոնֆիգուրացիա, որը նախատեսված է պատրաստի React հավելված ստեղծելու համար: Հաջորդը, ես հրաման ունեմ, որը նավահանգստում սկսում է Node.js-ի վրա հիմնված սերվերը 5000. Այն կարծես այսպիսին է.
npm i # установка зависимостей
npm run build # сборка React-приложения
npm run start # запуск Node-сервера
Հարկ է նշել, որ այս նյութի համար օրինակելի դիմում չունեմ։ Բայց այստեղ, փորձերի համար, ցանկացած պարզ Node հավելված կարող է անել:
Բեռնարկղն օգտագործելու համար դուք պետք է հրահանգներ տաք Docker-ին: Դա արվում է ֆայլի միջոցով, որը կոչվում է Dockerfile, որը գտնվում է նախագծի արմատական գրացուցակում: Այս ֆայլը սկզբում բավականին անհասկանալի է թվում։
Բայց այն, ինչ այն պարունակում է, միայն նկարագրում է, հատուկ հրամաններով, աշխատանքային միջավայր ստեղծելու նման մի բան: Ահա այս հրամաններից մի քանիսը.
- ԻՑ — Այս հրամանը սկսում է ֆայլ: Այն նշում է բազային պատկերը, որի վրա կառուցված է կոնտեյները:
COPY — Ֆայլերի պատճենում տեղական աղբյուրից կոնտեյներ:
ԱՇԽԱՏԱՆՔԱՅԻՆ ԴԻՐ — Աշխատանքային գրացուցակի կարգավորում հետևյալ հրամանների համար:
# Загрузить базовый образ
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 գործիքի ստեղծում:
Արտադրության սերվերի կարգավորում, որպեսզի այն կարողանա ներբեռնել և գործարկել մեր կոդը:
Հարկ է նշել, որ այստեղ դուք կարող եք օգտվել ծառայությունների մեկ այլ համակցությունից: Օրինակ, 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 վերը նշված սխալից ազատվելու համար։
Նույն մոտեցումը կարող է օգտագործվել մասնավոր բանալիով կապ հաստատելիս, քանի որ ձեզ կարող է անհրաժեշտ լինել մասնավոր բանալի՝ սերվեր մուտք գործելու համար: Բանալին աշխատելիս պարզապես պետք է համոզվեք, որ այն ապահով կերպով պահվում է 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 օր անվճար թեստավորում: