Oprettelse af CI/CD-kæde og automatisering af arbejde med Docker

Jeg lavede mine første hjemmesider i slutningen af 90'erne. Dengang var det meget enkelt at få dem til at fungere. Der var en Apache-server på en eller anden delt hosting, og man kunne logge ind på denne server via FTP ved at skrive noget i browserens adresselinje såsom ftp://ftp.example.com. Så skulle man indtaste sit brugernavn og kodeord og uploade filer til serveren. Tiderne var anderledes, alt var lettere dengang end nu.

Oprettelse af CI/CD-kæde og automatisering af arbejde med Docker

I de to årtier, der er gået siden, er alt blevet ret meget ændret. Hjemmesiderne er blevet mere komplekse, og før de går i produktion, skal de samles. En enkelt server er blevet til mange servere, der arbejder bag load balancere, og brugen af versionskontrolsystemer er blevet almindeligt.

Til mit personlige projekt havde jeg en speciel konfiguration. Og jeg vidste, at jeg havde brug for muligheden for hurtigt at implementere hjemmesiden i produktionen med blot én handling: at skrive koden til en gren master på GitHub. Derudover vidste jeg, at jeg ikke ønskede at håndtere et enormt Kubernetes-klynge for at få mit lille webapp til at fungere, eller bruge Docker Swarm, eller administrere en samling servere med pods, agenter og andre komplekse ting. For at nå mit mål om maksimal forenkling af arbejdet måtte jeg lære om CI/CD.

Hvis du har et lille projekt (i dette tilfælde en Node.js-projekt) og gerne vil vide, hvordan man automatiserer implementeringen af dette projekt, samtidig med at det som opbevares i depotet nøjagtigt svarer til det, der kører i produktionen, så tror jeg, at du kan finde denne artikel interessant.

Forudsætninger

Det forventes, at læseren af denne artikel har grundlæggende kendskab til at arbejde med kommandolinjen og skrive Bash-scripts. Derudover vil der være behov for konti Travis CI og Docker Hub.

Mål

Jeg vil ikke sige, at denne artikel uden forbehold kan kaldes et "vejledning." Det er nærmere et dokument, hvor jeg fortæller om, hvad jeg har lært, og beskriver den proces for testning og implementering af kode i produktionen, som jeg finder tilfredsstillende, og som udføres i et enkelt automatiseret trin.

Her er, hvordan min arbejdsproces i sidste ende så ud.

For koden sendt til enhver gren af depotet, undtagen master, udføres følgende handlinger:

  • Projektet bygges på Travis CI.
  • Alle enhedstest, integrationstest og end-to-end test køres.

Kun for koden, der falder ind master, udføres følgende:

  • Alt det, der er nævnt ovenfor, plus…
  • Bygning af et Docker-billede baseret på den nuværende kode, indstillinger og miljø.
  • Placerer billedet på Docker Hub.
  • Tilslutning til produktionsserveren.
  • Download billedet fra Docker Hub til serveren.
  • Stop den nuværende container og start en ny baseret på det nye billede.

Hvis du slet ikke ved noget om Docker, billeder og containere — ingen grund til bekymring. Jeg vil fortælle dig alt om det.

Hvad er CI/CD?

Forkortelsen CI/CD står for 'continuous integration/continuous deployment' — 'kontinuerlig integration/kontinuerlig implementering'.

▍Kontinuerlig integration

Kontinuerlig integration er en proces, hvor udviklere foretager commits til hovedlageret af kildeteksten i projektet (normalt til grenen master). Kvaliteten af koden sikres ved hjælp af automatiserede tests.

▍Kontinuerlig implementering

Kontinuerlig implementering er hyppig automatiseret implementering af koden i produktionen. Den anden del af forkortelsen CI/CD bliver nogle gange forklaret som 'continuous delivery' ('kontinuerlig levering'). Dette er i det store hele det samme som 'kontinuerlig implementering', men 'kontinuerlig levering' indebærer behovet for manuel bekræftelse af ændringerne, før processen for implementering af projektet startes.

Getting Started

Applikationen, som jeg har lært alt dette på, hedder TakeNote. Dette er et webprojekt, jeg arbejder på, designet til at tage noter. Først forsøgte jeg at lave et JAMStack-projekt, eller blot en frontend-applikation uden server, for at udnytte de standardmuligheder for hosting og implementering af projekter, som tilbydes af Netlify. I takt med at kompleksiteten af applikationen voksede, havde jeg brug for at skabe dens serverdel, hvilket betød, at jeg skulle udvikle min egen strategi for automatiseret integration og automatiseret implementering af projektet.

I mit tilfælde er applikationen en Express-server, der kører i Node.js-miljøet, betjener en enkelt-side React-applikation og understøtter et sikkert server-API. Denne arkitektur følger en strategi, man kan finde i denne vejledning til fullstack-autentifikation.

Jeg har rådført mig med en anden, som er en ekspert i automatisering, og jeg spurgte ham, hvad jeg skulle gøre for at få det hele til at fungere, som jeg ønskede. Han gav mig en idé om, hvordan den automatiserede arbejdsproces skulle se ud, som beskrevet i afsnittet 'Mål' i denne artikel. At jeg satte mig sådanne mål betød, at jeg var nødt til at finde ud af, hvordan man bruger Docker.

Docker

Docker er et værktøj, der ved hjælp af containeriseringsteknologi gør det muligt at distribuere applikationer let samt udføre deres deployment og kørsel i det samme miljø, selvom Docker-platformen kører i forskellige miljøer. For at komme i gang havde jeg brug for at få adgang til Docker Command Line Interface (CLI)-værktøjerne. Instruktionen til installation af Docker kan ikke kaldes meget klar og forståelig, men den giver information om, at for at tage det første skridt mod installation, skal man downloade Docker Desktop (til Mac eller Windows).

Docker Hub er omtrent det samme som GitHub for git-repositories, eller et register npm for JavaScript-pakker. Det er et online-repository for Docker-images. Det er til dette, Docker Desktop forbindes.

Så for at begynde at arbejde med Docker skal du gøre to ting:

Derefter kan du kontrollere, om Docker CLI fungerer ved at køre følgende kommando for at tjekke Docker-versionen:

docker -v

Derefter logger du ind på Docker Hub ved at indtaste dit brugernavn og adgangskode, når du bliver bedt om det:

docker login

For at bruge Docker skal du forstå begreberne images og containere.

▍Images

Et image er noget, der ligner en plan, der indeholder instruktioner til at bygge en container. Det er et uforanderligt snapshot af filsystemet og applikationens indstillinger. Udviklere kan nemt udveksle images.

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

Denne kommando vil give en tabel med følgende overskrift:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

Herefter vil vi se på nogle eksempler på kommandoer i samme format — først kommandoen med en kommentar, og derefter et eksempel på, hvad den kan producere.

▍Containere

En container er en eksekverbar pakke, der indeholder alt, hvad der er nødvendigt for at køre en applikation. Applikationen vil i denne tilgang altid fungere ens, uanset infrastrukturen: i et isoleret miljø og i det samme miljø. Det handler om, at der kører instanser af det samme billede i forskellige miljøer.

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

▍Tags

Et tag er en angivelse af en specifik version af et billede.

▍Kort vejledning til Docker-kommandoer

Her er et overblik over nogle ofte brugte Docker-kommandoer.

Kommandoen

Kontext

Handling

docker build

Billede

Bygning af billede fra Dockerfile

docker tag

Billede

Tagging af billede

docker images

Billede

Visning af listen over billeder

docker run

Container

Start af container baseret på billede

docker push

Billede

Upload af billede til registry

docker pull

Billede

Hentning af billede fra registry

docker ps

Container

Visning af listen over containere

docker system prune

Billede/Container

Fjernelse af ubrugte containere og billeder

▍Dockerfile

Jeg ved, hvordan jeg lokalt kan køre en applikation til produktion. Jeg har en Webpack-konfiguration, der er designet til at bygge et færdigt React-applikation. Derudover har jeg en kommando, der starter en server baseret på Node.js, på port 5000. Det ser således ud:

npm i         # installation af afhængigheder
npm run build # bygning af React-applikation
npm run start # start af Node-server

Det skal bemærkes, at jeg ikke har et eksempelapplikation til dette materiale. Men til eksperimenter kan enhver simpel Node-applikation bruges.

For at bruge containeren skal du give Docker instruktioner. Det gøres via en fil kaldet Dockerfile, som befinder sig i roden af projektmappen. Denne fil virker i starten ret uklar.

Men det, der er i den, beskriver blot, med specielle kommandoer, noget der ligner opsætningen af et arbejdsmiljø. Her er nogle af disse kommandoer:

  • FROM — Denne kommando starter filen. Den angiver det grundlæggende billede, som containeren bygges på.
  • COPY — Kopiering af filer fra en lokal kilde til containeren.
  • WORKDIR — Angivelse af arbejdsbiblioteket for følgende kommandoer.
  • RUN — Udførelse af kommandoer.
  • EXPOSE — Konfigurering af porten.
  • ENTRYPOINT — Angivelse af den kommando, der skal udføres.

Dockerfile kan se nogenlunde sådan ud:

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

Afhængigt af det valgte basisbillede kan det være nødvendigt at installere yderligere afhængigheder. Nogle basisbilleder (som Node Alpine Linux) er designet til at være så kompakte som muligt, hvilket betyder, at nogle programmer, du forventer, måske mangler.

▍Bygning, taggning og kørsel af containeren

Lokal bygning og kørsel af containeren — det er, efter vi har Dockerfile, opgaverne ret enkle. Før du sender billedet til Docker Hub, skal det testes lokalt.

▍Bygning

Først skal du bygge billede, angiv et navn og, hvis det ønskes, et tag (hvis tagget ikke angives, vil systemet automatisk tildele billedet et tag latest).

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

Efter at have udført denne kommando kan du se, hvordan Docker bygger billedet.

Sender byggetilstand til Docker daemon   2.88MB
Trin 1/9 : FRA node:12-alpine
 ---> ...udfører bygge trin...
Succesfuldt bygget 123456789123
Succesfuldt tagget <image>:<tag>

Bygningen kan tage et par minutter — det afhænger af, hvor mange afhængigheder du har. Efter bygningen kan du udføre kommandoen docker images og se beskrivelsen af dit nye billede.

REPOSITORY          TAG               IMAGE ID            CREATED              SIZE
<image>             latest            123456789123        For omtrent et minut siden   x.xxGB

▍Kørsel

Billedet er oprettet. Det betyder, at du kan starte en container baseret på det. Da jeg ønsker, at jeg skal kunne få adgang til applikationen, der kører i containeren, på adressen localhost:5000, har jeg i venstre del af paragrafen 5000:5000 i den næste kommando angivet 5000. I den højre del er der containerens port.

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

Nu, hvor containeren er oprettet og kørt, kan du bruge kommandoen docker ps for at se oplysninger om denne container (eller du kan bruge kommandoen docker ps -a, som viser oplysninger om alle containere, ikke kun de kørende).

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS                    NAMES
987654321234        <image>             "\/bin\/sh -c 'npm run…"   6 sekunder siden        Kører 6 sekunder                0.0.0.0:5000->5000\/tcp   stoic_darwin

Hvis du nu går til adressen localhost:5000 — kan du se siden af den kørende applikation, som ser nøjagtig ud som siden af applikationen, der kører i produktionsmiljøet.

▍Tildeling af tag og publicering

For to take advantage of one of the created images on the production server, we need to ensure that we have the ability to upload this image from Docker Hub. This means we first need to create a repository for the project on Docker Hub. After that, we will have a place where we can send the image. The image needs to be renamed so that its name begins with our username on Docker Hub. Following that, the repository name should follow. At the end of the name, any tag can be placed. Below is an example of naming images according to this scheme.

Now let's build the image with a new name assigned to it and execute the command docker push to send it to the Docker Hub repository.

docker build -t \/ : .
docker tag \/ : \/ :latest
docker push \/ :

# In practice, this might look, for example, like this:
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

If everything goes well, the image will be available on Docker Hub and can be easily uploaded to the server or shared with other developers.

Næste skridt

By now, we have confirmed that the application, in the form of a Docker container, works locally. We have uploaded the container to Docker Hub. All of this means that we have made significant progress towards our goal. Now we need to resolve two more questions:

  • Setting up the CI tool for testing and deploying the code.
  • Setting up the production server so it can upload and run our code.

In our case, the CI/CD solution used is Travis CI. As a server — DigitalOcean.

It should be noted that other combinations of services can also be utilized here. For example, instead of Travis CI, one could use CircleCI or GitHub Actions. And instead of DigitalOcean — AWS or Linode.

We decided to work with Travis CI, and I already have some setup configured in this service. Therefore, I will briefly explain how to prepare it for use.

Travis CI

Travis CI is a tool for testing and deploying code. I wouldn't want to go into the details of configuring Travis CI, as each project is unique, and this wouldn’t be particularly useful. But I will explain the basics that will allow you to get started if you decide to use Travis CI. Whatever you choose — Travis CI, CircleCI, Jenkins, or something else, similar configuration methods will apply.

For at komme i gang med Travis CI, skal du gå til projektets hjemmeside og oprette en konto. Derefter skal du integrere Travis CI med din GitHub-konto. Under opsætningen af systemet vil du skulle angive det repository, som du vil automatisere arbejdet med, og give adgang til det. (Jeg bruger GitHub, men jeg er sikker på, at Travis CI også kan integreres med BitBucket, GitLab og andre lignende tjenester).

Hver gang Travis CI sættes i gang, starter en server, der udfører de angivne kommandoer i konfigurationsfilen, inklusive udrulning af de relevante grene i repository'et.

▍Joblivscyklus

Konfigurationsfilen for Travis CI, som kaldes .travis.yml og som opbevares i rodmappen af projektet, understøtter konceptet for begivenheder joblivscyklus for job. Her er disse begivenheder, præsenteret i den rækkefølge, de opstår:

  • apt addons
  • cache components
  • before_install
  • installation
  • before_script
  • script
  • before_cache
  • after_success eller after_failure
  • before_deploy
  • deploy
  • after_deploy
  • after_script

▍Testning

I konfigurationsfilen vil jeg opsætte en lokal Travis CI-server. Jeg har valgt Node version 12 som sprog og angivet til systemet, at det skal installere de afhængigheder, der er nødvendige for at bruge Docker.

Alt, hvad der er angivet i .travis.yml, vil blive udført ved alle pull-anmodninger til alle grene i repository'et, medmindre andet er angivet. Dette er en nyttig funktion, da det betyder, at vi kan teste al koden, der kommer ind i repository'et. Dette sikrer, at vi ved, om koden er klar til at blive skrevet i grenen master, og om den vil forstyrre byggeprocessen for projektet. I denne globale konfiguration installerer jeg alt lokalt, kører Webpack udvikler-serveren i baggrunden (dette er en funktion i min arbejdsproces) og udfører testene.

Hvis du ønsker, at dit repository skal vise badges med information om test dækning, her kan du finde en kort vejledning til brug af Jest, Travis CI og Coveralls til at opsamle og vise disse oplysninger.

Så her er indholdet af filen .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

Her slutter de handlinger, der udføres for alle grene i repository'et og for pull-anmodninger.

▍Udrulning

Givet antagelsen om, at alle automatiserede tests er blevet gennemført med succes, kan vi, hvilket ikke er nødvendigt, udrulle koden på produktionsserveren. Da vi kun ønsker at gøre dette for koden fra grenen master, vi giver systemet de relevante instruktioner i deploymentsindstillingerne. Før du prøver at bruge koden, som vi vil gennemgå, i dit projekt, vil jeg gerne advare dig om, at du skal have et reelt script, der kaldes for deployment.

deploy:
  # Byg Docker-container og send den til Docker Hub
  provider: script
  script: bash deploy.sh
  on:
    branch: master

Deployment-scriptet løser to opgaver:

  • Bygning, tagging og upload af billedet til Docker Hub ved hjælp af CI-værktøjet (i vores tilfælde er det Travis CI).
  • Upload af billedet til serveren, stop af den gamle container og start af den nye (i vores tilfælde kører serveren på platformen DigitalOcean).

Først skal automatiseringsprocessen til bygning, tagging og upload af billedet til Docker Hub indstilles. Alt dette ligner meget det, vi tidligere har gjort manuelt, bortset fra at vi her har brug for en strategi for at tildele billederne unikke tags og automatisere login. Jeg havde nogle udfordringer med visse detaljer i deployment-scriptet, såsom tagging-strategien, login, SSH-nøglekodning og etablering af SSH-forbindelsen. Men heldigvis håndterer min kæreste bash meget godt, ligesom mange andre ting. Han hjalp mig med at skrive dette script.

Så den første del af scriptet er at sende billedet til Docker Hub. Det er ret enkelt. Den tagging-skema, jeg brugte, indebærer at kombinere git-hash med git-tag, hvis det eksisterer. Dette sikrer, at der oprettes et unikt tag og forenkler identificeringen af den build, som det er baseret på. DOCKER_USERNAME og DOCKER_PASSWORD — det er brugerdefinerede miljøvariabler, der kan angives via grænsefladen i Travis CI. Travis CI vil automatisk håndtere hemmelige oplysninger, så de ikke falder i forkert hænder.

Her er den første del af scriptet 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}

Hvordan den anden del af scriptet ser ud, afhænger helt af, hvilken hostingudbyder du bruger, og hvordan forbindelsen er organiseret. I mit tilfælde, da jeg bruger Digital Ocean, anvendes kommandoerne doctl. Ved arbejde med AWS vil værktøjet aws, og så videre.

Det var ikke særlig svært at konfigurere serverens funktion. Jeg opsatte en dråbe baseret på det grundlæggende billede. Det skal bemærkes, at det valgte system kræver én manuel installation af Docker og én manuel opstart af Docker. Jeg brugte Ubuntu 18.04 til installationen af Docker, så hvis du også bruger Ubuntu, kan du bare følge denne den enkle vejledning.

Jeg taler ikke om specifikke kommandoer til tjenesten, da dette aspekt kan variere meget i forskellige tilfælde. Jeg vil blot give en overordnet handlingsplan, der udføres efter at have tilsluttet sig serveren via SSH, hvor projektet skal implementeres:

  • Du skal finde den container, der kører i øjeblikket, og stoppe den.
  • Derefter skal du i baggrunden starte en ny container.
  • Du skal indstille den lokale servers port til 80 — dette vil gøre det muligt at tilgå webstedet på en adresse som example.com, uden at angive porten, i stedet for at bruge en adresse som example.com:5000.
  • Og endelig skal du slette alle gamle containere og billeder.

Her er fortsættelsen af scriptet.

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

Nogle ting, du skal være opmærksom på

Måske når du tilslutter til serveren via SSH fra Travis CI, vil du se en advarsel, der forhindrer dig i at fortsætte installationen, da systemet venter på brugerens reaktion.

Autenticiteten af værten '<hostname> (<IP address>)' kan ikke fastslås.
RSA nøglefingeraftryk er <key fingerprint>.
Er du sikker på, at du vil fortsætte med at tilslutte (ja/nej)?

Jeg har fundet ud af, at strengnøglen kan kodes i base64 for at gemme den i en form, der er nem at arbejde med. Under installationen kan den offentlige nøgle dekodes og skrives til filen known_hosts for at eliminere den førnævnte fejl.

echo <public key> | base64 # udskriver <den offentlige nøgle, kodet i base64>

I praksis kan denne kommando se således ud:

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

Og her er, hvordan det ser ud — en streng i base64-kodning:

123.45.67.89 ssh-rsa AAAAB3NzaC1yc2EAAAAABIwAB...

Her er kommandoen, der blev nævnt tidligere

install:
  - echo  | base64 -d >> $HOME/.ssh/known_hosts

Den samme tilgang kan anvendes med den private nøgle, når der oprettes forbindelse, da du muligvis har brug for den private nøgle for at få adgang til serveren. Når du arbejder med nøglen skal du blot sørge for at opbevare den sikkert i en Travis CI-miljøvariabel, så den ikke bliver vist.

En anden ting at være opmærksom på er, at du måske skal køre hele deployeringsscriptet som en enkelt linje, for eksempel — ved hjælp af doctl. Det kan kræve lidt ekstra arbejde.

doctl compute ssh  --ssh-command "alle kommandoer vil være her && her"

TLS/SSL og lastbalancering

Efter at jeg har gjort alt det, der er nævnt tidligere, var det sidste problem, jeg stødte på, at serveren ikke havde SSL. Da jeg bruger en Node.js-server, for at få den til at arbejde arbejde omvendt proxy Nginx og Let’s Encrypt, kræver det en del arbejde.

Jeg ønskede slet ikke at konfigurere alle disse SSL-indstillinger manuelt, så jeg oprettede bare en lastbalancer og registrerede oplysningerne om den i DNS. I tilfælde af DigitalOcean er oprettelsen af et selvudførende, selvsigneret certifikat på lastbalancen en simpel, gratis og hurtig procedure. En sådan tilgang har også den ekstra fordel, at det, om nødvendigt, gør det meget let at konfigurere SSL på flere servere, der kører bag lastbalancen. Dette betyder, at serverne ikke behøver at "tænke" over SSL, men stadig kan bruge port 80. Så konfiguration af SSL på lastbalanceren er langt lettere og mere bekvemt end alternative metoder til at konfigurere SSL.

Nu kan du lukke alle porte på serveren, der accepterer indgående forbindelser — undtagen port 80, der bruges til kommunikation med lastbalanceren. 22 for SSH. As a result, any attempt to directly access the server on any ports, except for these two, will fail.

Resumé

After I did everything I described in this material, I was no longer intimidated by the Docker platform or the concepts of automated CI/CD pipelines. I managed to set up a continuous integration chain, during which the code is tested before it goes into production, and the code is automatically deployed on the server. All of this is still relatively new to me, and I am sure there are ways to improve my automated workflow and make it more effective. So if you have any ideas on this, please let me know. I hope this article has helped you in your endeavors. I like to think that after reading it, you learned as much as I did while figuring out everything I wrote about.

P.S. I vores marketplace there is an image Docker, which can be installed with one click. You can check the work of the containers on VPS. All new clients are given 3 days for free testing.

Kære læsere! Do you use CI/CD technologies in your projects?

Oprettelse af CI/CD-kæde og automatisering af arbejde med Docker

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster