Написах първите си сайтове в края на 90-те години. Тогава беше много лесно да ги приведеш в работно състояние. Имаше Apache-сервер на някакъв общ хостинг, към който можеше да се свържеш по FTP, като напишеш в адресната лента на браузъра нещо подобно на ftp://ftp.example.com. След това трябваше да въведеш име и парола и да качиш файловете на сървера. Бяха различни времена, всичко беше по-просто, отколкото сега.
През последните две десетилетия всичко се е променило значително. Сайтовете станаха по-сложни, и преди да бъдат пуснати в продукция, трябва да се компилират. Един единствен сървър стана множество сървъри, работещи с балансировачи на натоварването, и стана обичайно да се използват системи за контрол на версиите.
За моя личен проект имах специална конфигурация. И знаех, че ми е нужна възможност да разгръщам сайта в продукция, с едно единствено действие: запис на кода в клон master в GitHub. Освен това, знаех, че не искам да се занимавам с управление на огромен кластер Kubernetes, или да използвам технологията Docker Swarm, или да поддържам парк от сървъри с подове, агенти и всякакви други сложности, за да осигуря работата на моето малко уеб приложение. За да постигна целта да улесня максимално работата, ми се наложи да се запозная с CI/CD.
Ако имате малък проект (в нашия случай става дума за Node.js проект) и искате да разберете как да автоматизирате разгръщането му, така че това, което се съхранява в репозитория, да съответства на това, което работи в продукция, то предполагам, че статията може да ви заинтересува.
Предварителни изисквания
Очаква се читателят на тази статия да има основни познания в работата с команден ред и написването на Bash скриптове. Освен това ще му трябват акаунти и .
Цели
Не бих казала, че тази статия може да бъде наречена безусловно "учебно ръководство". Това е по-скоро документ, в който разказвам какво съм научила и описвам удовлетворителния за мен процес на тестване и разгръщане на кода в продукция, извършван с едно автоматизирано преминаване.
Ето какъв е в крайна сметка моя работен процес.
За кода, изпратен в който и да е клон на репозитория, с изключение на master, се извършват следните действия:
- Стартира се изграждането на проекта в Travis CI.
- Изпълняват се всички модулни, интеграционни и крайни тестове.
Само за кода, който попада в master, се извършва следното:
- Всичко, което беше казано по-горе, плюс…
- Създаване на Docker образ на основата на текущия код, настройки и окружение.
- Поставяне на образа в Docker Hub.
- Свързване с производствения сървър.
- Изтегляне на образа от Docker Hub на сървъра.
- Спиране на текущия контейнер и стартиране на нов, базиран на новия образ.
Ако не знаете абсолютно нищо за Docker, образи и контейнери — не се притеснявайте. Ще ви разкажа за всичко това.
Какво е CI/CD?
Съкращението CI/CD се разшифрова като „непрекъсната интеграция/непрекъснато разпределение“.
▍Непрекъсната интеграция
Непрекъснатата интеграция е процес, при който разработчиците правят комити в основното хранилище на изходния код на проекта (обикновено в клон master). Качеството на кода се осигурява чрез автоматизирано тестване.
▍Непрекъснато разпределение
Непрекъснатото разпределение е често автоматизирано разпределение на код в производството. Втората част на съкращението CI/CD понякога се разглежда като „непрекъсната доставка“. Това, по принцип, е същото като „непрекъснато разпределение“, но „непрекъснатата доставка“ предполага необходимост от ръчно потвърждение на промените преди стартиране на процеса на разпределение на проекта.
Започване на работа
Приложението, в което аз усъществявах всичко това, се нарича . Това е уеб проект, над който работя, предназначен за вземане на бележки. Първоначално се опитах да направя -проект, или просто фронтенд приложение без сървър, за да се възползвам от стандартните възможности за хостинг и разпределение на проекти, които предлага . С нарастваща сложност на приложението, се нуждаех от създаването на неговата сървърна част, което означаваше, че трябваше да формулирам собствена стратегия за автоматизирана интеграция и автоматизирано разпределение на проекта.
В моя случай приложението представлява Express-сървър, работещ в среда Node.js, обслужващ едностранично React приложение и поддържащ защитен сървърен API. Тази архитектура следва стратегия, която може да бъде намерена в ръководство за фуллстек автентикация.
Консултирах се с , който е експерт в автоматизацията, и го попитах какво трябва да направя, за да всичко да работи така, както ми е нужно. Той ми предложи идея как трябва да изглежда автоматизираният работен процес, описан в раздела „Цели“ на тази статия. Фактът, че си поставих подобни цели, означаваше, че трябва да разбера как да използвам Docker.
Docker
Docker е инструмент, който, благодарение на технологията за контейнеризация, позволява лесното разпространение на приложения, както и изпълнението им на една и съща среда, дори когато самата платформата Docker работи в различни среди. Първо, трябваше да си набавя инструментите за команден ред (CLI) на Docker. за инсталиране на Docker не може да се нарече много ясна и разбираема, но от нея може да се научи, че за да направите първата стъпка в инсталацията, трябва да изтеглите Docker Desktop (за Mac или Windows).
Docker Hub е нещо като за git хранилища, или регистър за JavaScript пакети. Това е онлайн хранилище за Docker изображения. Именно към него се свързва Docker Desktop.
И така, за да започнете работа с Docker, трябва да направите две неща:
- Инсталирайте .
- Регистрирайте се на .
След това можете да проверите работоспособността на Docker CLI, като изпълните следната команда за проверка на версията на Docker:
docker -vСлед това влезте в Docker Hub, като въведете, когато ви попитат, вашето потребителско име и парола:
docker loginЗа да използвате Docker, трябва да разбирате концепциите за изображения и контейнери.
▍Изображения
Изображението е нещо като план, съдържащ инструкции за изграждане на контейнер. Това е неизменяем моментен снимка на файловата система и настройките на приложението. Разработчиците могат лесно да обменят изображения.
# Вывод сведений обо всех образах
docker imagesТази команда ще изведе таблица с следния заглавие:
РЕПОЗИТОРИЙ ТАГ ID НА ИЗОБРАЖЕНИЕ СЪЗДАДЕНО РАЗМЕР
---По-нататък ще разгледаме някои примери на команди в същия формат — първо идва командата с коментар, а след това — пример за това, което тя може да изведе.
▍Контейнери
Контейнерът е изпълним пакет, който съдържа всичко необходимо за изпълнение на приложението. При такъв подход приложението ще работи по един и същи начин, независимо от инфраструктурата: в изолирана среда и в една и съща среда. Става въпрос за това, че в различни среди се стартират екземпляри на един и същи образ.
# Перечисление всех контейнеров
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
---▍Тагове
Тагът е указание за конкретна версия на образа.
▍Кратко ръководство по командите на Docker
Ето преглед на някои от често използваните команди на Docker.
Команда
Контекст
Действие
Образ
Създаване на образ от Dockerfile
Образ
Тагиране на образа
Образ
Извеждане на списък с образи
Контейнер
Стартиране на контейнер на базата на образа
Образ
Изпращане на образа в регистър
Образ
Изтегляне на образа от регистра
Контейнер
Извеждане на списък с контейнери
Образ/Контейнер
Премахване на неизползвани контейнери и образи
▍Файл Dockerfile
Знам как локално да стартирам приложението за продукция. Имам Webpack конфигурация, предназначена за компилиране на готово React приложение. След това имам команда, която стартира сървър, базиран на Node.js, на порт 5000. Изглежда ето така:
npm i # инсталиране на зависимости
npm run build # компилиране на React приложението
npm run start # стартиране на Node сървъраТрябва да отбележа, че нямам демонстрационно приложение за този материал. Но за експерименти подхожда всяко просто Node приложение.
За да ползвате контейнера, ще трябва да дадете инструкции на Docker. Това става чрез файл, наречен Dockerfile, който се намира в кореновата директория на проекта. Този файл на пръв поглед изглежда доста неразбираем.
Но това, което съдържа, всъщност описва, със специфични команди, нещо подобно на настройка на работна среда. Ето някои от тези команди:
- — Тази команда стартира файла. В нея е указан базовият образ, на базата на който се изгражда контейнерът.
- — Копиране на файлове от локален източник в контейнера.
- — Настройка на работната директория за следващите команди.
- — Изпълняване на команди.
- — Настройка на порта.
- — Указание на изпълняваната команда.
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 изпълнява сглобяването на образа.
Изпращане на контекста на сглобяване към Docker демон 2.88MB
Стъпка 1/9 : ОТ node:12-alpine
---> ...изпълнение на етапите на сглобяване...
Успешно сглобен 123456789123
Успешно тагиран <image>:<tag> Сглобяването може да отнеме няколко минути — всичко зависи от това колко зависимости имате. След завършване на сглобяването можете да изпълните командата docker images и да погледнете описанието на новия си образ.
РЕПОЗИТОРИЙ TAG IMAGE ID СЪЗДАДЕН РАЗМЕР
<image> latest 123456789123 Преди около минута 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 СЪЗДАДЕН СТАТУС PORTS NAMES
987654321234 <image> "\/bin\/sh -c 'npm run…" 6 секунди назад Up 6 секунди 0.0.0.0:5000->5000\/tcp stoic_darwin Ако сега отидете на адрес localhost:5000 , можете да видите страницата на работещото приложение, която изглежда точно така, както страницата на приложението, работещо в продукционна среда.
▍Назначаване на таг и публикуване
За да се възползвате от един от създадените образи на продукционния сървър, е необходимо да имате възможност да качите този образ от Docker Hub. Това означава, че първо трябва да създадете хранилище на Docker Hub за проекта. След това ще имате място, където да изпратите образа. Образът трябва да бъде преименуван така, че името му да започва с вашето потребителско име на Docker Hub. След това трябва да идва името на хранилището. В края на името може да има произволен таг. По-долу е показан пример за именуване на образи според тази схема.
Сега можете да съберете образа с новото му име и да изпълните командата docker push за изпращането му в хранилището на Docker Hub.
docker build -t /: .
docker tag /: /:latest
docker push /:
# На практика това може да изглежда, например, така:
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/CD решение се използва . Като сървър — .
Трябва да отбележа, че тук можете да използвате и друга комбинация от услуги. Например, вместо Travis CI можете да използвате CircleCI или Github Actions. А вместо DigitalOcean — AWS или Linode.
Решихме да работим с Travis CI и в този сервис вече имам настроено нещо. Затова сега накратко ще разкажа как да го подготвите за работа.
Travis 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 addonscache componentsbefore_installinstallbefore_scriptscriptbefore_cacheafter_success или after_failurebefore_deploydeployafter_deployafter_script
▍Тестиране
В конфигурационния файл възнамерявам да настроя локален сървър на Travis CI. За език съм избрала Node версия 12 и указах на системата да инсталира зависимостите, необходими за използване на Docker.
Всичко, изброено в .travis.yml, ще се изпълнява при всеки pull request за всички клонове на репозитория, освен ако не е указано друго. Това е полезна характеристика, тъй като означава, че можем да тестваме целия код, който постъпва в репозитория. Това позволява да знаем дали кодът е готов за запис в клона 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 requests.
▍Разгръщане
Предполагайки, че всички автоматизирани тестове са завършили успешно, можем, без да е задължително, да разположим кода на производствения сървър. Тъй като искаме да правим това само за кода от клона master, ние даваме на системата съответни инструкции в настройките за разгръщане. Преди да опитате да използвате кода в проекта си, който ще разгледаме по-нататък, искам да ви предупредя, че трябва да имате реален скрипт, който да се извиква за разгръщането.
deploy:
# Събиране на Docker контейнер и изпращането му в Docker Hub
provider: script
script: bash deploy.sh
on:
branch: masterСкриптът за разгръщане решава две задачи:
- Събиране, тагиране и изпращане на изображение в Docker Hub с помощта на CI инструмент (в нашия случай Travis CI).
- Изтегляне на изображението на сървъра, спиране на стария контейнер и стартиране на новия (в нашия случай сървърът работи на платформата DigitalOcean).
Първо, трябва да настроите автоматичния процес за събиране, тагиране и изпращане на изображение в Docker Hub. Всичко това е доста похоже на това, което вече правихме ръчно, с изключение на това, че тук ни е необходима стратегия за задаване на уникални тагове на изображенията и автоматизация на входа в системата. Имах трудности с някои детайли на скрипта за разгръщане, като стратегията за тагиране, входа в системата, кодировката на SSH ключовете и установяването на SSH връзката. Но, за щастие, моят приятел се справя много добре с bash, както и с много други неща. Той ми помогна да напиша този скрипт.
И така, първата част на скрипта е изпращането на изображение в Docker Hub. Да го направите е доста просто. Използваната от мен схема за тагиране предвижда комбиниране на git хеш и git таг, ако съществува. Това позволява да се създаде уникален таг и улеснява идентификацията на сборката, на която той се основава. 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. Аз, за инсталирането на Docker, използвах Ubuntu 18.04, затова вие, ако също използвате 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, да видите предупреждение, което няма да позволи продължаването на инсталацията, тъй като системата ще чака реакция от потребителя.
Автентичността на хоста ' ()' не може да бъде установена.
RSA ключовият отпечатък е .
Сигурни ли сте, че искате да продължите свързването (да/не)? Научих, че стринг ключът може да бъде кодиране в base64, за да се запази в такъв вид, в който с него може да се работи удобно и надеждно. На етапа на инсталацията можете да декодирате публичния ключ и да го запишете в файл known_hosts за да се отървете от гореспоменатата грешка.
echo | 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== you@example.com" | base64А ето как изглежда това, което тя извежда — стринг в кодировката base64:
MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==Ето командата, за която се спомена по-горе
install:
- echo | base64 -d >> $HOME/.ssh/known_hostsСъщият подход може да се използва и с личния ключ при установяване на връзка, тъй като за достъп до сървера може да ви бъде необходим личен ключ. При работа с ключа трябва само да осигурите безопасното му съхранение в променлива на околната среда на Travis CI и да се уверите, че не се извежда никъде.
Още едно нещо, на което си струва да обърнете внимание, е че може да се наложи да стартирате целия скрипт за разгръщане, представен в един ред, например — с помощта на doctl. Това може да изисква известни допълнителни усилия.
doctl compute ssh --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 вериги. Успях да настроя веригата за непрекъсната интеграция, по време на която се извършва тестване на кода преди да влезе в продукция и автоматично разгръщане на кода на сървъра. Всичко това ми е все още относително ново, и съм сигурна, че има начини да подобря автоматизирания си работен процес и да го направя по-ефективен. Затова, ако имате идеи по този въпрос — дайте ми знак. Надявам се, че тази статия ви е помогнала в работата. Искам да вярвам, че като я прочетете, сте научили толкова, колкото аз, докато се справях с всичко, за което пиша тук.
P.S. В нашия има образ , който се инсталира с едно кликване. Можете да проверите работата на контейнерите на . На всички нови клиенти се предоставят безплатно 3 дни за тестване.
Уважаеми читатели! Използвате ли технологии CI/CD в проектите си?
Източник: habr.com
