Paglikha ng CI/CD chain at pag-automate ng trabaho sa Docker

Isinulat ko ang aking mga unang website noong huling bahagi ng dekada 90. Noon napakadaling ilagay ang mga ito sa ayos ng trabaho. Nagkaroon ng Apache server sa ilang shared hosting, maaari kang mag-log in sa server na ito sa pamamagitan ng FTP sa pamamagitan ng pagsusulat ng katulad nito ftp://ftp.example.com. Pagkatapos ay kailangan mong ipasok ang iyong pangalan at password at i-upload ang mga file sa server. May iba't ibang panahon, mas simple ang lahat noon kaysa ngayon.

Paglikha ng CI/CD chain at pag-automate ng trabaho sa Docker

Sa loob ng dalawang dekada mula noon, malaki ang pinagbago ng lahat. Ang mga website ay naging mas kumplikado; dapat silang tipunin bago ilabas sa produksyon. Ang isang solong server ay naging maraming server na tumatakbo sa likod ng mga load balancer, at ang paggamit ng mga version control system ay naging pangkaraniwan.

Para sa aking personal na proyekto mayroon akong isang espesyal na pagsasaayos. At alam ko na kailangan ko ng kakayahang i-deploy ang site sa produksyon sa pamamagitan ng pagsasagawa ng isang aksyon lang: pagsusulat ng code sa isang sangay master sa GitHub. Bilang karagdagan, alam ko na upang matiyak ang pagpapatakbo ng aking maliit na web application, hindi ko nais na pamahalaan ang isang malaking kumpol ng Kubernetes, o gumamit ng teknolohiya ng Docker Swarm, o magpanatili ng isang fleet ng mga server na may mga pod, ahente at lahat ng uri ng iba pa. mga kumplikado. Upang makamit ang layunin na gawing mas madali ang trabaho hangga't maaari, kailangan kong maging pamilyar sa CI/CD.

Kung mayroon kang maliit na proyekto (sa kasong ito, isang proyekto ng Node.js) at gusto mong malaman kung paano i-automate ang pag-deploy ng proyektong ito, habang tinitiyak na ang naka-imbak sa repositoryo ay eksaktong tumutugma sa kung ano ang gumagana sa produksyon, pagkatapos ay isipin na baka interesado ka sa artikulong ito.

Mga Pangangailangan

Ang mambabasa ng artikulong ito ay inaasahang magkaroon ng pangunahing pag-unawa sa command line at pagsulat ng mga script ng Bash. Bilang karagdagan, kakailanganin niya ng mga account Travis CI и Docker hub.

Mga Layunin

Hindi ko sasabihin na ang artikulong ito ay maaaring walang kondisyong tawaging isang "tutorial". Ito ay higit pa sa isang dokumento kung saan pinag-uusapan ko kung ano ang aking natutunan at inilalarawan ang proseso na nababagay sa akin para sa pagsubok at pag-deploy ng code sa produksyon, na isinagawa sa isang automated pass.

Ito ang naging resulta ng daloy ng trabaho ko.

Para sa code na nai-post sa anumang sangay ng repository maliban sa master, ang mga sumusunod na aksyon ay isinasagawa:

  • Nagsisimula ang proyektong binuo sa Travis CI.
  • Ginagawa ang lahat ng unit, integration at end-to-end na pagsubok.

Para lamang sa code na nahuhulog sa master, ang mga sumusunod ay isinasagawa:

  • Lahat ng nabanggit sa itaas, plus...
  • Pagbuo ng imahe ng Docker batay sa kasalukuyang code, mga setting at kapaligiran.
  • Pag-deploy ng imahe sa Docker Hub.
  • Koneksyon sa production server.
  • Pag-upload ng imahe mula sa Docker Hub sa server.
  • Paghinto sa kasalukuyang lalagyan at pagsisimula ng bago batay sa bagong larawan.

Kung wala ka talagang alam tungkol sa Docker, mga larawan at mga lalagyan, huwag mag-alala. Sasabihin ko sa iyo ang lahat tungkol dito.

Ano ang CI/CD?

Ang abbreviation na CI/CD ay kumakatawan sa “continuous integration/continuous deployment.”

▍Patuloy na pagsasama

Ang tuluy-tuloy na pagsasama ay isang proseso kung saan ang mga developer ay gumagawa ng mga commit sa pangunahing source code repository ng proyekto (karaniwan ay isang sangay master). Kasabay nito, ang kalidad ng code ay sinisiguro sa pamamagitan ng awtomatikong pagsubok.

▍Patuloy na pag-deploy

Ang tuluy-tuloy na pag-deploy ay ang madalas, automated na pag-deploy ng code sa produksyon. Ang pangalawang bahagi ng CI/CD acronym ay minsan ay binabaybay bilang "tuloy-tuloy na paghahatid." Ito ay karaniwang kapareho ng "tuloy-tuloy na pag-deploy", ngunit ang "patuloy na paghahatid" ay nagpapahiwatig ng pangangailangang manu-manong kumpirmahin ang mga pagbabago bago simulan ang proseso ng pag-deploy ng proyekto.

Pagsisimula

Ang app na ginamit ko upang matutunan ang lahat ng ito ay tinatawag Tandaan. Ito ay isang proyekto sa web na aking ginagawa, na idinisenyo para sa pagkuha ng mga tala. Noong una sinubukan kong gawin JAMStack-proyekto, o isang front-end na application lamang na walang server, upang samantalahin ang karaniwang pagho-host at mga kakayahan sa pag-deploy ng proyekto na inaalok nito netlify. Habang lumalago ang pagiging kumplikado ng application, kailangan kong likhain ang panig ng server nito, na nangangahulugang kakailanganin kong bumalangkas ng sarili kong diskarte para sa awtomatikong pagsasama at awtomatikong pag-deploy ng proyekto.

Sa aking kaso, ang application ay isang Express server na tumatakbo sa kapaligiran ng Node.js, na naghahatid ng isang solong-pahinang React application at sumusuporta sa isang secure na server-side API. Ang arkitektura na ito ay sumusunod sa diskarte na makikita sa ito Gabay sa pagpapatunay ng buong stack.

Kinunsulta ko sa другом, na isang dalubhasa sa automation, at tinanong siya kung ano ang kailangan kong gawin para gumana ang lahat sa paraang gusto ko. Binigyan niya ako ng ideya kung ano dapat ang hitsura ng isang awtomatikong daloy ng trabaho, na nakabalangkas sa seksyong Mga Layunin ng artikulong ito. Nangangahulugan ang pagkakaroon ng mga layuning ito na kailangan kong malaman kung paano gamitin ang Docker.

Manggagawa sa pantalan

Ang Docker ay isang tool na, salamat sa teknolohiya ng containerization, ay nagbibigay-daan sa mga application na madaling maipamahagi, ma-deploy at tumakbo sa parehong kapaligiran, kahit na ang Docker platform mismo ay tumatakbo sa iba't ibang mga kapaligiran. Una, kailangan kong makuha ang aking mga kamay sa mga tool ng command line ng Docker (CLI). pagtuturo Ang gabay sa pag-install ng Docker ay hindi matatawag na napakalinaw at naiintindihan, ngunit mula dito maaari mong malaman na upang gawin ang unang hakbang sa pag-install, kailangan mong i-download ang Docker Desktop (para sa Mac o Windows).

Ang Docker Hub ay halos pareho sa GitHub para sa git repository, o registry npm para sa mga pakete ng JavaScript. Ito ay isang online na imbakan para sa mga imahe ng Docker. Ito ang kinokonekta ng Docker Desktop.

Kaya, upang makapagsimula sa Docker, kailangan mong gawin ang dalawang bagay:

Pagkatapos nito, maaari mong suriin kung gumagana ang Docker CLI sa pamamagitan ng pagpapatakbo ng sumusunod na command upang suriin ang bersyon ng Docker:

docker -v

Susunod, mag-log in sa Docker Hub sa pamamagitan ng pagpasok ng iyong username at password kapag tinanong:

docker login

Upang magamit ang Docker, dapat mong maunawaan ang mga konsepto ng mga larawan at lalagyan.

▍Mga larawan

Ang isang imahe ay isang bagay tulad ng isang blueprint na naglalaman ng mga tagubilin para sa pag-assemble ng lalagyan. Ito ay isang hindi nababagong snapshot ng file system at mga setting ng application. Ang mga developer ay madaling magbahagi ng mga larawan.

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

Ang utos na ito ay maglalabas ng isang talahanayan na may sumusunod na header:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

Susunod na titingnan natin ang ilang mga halimbawa ng mga utos sa parehong format - una ay mayroong isang utos na may komento, at pagkatapos ay isang halimbawa ng kung ano ang maaari nitong i-output.

▍Mga lalagyan

Ang container ay isang executable package na naglalaman ng lahat ng kailangan para magpatakbo ng application. Ang isang application na may ganitong diskarte ay palaging gagana nang pareho, anuman ang imprastraktura: sa isang nakahiwalay na kapaligiran at sa parehong kapaligiran. Ang punto ay ang mga pagkakataon ng parehong imahe ay inilunsad sa iba't ibang mga kapaligiran.

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

▍Mga Tag

Ang tag ay isang indikasyon ng isang partikular na bersyon ng isang larawan.

▍Isang mabilis na sanggunian sa mga utos ng Docker

Narito ang isang pangkalahatang-ideya ng ilang karaniwang ginagamit na mga utos ng Docker.

Koponan

Konteksto

epekto

pagtatayo ng docker

Larawan

Pagbuo ng isang imahe mula sa isang Dockerfile

tag ng pantalan

Larawan

Pag-tag ng larawan

docker images

Larawan

Listahan ng mga larawan

docker run

Lalagyan

Pagpapatakbo ng isang lalagyan batay sa isang imahe

tulak ng docker

Larawan

Pag-upload ng imahe sa registry

hatak ng pantalan

Larawan

Naglo-load ng isang imahe mula sa pagpapatala

docker ps

Lalagyan

Listahan ng mga lalagyan

prune ng sistema ng pantalan

Larawan/Lalagyan

Pag-alis ng mga hindi nagamit na lalagyan at larawan

▍Dockerfile

Alam ko kung paano magpatakbo ng isang production application nang lokal. Mayroon akong configuration ng Webpack na idinisenyo upang bumuo ng isang handa na React na application. Susunod, mayroon akong utos na magsisimula ng server na nakabatay sa Node.js sa port 5000. Mukhang ganito:

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

Dapat tandaan na wala akong halimbawang aplikasyon para sa materyal na ito. Ngunit dito, para sa mga eksperimento, magagawa ang anumang simpleng Node application.

Upang magamit ang lalagyan, kakailanganin mong magbigay ng mga tagubilin sa Docker. Ginagawa ito sa pamamagitan ng isang file na tinatawag Dockerfile, na matatagpuan sa root directory ng proyekto. Ang file na ito, sa una, ay tila hindi maintindihan.

Ngunit ang nilalaman nito ay naglalarawan lamang, na may mga espesyal na utos, isang bagay na katulad ng pagse-set up ng isang kapaligiran sa pagtatrabaho. Narito ang ilan sa mga utos na ito:

  • MULA SA — Ang utos na ito ay nagsisimula ng isang file. Tinutukoy nito ang batayang imahe kung saan itinayo ang lalagyan.
  • KOPYA — Pagkopya ng mga file mula sa isang lokal na pinagmulan patungo sa isang lalagyan.
  • WORKDIR — Pagtatakda ng gumaganang direktoryo para sa mga sumusunod na utos.
  • RUN - Patakbuhin ang mga utos.
  • I-expose — Mga setting ng port.
  • PASUKAN — Indikasyon ng utos na isasagawa.

Dockerfile maaaring ganito ang hitsura:

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

Depende sa batayang larawang pipiliin mo, maaaring kailanganin mong mag-install ng mga karagdagang dependency. Ang katotohanan ay ang ilang mga batayang larawan (tulad ng Node Alpine Linux) ay nilikha na may layuning gawing compact ang mga ito hangga't maaari. Bilang resulta, maaaring wala silang ilan sa mga programang inaasahan mo.

▍Pagbuo, pag-tag at pagpapatakbo ng lalagyan

Ang lokal na pagpupulong at paglulunsad ng lalagyan ay pagkatapos namin Dockerfile, ang mga gawain ay medyo simple. Bago mo itulak ang imahe sa Docker Hub, kailangan mong subukan ito nang lokal.

▍Assembly

Una kailangan mong mangolekta isang imahe, pagtukoy ng pangalan at, opsyonal, isang tag (kung hindi tinukoy ang isang tag, awtomatikong magtatalaga ang system ng tag sa larawan latest).

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

Pagkatapos patakbuhin ang command na ito, maaari mong panoorin ang Docker na bumuo ng imahe.

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

Maaaring tumagal ng ilang minuto ang build - depende ang lahat sa kung gaano karaming mga dependency ang mayroon ka. Kapag kumpleto na ang build, maaari mong patakbuhin ang command docker images at tingnan ang paglalarawan ng iyong bagong larawan.

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

▍Ilunsad

Ang imahe ay nilikha. Nangangahulugan ito na maaari kang magpatakbo ng isang lalagyan batay dito. Dahil gusto kong ma-access ang application na tumatakbo sa container sa localhost:5000, ako, sa kaliwang bahagi ng pares 5000:5000 sa susunod na command na naka-install 5000. Sa kanang bahagi ay ang container port.

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

Ngayon na ang lalagyan ay nilikha at tumatakbo, maaari mong gamitin ang command docker ps upang tingnan ang impormasyon tungkol sa lalagyan na ito (o maaari mong gamitin ang command docker ps -a, na nagpapakita ng impormasyon tungkol sa lahat ng mga lalagyan, hindi lamang sa mga tumatakbo).

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

Kung pupunta ka ngayon sa address localhost:5000 — makakakita ka ng page ng tumatakbong application na eksaktong kapareho ng page ng application na tumatakbo sa production environment.

▍Pag-tag at pag-publish

Upang magamit ang isa sa mga nilikhang larawan sa production server, kailangan nating ma-download ang larawang ito mula sa Docker Hub. Nangangahulugan ito na kailangan mo munang gumawa ng repository para sa proyekto sa Docker Hub. Pagkatapos nito, magkakaroon tayo ng isang lugar kung saan maaari nating ipadala ang imahe. Kailangang palitan ang pangalan ng imahe upang magsimula ang pangalan nito sa aming username sa Docker Hub. Dapat itong sundan ng pangalan ng repositoryo. Anumang tag ay maaaring ilagay sa dulo ng pangalan. Nasa ibaba ang isang halimbawa ng pagbibigay ng pangalan sa mga larawan gamit ang scheme na ito.

Ngayon ay maaari kang bumuo ng imahe gamit ang isang bagong pangalan at patakbuhin ang command docker push para itulak ito sa repositoryo ng 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

Kung magiging maayos ang lahat, magiging available ang larawan sa Docker Hub at madaling ma-upload sa server o mailipat sa ibang mga developer.

Mga susunod na hakbang

Sa ngayon, na-verify na namin na ang application, sa anyo ng isang Docker container, ay tumatakbo nang lokal. Na-upload namin ang lalagyan sa Docker Hub. Ang lahat ng ito ay nangangahulugan na nakagawa na tayo ng napakahusay na pag-unlad patungo sa ating layunin. Ngayon ay kailangan nating lutasin ang dalawa pang tanong:

  • Pagse-set up ng CI tool para sa pagsubok at pag-deploy ng code.
  • Pagse-set up ng production server para ma-download at mapatakbo nito ang aming code.

Sa aming kaso, ginagamit namin Travis CI. Bilang isang server - DitigalOcean.

Dapat tandaan na dito maaari kang gumamit ng isa pang kumbinasyon ng mga serbisyo. Halimbawa, sa halip na Travis CI, maaari mong gamitin ang CircleCI o Github Actions. At sa halip na DigitalOcean - AWS o Linode.

Nagpasya kaming makipagtulungan sa Travis CI, at mayroon na akong na-configure sa serbisyong ito. Samakatuwid, ngayon ay maikling pag-uusapan ko kung paano ihanda ito para sa trabaho.

Travis CI

Ang Travis CI ay isang tool para sa pagsubok at pag-deploy ng code. Hindi ko nais na pumunta sa mga intricacies ng pag-set up ng Travis CI, dahil ang bawat proyekto ay natatangi, at hindi ito magdadala ng maraming benepisyo. Ngunit sasakupin ko ang mga pangunahing kaalaman upang makapagsimula ka kung magpasya kang gamitin ang Travis CI. Pipiliin mo man ang Travis CI, CircleCI, Jenkins, o iba pa, ang mga katulad na paraan ng pagsasaayos ay gagamitin sa lahat ng dako.

Upang makapagsimula sa Travis CI, pumunta sa website ng proyekto at gumawa ng account. Pagkatapos ay isama ang Travis CI sa iyong GitHub account. Kapag nagse-set up ng system, kakailanganin mong tukuyin ang repositoryo kung saan mo gustong i-automate ang trabaho at paganahin ang pag-access dito. (Gumagamit ako ng GitHub, ngunit sigurado ako na ang Travis CI ay maaaring isama sa BitBucket, at GitLab, at iba pang katulad na mga serbisyo).

Sa tuwing magsisimula ang Travis CI, inilulunsad ang server, na isinasagawa ang mga utos na tinukoy sa file ng pagsasaayos, kabilang ang pag-deploy ng kaukulang mga sangay ng repositoryo.

▍Ikot ng buhay ng trabaho

Tinawag ang file ng pagsasaayos ng Travis CI .travis.yml at naka-imbak sa direktoryo ng ugat ng proyekto, ay sumusuporta sa konsepto ng mga kaganapan ikot ng buhay mga gawain. Ang mga kaganapang ito ay nakalista sa pagkakasunud-sunod kung saan nangyari ang mga ito:

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

▍Pagsubok

Sa configuration file, iko-configure ko ang lokal na Travis CI server. Pinili ko ang Node 12 bilang wika at sinabi sa system na i-install ang mga dependency na kinakailangan upang magamit ang Docker.

Lahat ng nakalista sa .travis.yml, ay isasagawa kapag ang lahat ng pull request ay ginawa sa lahat ng sangay ng repository, maliban kung tinukoy. Ito ay isang kapaki-pakinabang na tampok dahil nangangahulugan ito na maaari naming subukan ang lahat ng code na papasok sa repositoryo. Ito ay nagpapaalam sa iyo kung ang code ay handa nang isulat sa sangay. master, at kung masisira nito ang proseso ng pagbuo ng proyekto. Sa pandaigdigang pagsasaayos na ito, lokal kong ini-install ang lahat, pinapatakbo ang server ng Webpack dev sa background (ito ay isang tampok ng aking daloy ng trabaho), at nagpapatakbo ng mga pagsubok.

Kung gusto mong magpakita ang iyong repository ng mga badge na nagpapahiwatig ng saklaw ng pagsubok, dito Makakahanap ka ng mga maikling tagubilin sa paggamit ng Jest, Travis CI at Coveralls upang kolektahin at ipakita ang impormasyong ito.

Kaya narito ang nilalaman ng file .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

Dito nagtatapos ang mga pagkilos na ginagawa para sa lahat ng sangay ng repositoryo at para sa mga pull request.

▍Pag-deploy

Batay sa pag-aakalang matagumpay na nakumpleto ang lahat ng automated na pagsubok, maaari naming, na opsyonal, i-deploy ang code sa production server. Dahil gusto naming gawin ito para lamang sa code mula sa sangay master, binibigyan namin ang system ng naaangkop na mga tagubilin sa mga setting ng deployment. Bago mo subukang gamitin ang code na titingnan namin sa susunod sa iyong proyekto, nais kong balaan ka na dapat ay mayroon kang aktwal na script na tinatawag para sa pag-deploy.

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

Ang deployment script ay lumulutas ng dalawang problema:

  • Buuin, i-tag at ipadala ang larawan sa Docker Hub gamit ang isang tool na CI (sa aming kaso, Travis CI).
  • Nilo-load ang imahe sa server, pinahinto ang lumang container at nagsisimula ng bago (sa aming kaso, tumatakbo ang server sa DigitalOcean platform).

Una, kailangan mong mag-set up ng isang awtomatikong proseso para sa pagbuo, pag-tag, at pagtulak ng larawan sa Docker Hub. Ang lahat ng ito ay halos kapareho sa kung ano ang nagawa na namin nang manu-mano, maliban na kailangan namin ng diskarte para sa pagtatalaga ng mga natatanging tag sa mga larawan at pag-automate ng mga pag-login. Nahirapan ako sa ilang detalye ng script ng deployment, tulad ng diskarte sa pag-tag, pag-login, pag-encode ng SSH key, pagtatatag ng koneksyon sa SSH. Pero sa kabutihang-palad ang aking kasintahan ay napakahusay sa bash, tulad ng maraming iba pang mga bagay. Tinulungan niya akong isulat ang script na ito.

Kaya, ang unang bahagi ng script ay ang pag-upload ng imahe sa Docker Hub. Ito ay medyo madaling gawin. Ang pamamaraan ng pag-tag na ginamit ko ay kinabibilangan ng pagsasama ng isang git hash at isang git tag, kung mayroon man. Tinitiyak nito na ang tag ay natatangi at ginagawang mas madaling matukoy ang pagpupulong kung saan ito nakabatay. DOCKER_USERNAME и DOCKER_PASSWORD ay mga variable ng kapaligiran ng user na maaaring itakda gamit ang interface ng Travis CI. Awtomatikong ipoproseso ng Travis CI ang sensitibong data upang hindi ito mahulog sa maling mga kamay.

Narito ang unang bahagi ng script 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}

Ang magiging pangalawang bahagi ng script ay ganap na nakasalalay sa kung anong host ang iyong ginagamit at kung paano nakaayos ang koneksyon dito. Sa aking kaso, dahil gumagamit ako ng Digital Ocean, ginagamit ko ang mga utos upang kumonekta sa server doctl. Kapag nagtatrabaho sa AWS, gagamitin ang utility aws, at iba pa.

Ang pag-set up ng server ay hindi partikular na mahirap. Kaya, nag-set up ako ng droplet batay sa base na imahe. Dapat pansinin na ang system na pinili ko ay nangangailangan ng isang beses na manu-manong pag-install ng Docker at isang isang beses na manu-manong paglulunsad ng Docker. Gumamit ako ng Ubuntu 18.04 upang i-install ang Docker, kaya kung gumagamit ka rin ng Ubuntu para gawin ang parehong, maaari mo lamang sundin ito simpleng gabay.

Hindi ako nagsasalita dito tungkol sa mga partikular na utos para sa serbisyo, dahil ang aspetong ito ay maaaring mag-iba nang malaki sa iba't ibang mga kaso. Magbibigay lang ako ng pangkalahatang plano ng aksyon na isasagawa pagkatapos kumonekta sa pamamagitan ng SSH sa server kung saan ipapakalat ang proyekto:

  • Kailangan nating hanapin ang lalagyan na kasalukuyang tumatakbo at ihinto ito.
  • Pagkatapos ay kailangan mong maglunsad ng bagong lalagyan sa background.
  • Kakailanganin mong itakda ang lokal na port ng server sa 80 - ito ay magbibigay-daan sa iyo upang ipasok ang site sa isang address tulad ng example.com, nang hindi tinukoy ang port, sa halip na gumamit ng isang address tulad ng example.com:5000.
  • Panghuli, kailangan mong tanggalin ang lahat ng lumang lalagyan at larawan.

Narito ang pagpapatuloy ng script.

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

Ang ilang mga bagay na dapat bigyang pansin

Posible na kapag kumonekta ka sa server sa pamamagitan ng SSH mula sa Travis CI, makakakita ka ng babala na pipigil sa iyong magpatuloy sa pag-install dahil maghihintay ang system para sa tugon ng user.

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

Natutunan ko na ang isang string key ay maaaring i-encode sa base64 upang i-save ito sa isang form kung saan maaari itong maginhawa at mapagkakatiwalaang magtrabaho kasama. Sa yugto ng pag-install, maaari mong i-decode ang pampublikong key at isulat ito sa isang file known_hosts upang maalis ang error sa itaas.

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

Sa pagsasagawa, ang utos na ito ay maaaring magmukhang ganito:

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

At narito ang ginagawa nito - isang base64 na naka-encode na string:

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

Narito ang utos na nabanggit sa itaas

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

Ang parehong diskarte ay maaaring gamitin sa isang pribadong key kapag nagtatatag ng isang koneksyon, dahil maaaring kailangan mo ng isang pribadong key upang ma-access ang server. Kapag nagtatrabaho gamit ang susi, kailangan mo lang tiyakin na ito ay ligtas na nakaimbak sa isang variable ng kapaligiran ng Travis CI at hindi ito ipinapakita kahit saan.

Ang isa pang dapat tandaan ay maaaring kailanganin mong patakbuhin ang buong script ng deployment bilang isang linya, halimbawa - kasama doctl. Maaaring mangailangan ito ng dagdag na pagsisikap.

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

TLS/SSL at Load Balancing

Matapos kong gawin ang lahat ng nabanggit sa itaas, ang huling problema na naranasan ko ay ang server ay walang SSL. Dahil gumagamit ako ng Node.js server, para mapilitan работать reverse proxy Nginx at Let's Encrypt, kailangan mong mag-tinker ng marami.

Talagang ayaw kong gawin nang manu-mano ang lahat ng pagsasaayos ng SSL na ito, kaya gumawa na lang ako ng load balancer at naitala ang mga detalye nito sa DNS. Sa kaso ng DigitalOcean, halimbawa, ang paggawa ng auto-renewing self-signed certificate sa load balancer ay isang simple, libre at mabilis na pamamaraan. Ang diskarte na ito ay may karagdagang benepisyo na ginagawang napakadaling mag-set up ng SSL sa maraming server na tumatakbo sa likod ng isang load balancer kung kinakailangan. Pinapayagan nito ang mga server mismo na huwag "mag-isip" tungkol sa SSL, ngunit sa parehong oras ay gamitin ang port gaya ng dati 80. Kaya ang pagse-set up ng SSL sa isang load balancer ay mas madali at mas maginhawa kaysa sa mga alternatibong paraan ng pag-set up ng SSL.

Ngayon ay maaari mong isara ang lahat ng mga port sa server na tumatanggap ng mga papasok na koneksyon - maliban sa port 80, ginagamit upang makipag-ugnayan sa load balancer, at sa port 22 para sa SSH. Bilang resulta, ang pagtatangka na direktang ma-access ang server sa anumang port maliban sa dalawang ito ay mabibigo.

Mga resulta ng

Pagkatapos kong gawin ang lahat ng pinag-usapan ko sa materyal na ito, hindi na ako natakot sa platform ng Docker o ng mga konsepto ng automated CI/CD chain. Nagawa kong mag-set up ng tuluy-tuloy na integration chain, kung saan sinusuri ang code bago ito mapunta sa produksyon at ang code ay awtomatikong na-deploy sa server. Ang lahat ng ito ay medyo bago pa rin sa akin, at sigurado akong may mga paraan upang mapabuti ang aking automated na daloy ng trabaho at gawin itong mas mahusay. Kaya kung mayroon kang anumang mga ideya sa bagay na ito, mangyaring ipaalam sa akin. sa akin alam. Umaasa ako na ang artikulong ito ay nakatulong sa iyo sa iyong mga pagsisikap. Gusto kong maniwala na pagkatapos basahin ito, natutunan mo ang lahat ng natutunan ko habang inaalam ang lahat ng pinag-usapan ko dito.

PS Sa ating palengke may isang imahe Manggagawa sa pantalan, na maaaring mai-install sa isang pag-click. Maaari mong suriin ang pagpapatakbo ng mga lalagyan sa VPS. Lahat ng mga bagong kliyente ay binibigyan ng 3 araw ng pagsubok nang walang bayad.

Minamahal na mambabasa! Gumagamit ka ba ng mga teknolohiyang CI/CD sa iyong mga proyekto?

Paglikha ng CI/CD chain at pag-automate ng trabaho sa Docker

Pinagmulan: www.habr.com

Magdagdag ng komento