Docker ile CI/CD zinciri oluşturma ve çalışmayı otomatikleştirme

İlk web sitelerimi 90'ların sonlarında yazdım. O zamanlar bunları çalışır duruma getirmek çok kolaydı. Bazı paylaşılan barındırmalarda bir Apache sunucusu vardı, bu sunucuya FTP aracılığıyla şöyle bir şey yazarak giriş yapabilirsiniz: ftp://ftp.example.com. Daha sonra adınızı ve şifrenizi girmeniz ve dosyaları sunucuya yüklemeniz gerekiyordu. Farklı zamanlar vardı, o zamanlar her şey şimdi olduğundan daha basitti.

Docker ile CI/CD zinciri oluşturma ve çalışmayı otomatikleştirme

O zamandan bu yana geçen yirmi yılda her şey çok değişti. Web siteleri daha karmaşık hale geldi; üretime geçmeden önce bir araya getirilmesi gerekiyor. Tek bir sunucu, yük dengeleyicilerin arkasında çalışan birçok sunucu haline geldi ve sürüm kontrol sistemlerinin kullanımı yaygınlaştı.

Kişisel projem için özel bir konfigürasyonum vardı. Ve tek bir eylemi gerçekleştirerek siteyi üretimde dağıtma becerisine ihtiyacım olduğunu biliyordum: bir şubeye kod yazmak master GitHub'da. Ek olarak, küçük web uygulamamın çalışmasını sağlamak için büyük bir Kubernetes kümesini yönetmek, Docker Swarm teknolojisini kullanmak veya bölmeler, aracılar ve diğer her türden içeren bir sunucu filosunu sürdürmek istemediğimi biliyordum. karmaşıklıklar. İşi olabildiğince kolaylaştırma hedefine ulaşmak için CI/CD'ye aşina olmam gerekiyordu.

Küçük bir projeniz varsa (bu durumda bir Node.js projesi) ve bu projenin dağıtımını nasıl otomatikleştireceğinizi bilmek, aynı zamanda depoda depolananların üretimde işe yarayanlarla tam olarak eşleştiğinden emin olmak istiyorsanız, o zaman ben Bu makalenin ilginizi çekebileceğini düşünüyorum.

Önkoşullar

Bu makalenin okuyucusunun komut satırı ve Bash komut dosyaları yazma konusunda temel bilgiye sahip olması beklenmektedir. Ayrıca hesaplara ihtiyacı olacak Travis C.I. и Docker Hub'ı.

Amacı

Bu makalenin koşulsuz olarak “öğretici” olarak adlandırılabileceğini söylemeyeceğim. Bu daha çok öğrendiklerimden bahsettiğim ve tek bir otomatik geçişte gerçekleştirilen kodu test etmek ve üretime dağıtmak için bana uygun olan süreci tanımladığım bir belgedir.

İş akışım bu şekilde sonuçlandı.

Aşağıdakiler hariç herhangi bir depo şubesine gönderilen kod için: masteraşağıdaki eylemler gerçekleştirilir:

  • Travis CI üzerine inşa edilen proje başlıyor.
  • Tüm birim, entegrasyon ve uçtan uca testler gerçekleştirilir.

Yalnızca aşağıdakilere düşen kodlar için: masteraşağıdakiler gerçekleştirilir:

  • Yukarıda bahsedilenlerin hepsi artı...
  • Geçerli koda, ayarlara ve ortama dayalı bir Docker görüntüsü oluşturma.
  • Görüntüyü Docker Hub'a dağıtma.
  • Üretim sunucusuna bağlantı.
  • Docker Hub'dan sunucuya imaj yükleme.
  • Geçerli kapsayıcının durdurulması ve yeni görüntüye göre yenisinin başlatılması.

Docker, görüntüler ve kapsayıcılar hakkında kesinlikle hiçbir şey bilmiyorsanız endişelenmeyin. Sana her şeyi anlatacağım.

CI/CD nedir?

CI/CD kısaltması "sürekli entegrasyon/sürekli dağıtım" anlamına gelir.

▍Sürekli entegrasyon

Sürekli entegrasyon, geliştiricilerin projenin ana kaynak kodu deposuna (genellikle bir şube) taahhütte bulunduğu bir süreçtir. master). Aynı zamanda kodun kalitesi otomatik testlerle sağlanır.

▍Sürekli dağıtım

Sürekli dağıtım, kodun üretime sık sık otomatik olarak dağıtılmasıdır. CI/CD kısaltmasının ikinci kısmı bazen "sürekli dağıtım" olarak yazılır. Bu temelde "sürekli dağıtım" ile aynıdır ancak "sürekli dağıtım", proje dağıtım sürecine başlamadan önce değişikliklerin manuel olarak onaylanması ihtiyacını ifade eder.

Başlarken

Bütün bunları öğrendiğim uygulamanın adı Not Al. Bu üzerinde çalıştığım, not almak için tasarlanmış bir web projesi. İlk başta yapmaya çalıştım JAMYığını-project veya sunduğu standart barındırma ve proje dağıtım özelliklerinden yararlanmak için yalnızca sunucusuz bir ön uç uygulama netleştir. Uygulamanın karmaşıklığı arttıkça sunucu bölümünü oluşturmam gerekiyordu; bu da projenin otomatik entegrasyonu ve otomatik dağıtımı için kendi stratejimi formüle etmem gerektiği anlamına geliyordu.

Benim durumumda uygulama, Node.js ortamında çalışan, tek sayfalı bir React uygulamasına hizmet eden ve güvenli bir sunucu tarafı API'sini destekleyen bir Express sunucusudur. Bu mimari şurada bulunabilecek stratejiyi takip eder: bu Tam yığın kimlik doğrulama kılavuzu.

danıştım другомOtomasyon uzmanı olan , her şeyin istediğim gibi çalışması için ne yapmam gerektiğini sordu. Bana bu makalenin Hedefler bölümünde özetlenen otomatik bir iş akışının nasıl görünmesi gerektiği fikrini verdi. Bu hedeflere sahip olmak, Docker'ı nasıl kullanacağımı bulmam gerektiği anlamına geliyordu.

liman işçisi

Docker, konteynerizasyon teknolojisi sayesinde, Docker platformunun kendisi farklı ortamlarda çalışsa bile uygulamaların kolayca dağıtılmasına, devreye alınmasına ve aynı ortamda çalıştırılmasına olanak tanıyan bir araçtır. İlk önce Docker komut satırı araçlarını (CLI) kullanmam gerekiyordu. Talimat Docker kurulum kılavuzunun çok açık ve anlaşılır olduğu söylenemez, ancak ilk kurulum adımını atmak için Docker Masaüstünü (Mac veya Windows için) indirmeniz gerektiğini ondan öğrenebilirsiniz.

Docker Hub kabaca aynı şeydir GitHub git depoları veya kayıt defteri için npm JavaScript paketleri için. Bu, Docker görüntüleri için çevrimiçi bir depodur. Docker Desktop'ın bağlandığı şey budur.

Yani Docker'ı kullanmaya başlamak için iki şey yapmanız gerekir:

Bundan sonra Docker sürümünü kontrol etmek için aşağıdaki komutu çalıştırarak Docker CLI’nin çalışıp çalışmadığını kontrol edebilirsiniz:

docker -v

Ardından, istendiğinde kullanıcı adınızı ve şifrenizi girerek Docker Hub'da oturum açın:

docker login

Docker'ı kullanmak için görüntü ve kapsayıcı kavramlarını anlamalısınız.

▍Resimler

Görüntü, kabın montajına ilişkin talimatları içeren plan gibi bir şeydir. Bu, uygulamanın dosya sisteminin ve ayarlarının değişmez bir anlık görüntüsüdür. Geliştiriciler görüntüleri kolayca paylaşabilir.

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

Bu komut aşağıdaki başlığa sahip bir tablonun çıktısını alacaktır:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

Daha sonra aynı formattaki bazı komut örneklerine bakacağız - önce yorum içeren bir komut var, sonra da bunun ne çıktı verebileceğine dair bir örnek var.

▍Konteynerler

Konteyner, bir uygulamayı çalıştırmak için gereken her şeyi içeren yürütülebilir bir pakettir. Bu yaklaşıma sahip bir uygulama, altyapıdan bağımsız olarak her zaman aynı şekilde çalışacaktır: izole bir ortamda ve aynı ortamda. Mesele şu ki, aynı görüntünün örnekleri farklı ortamlarda başlatılıyor.

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

▍Etiketler

Etiket, bir görselin belirli bir sürümünün göstergesidir.

▍Docker komutlarına hızlı bir referans

Burada yaygın olarak kullanılan bazı Docker komutlarına genel bir bakış yer almaktadır.

Ekip

Bağlam

Eylem

liman işçisi inşa

görüntü

Dockerfile'dan görüntü oluşturma

liman işçisi etiketi

görüntü

Resim etiketleme

docker görüntüleri

görüntü

Resimleri listeleme

docker koşmak

konteyner

Bir görüntüyü temel alan bir kapsayıcıyı çalıştırma

liman işçisi itme

görüntü

Kayıt defterine bir resim yükleme

liman işçisi çekme

görüntü

Kayıt defterinden bir resim yükleniyor

docker ps

konteyner

Kapsayıcıları listeleme

docker sistemi budama

Görüntü/Konteyner

Kullanılmayan kapsayıcıları ve görüntüleri kaldırma

▍Docker dosyası

Bir üretim uygulamasının yerel olarak nasıl çalıştırılacağını biliyorum. Hazır bir React uygulaması oluşturmak için tasarlanmış bir Webpack yapılandırmam var. Daha sonra, bağlantı noktasında Node.js tabanlı bir sunucuyu başlatan bir komutum var. 5000. Şuna benziyor:

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

Bu materyal için örnek bir uygulamamın olmadığını belirtelim. Ancak burada deneyler için herhangi bir basit Node uygulaması işe yarayacaktır.

Container'ı kullanabilmek için Docker'a talimat vermeniz gerekecektir. Bu, adlı bir dosya aracılığıyla yapılır. Dockerfile, projenin kök dizininde bulunur. Bu dosya ilk bakışta oldukça anlaşılmaz görünüyor.

Ancak içerdiği şey, özel komutlarla, yalnızca çalışma ortamı kurmaya benzer bir şeyi anlatır. İşte bu komutlardan bazıları:

  • DAN — Bu komut bir dosyayı başlatır. Kabın oluşturulduğu temel görüntüyü belirtir.
  • KOPYA — Dosyaların yerel bir kaynaktan bir konteynere kopyalanması.
  • İŞ DİREKTÖRÜ — Aşağıdaki komutlar için çalışma dizinini ayarlama.
  • KOŞMAK - Komutları çalıştırın.
  • MARUZ BIRAKMAK — Bağlantı noktası ayarları.
  • GİRİŞ NOKTASI — Yürütülecek komutun göstergesi.

Dockerfile şöyle görünebilir:

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

Seçtiğiniz temel görüntüye bağlı olarak ek bağımlılıklar yüklemeniz gerekebilir. Gerçek şu ki, bazı temel görüntüler (Node Alpine Linux gibi) onları mümkün olduğunca kompakt hale getirmek amacıyla yaratılmıştır. Sonuç olarak beklediğiniz programlardan bazıları onlarda olmayabilir.

▍Konteynerin oluşturulması, etiketlenmesi ve çalıştırılması

Konteynerin yerel montajı ve lansmanı bizden sonradır. Dockerfile, görevler oldukça basit. Görüntüyü Docker Hub'a göndermeden önce yerel olarak test etmeniz gerekir.

▍Montaj

İlk önce toplamanız gerekiyor образ, bir ad ve isteğe bağlı olarak bir etiket belirterek (etiket belirtilmezse sistem görsele otomatik olarak bir etiket atayacaktır) latest).

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

Bu komutu çalıştırdıktan sonra Docker'ın imajı oluşturmasını izleyebilirsiniz.

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

Derleme birkaç dakika sürebilir; bu tamamen kaç bağımlılığa sahip olduğunuza bağlıdır. Derleme tamamlandıktan sonra komutu çalıştırabilirsiniz. docker images ve yeni görüntünüzün açıklamasına bakın.

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

▍Başlat

Görüntü oluşturuldu. Bu, buna dayalı olarak bir konteyner çalıştırabileceğiniz anlamına gelir. Çünkü konteynerde çalışan uygulamaya şu adresten erişebilmek istiyorum: localhost:5000, ben, çiftin sol tarafında 5000:5000 yüklü bir sonraki komutta 5000. Sağ tarafta konteyner limanı var.

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

Artık konteyner oluşturulduğuna ve çalıştığına göre şu komutu kullanabilirsiniz: docker ps bu kapsayıcı hakkındaki bilgilere bakmak için (veya komutu kullanabilirsiniz) docker ps -a, yalnızca çalışan konteynerler hakkında değil, tüm konteynerler hakkındaki bilgileri görüntüler).

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

Şimdi adrese giderseniz localhost:5000 — çalışan bir uygulamanın, üretim ortamında çalışan bir uygulamanın sayfasıyla tamamen aynı görünen bir sayfasını görebilirsiniz.

▍Etiketleme ve yayınlama

Oluşturulan imajlardan birini üretim sunucusunda kullanabilmemiz için bu imajı Docker Hub’dan indirebilmemiz gerekiyor. Bu, öncelikle Docker Hub'da proje için bir repository oluşturmanız gerektiği anlamına gelir. Bundan sonra imajı gönderebileceğimiz bir yerimiz olacak. Görüntünün, adı Docker Hub kullanıcı adımızla başlayacak şekilde yeniden adlandırılması gerekiyor. Bunu havuzun adı takip etmelidir. İsmin sonuna herhangi bir etiket yerleştirilebilir. Aşağıda bu şemayı kullanarak görüntüleri adlandırmanın bir örneği verilmiştir.

Artık görüntüyü yeni bir adla oluşturabilir ve komutu çalıştırabilirsiniz. docker push Docker Hub deposuna göndermek için.

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

Her şey yolunda giderse imaj Docker Hub’da mevcut olacak ve kolaylıkla sunucuya yüklenebilecek veya diğer geliştiricilere aktarılabilecek.

Takibin Shui

Şu ana kadar Docker konteyneri formundaki uygulamanın yerel olarak çalıştığını doğruladık. Container’ı Docker Hub’a yükledik. Bütün bunlar, hedefimize doğru çok iyi bir ilerleme kaydettiğimiz anlamına geliyor. Şimdi iki soruyu daha çözmemiz gerekiyor:

  • Kodu test etmek ve dağıtmak için bir CI aracı ayarlama.
  • Üretim sunucusunu kodumuzu indirip çalıştırabilecek şekilde ayarlama.

Bizim durumumuzda kullanıyoruz Travis C.I.. Sunucu olarak - DitigalOcean.

Burada başka bir hizmet kombinasyonunu kullanabileceğiniz unutulmamalıdır. Örneğin Travis CI yerine CircleCI veya Github Actions'ı kullanabilirsiniz. Ve DigitalOcean yerine - AWS veya Linode.

Travis CI ile çalışmaya karar verdik ve bu hizmette zaten yapılandırılmış bir şeyim var. Bu nedenle şimdi işe nasıl hazırlanacağından kısaca bahsedeceğim.

Travis C.I.

Travis CI, kodu test etmeye ve dağıtmaya yönelik bir araçtır. Her proje benzersiz olduğundan ve bu pek bir fayda getirmeyeceğinden Travis CI'yı kurmanın inceliklerine girmek istemiyorum. Ancak Travis CI'yı kullanmaya karar verirseniz başlamanız için temel bilgileri anlatacağım. Travis CI, CircleCI, Jenkins veya başka bir şeyi seçerseniz seçin, benzer yapılandırma yöntemleri her yerde kullanılacaktır.

Travis CI'yı kullanmaya başlamak için şu adrese gidin: proje sitesi ve bir hesap oluşturun. Ardından Travis CI'yı GitHub hesabınızla entegre edin. Sistemi kurarken, işi otomatikleştirmek istediğiniz havuzu belirtmeniz ve ona erişimi etkinleştirmeniz gerekecektir. (GitHub kullanıyorum ancak Travis CI'nın BitBucket, GitLab ve diğer benzer hizmetlerle entegre olabileceğinden eminim).

Travis CI her başlatıldığında, ilgili depo dallarının dağıtılması da dahil olmak üzere, yapılandırma dosyasında belirtilen komutları yürüten bir sunucu başlatılır.

▍İş yaşam döngüsü

Travis CI yapılandırma dosyası çağrıldı .travis.yml ve proje kök dizininde saklanan olay kavramını destekler yaşam döngüsü görevler. Bu olaylar meydana gelme sırasına göre listelenmiştir:

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

▍Test etme

Yapılandırma dosyasında yerel Travis CI sunucusunu yapılandıracağım. Dil olarak Node 12'yi seçtim ve sisteme Docker'ı kullanmak için gereken bağımlılıkları kurmasını söyledim.

Listelenen her şey .travis.ymlaksi belirtilmedikçe, tüm çekme istekleri havuzun tüm şubelerine yapıldığında yürütülecektir. Bu kullanışlı bir özelliktir çünkü depoya gelen tüm kodları test edebileceğimiz anlamına gelir. Bu, kodun şubeye yazılmaya hazır olup olmadığını bilmenizi sağlar. masterve proje oluşturma sürecini kesintiye uğratıp uğratmayacağı. Bu genel konfigürasyonda, her şeyi yerel olarak kuruyorum, Webpack dev sunucusunu arka planda çalıştırıyorum (bu benim iş akışımın bir özelliğidir) ve testler çalıştırıyorum.

Deponuzun test kapsamını belirten rozetler görüntülemesini istiyorsanız, burada Bu bilgileri toplamak ve görüntülemek için Jest, Travis CI ve Tulumların kullanımına ilişkin kısa talimatlar bulabilirsiniz.

İşte dosyanın içeriği .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

Deponun tüm şubeleri ve çekme istekleri için gerçekleştirilen eylemlerin sona erdiği yer burasıdır.

▍Dağıtım

Tüm otomatik testlerin başarıyla tamamlandığı varsayımına dayanarak isteğe bağlı olarak kodu üretim sunucusuna dağıtabiliriz. Bunu sadece şubeden gelen kod için yapmak istediğimiz için master, dağıtım ayarlarında sisteme uygun talimatları veriyoruz. Bundan sonra bakacağımız kodu projenizde kullanmaya çalışmadan önce, dağıtım için çağrılan gerçek bir komut dosyanızın olması gerektiği konusunda sizi uyarmak isterim.

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

Dağıtım betiği iki sorunu çözer:

  • Bir CI aracı (bizim durumumuzda Travis CI) kullanarak görüntüyü oluşturun, etiketleyin ve Docker Hub'a gönderin.
  • İmajın sunucuya yüklenmesi, eski konteynerin durdurulması ve yenisinin başlatılması (bizim durumumuzda sunucu DigitalOcean platformunda çalışmaktadır).

Öncelikle görüntüyü oluşturmak, etiketlemek ve Docker Hub'a göndermek için otomatik bir süreç ayarlamanız gerekir. Bunların hepsi, resimlere benzersiz etiketler atamak ve oturum açma işlemlerini otomatikleştirmek için bir stratejiye ihtiyacımız olması dışında, daha önce manuel olarak yaptıklarımıza çok benziyor. Dağıtım betiğinin etiketleme stratejisi, oturum açma, SSH anahtar kodlaması, SSH bağlantı kurulumu gibi bazı ayrıntılarında zorluk yaşadım. Ama neyse ki erkek arkadaşım diğer pek çok konuda olduğu gibi bash konusunda da çok iyi. Bu senaryoyu yazmama yardım etti.

Yani betiğin ilk kısmı görüntüyü Docker Hub'a yüklemektir. Bunu yapmak oldukça kolaydır. Kullandığım etiketleme şeması, varsa git hash ve git etiketinin birleştirilmesini içerir. Bu, etiketin benzersiz olmasını sağlar ve temel aldığı derlemenin tanımlanmasını kolaylaştırır. DOCKER_USERNAME и DOCKER_PASSWORD Travis CI arayüzü kullanılarak ayarlanabilen kullanıcı ortamı değişkenleridir. Travis CI hassas verileri otomatik olarak işleyerek yanlış ellere geçmesini önleyecektir.

İşte senaryonun ilk kısmı 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}

Komut dosyasının ikinci bölümünün ne olacağı tamamen hangi ana bilgisayarı kullandığınıza ve onunla bağlantının nasıl organize edildiğine bağlıdır. Benim durumumda Digital Ocean kullandığım için sunucuya bağlanmak için komutları kullanıyorum doktrin. AWS ile çalışırken yardımcı program kullanılacaktır aws, vb.

Sunucuyu kurmak özellikle zor değildi. Böylece temel görüntüyü temel alan bir damlacık oluşturdum. Seçtiğim sistemin, Docker'ın tek seferlik manuel kurulumunu ve Docker'ın tek seferlik manuel başlatılmasını gerektirdiğini belirtelim. Docker'ı yüklemek için Ubuntu 18.04'ü kullandım, dolayısıyla aynısını yapmak için Ubuntu'yu da kullanıyorsanız takip edebilirsiniz. bu basit bir rehber.

Burada hizmete yönelik belirli komutlardan bahsetmiyorum çünkü bu husus farklı durumlarda büyük ölçüde farklılık gösterebilir. Projenin konuşlandırılacağı sunucuya SSH üzerinden bağlandıktan sonra gerçekleştirilecek genel bir eylem planını vereceğim:

  • Şu anda çalışan konteyneri bulup durdurmamız gerekiyor.
  • Daha sonra arka planda yeni bir konteyner başlatmanız gerekir.
  • Sunucunun yerel bağlantı noktasını şu şekilde ayarlamanız gerekir: 80 - bu, siteye aşağıdaki gibi bir adresten girmenizi sağlayacaktır: example.comgibi bir adres kullanmak yerine bağlantı noktasını belirtmeden example.com:5000.
  • Son olarak tüm eski kapları ve görselleri silmeniz gerekiyor.

Senaryonun devamı burada.

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

Dikkat edilmesi gereken bazı şeyler

Travis CI'dan SSH üzerinden sunucuya bağlandığınızda sistem kullanıcının yanıtını bekleyeceğinden kuruluma devam etmenizi engelleyecek bir uyarı görmeniz mümkündür.

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

Bir dize anahtarının, uygun ve güvenilir bir şekilde çalışılabileceği bir biçimde kaydedilmesi için base64'te kodlanabileceğini öğrendim. Kurulum aşamasında genel anahtarın kodunu çözebilir ve bir dosyaya yazabilirsiniz. known_hosts Yukarıdaki hatadan kurtulmak için.

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

Pratikte bu komut şöyle görünebilir:

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

Ve işte ürettiği şey: base64 kodlu bir dize:

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

İşte yukarıda belirtilen komut

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

Sunucuya erişmek için özel bir anahtara ihtiyacınız olabileceğinden, bağlantı kurulurken aynı yaklaşım özel anahtar için de kullanılabilir. Anahtarla çalışırken, bunun Travis CI ortam değişkeninde güvenli bir şekilde saklandığından ve hiçbir yerde görüntülenmediğinden emin olmanız yeterlidir.

Unutulmaması gereken başka bir nokta da, dağıtım komut dosyasının tamamını örneğin tek bir satır olarak çalıştırmanız gerekebileceğidir. doctl. Bu biraz ekstra çaba gerektirebilir.

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

TLS/SSL ve Yük Dengeleme

Yukarıda bahsettiğim her şeyi yaptıktan sonra karşılaştığım son sorun sunucunun SSL olmamasıydı. Node.js sunucusu kullandığım için zorlamak için çalışma ters proxy Nginx ve Let's Encrypt'i kullanmak için çok fazla değişiklik yapmanız gerekir.

Tüm bu SSL yapılandırmasını gerçekten manuel olarak yapmak istemedim, bu yüzden bir yük dengeleyici oluşturdum ve ayrıntılarını DNS'ye kaydettim. Örneğin DigitalOcean durumunda, yük dengeleyicide otomatik olarak yenilenen, kendinden imzalı bir sertifika oluşturmak basit, ücretsiz ve hızlı bir prosedürdür. Bu yaklaşımın, gerektiğinde bir yük dengeleyicinin arkasında çalışan birden fazla sunucuda SSL kurulumunu çok kolaylaştırması gibi ek bir faydası vardır. Bu, sunucuların kendilerinin SSL hakkında "düşünmemesine", ancak aynı zamanda bağlantı noktasını her zamanki gibi kullanmasına olanak tanır 80. Dolayısıyla bir yük dengeleyicide SSL kurmak, alternatif SSL kurma yöntemlerinden çok daha kolay ve kullanışlıdır.

Artık sunucudaki bağlantı noktası hariç, gelen bağlantıları kabul eden tüm bağlantı noktalarını kapatabilirsiniz. 80, yük dengeleyiciyle ve bağlantı noktasıyla iletişim kurmak için kullanılır 22 SSH için. Sonuç olarak, bu iki bağlantı noktası dışındaki herhangi bir bağlantı noktasından sunucuya doğrudan erişme girişimi başarısız olacaktır.

sonuçlar

Bu materyalde bahsettiğim her şeyi yaptıktan sonra ne Docker platformu ne de otomatik CI/CD zincirleri kavramları beni artık korkutmadı. Kodun üretime geçmeden önce test edildiği ve kodun otomatik olarak sunucuya dağıtıldığı sürekli bir entegrasyon zinciri kurmayı başardım. Bunların hepsi benim için hala nispeten yeni ve eminim ki otomatik iş akışımı iyileştirmenin ve daha verimli hale getirmenin yolları vardır. Bu nedenle bu konuyla ilgili herhangi bir fikriniz varsa lütfen bana bildirin. bana Bilmek. Umarım bu makale çalışmalarınızda size yardımcı olmuştur. Okuduktan sonra, içinde bahsettiğim her şeyi çözerken benim öğrendiğim kadar sizin de öğrendiğinize inanmak istiyorum.

PS В нашем pazar yeri bir resim var liman işçisi, tek tıklamayla kurulabilir. Konteynerlerin çalışmasını şu adresten kontrol edebilirsiniz: VPS. Tüm yeni müşterilere 3 günlük ücretsiz test hakkı verilir.

Sevgili okuyucular! Projelerinizde CI/CD teknolojilerini kullanıyor musunuz?

Docker ile CI/CD zinciri oluşturma ve çalışmayı otomatikleştirme

Kaynak: habr.com

Yorum ekle