Het opzetten van een CI/CD-pijplijn en automatisering van het werk met Docker

Ik heb mijn eerste websites aan het eind van de jaren 90 geschreven. Toen was het heel eenvoudig om ze operationeel te krijgen. Er was een Apache-server op een of andere gedeelde hosting, en je kon deze server bereiken via FTP door iets in de browserbalk in te voeren zoals ftp://ftp.example.com. Vervolgens moest je de naam en het wachtwoord invoeren en de bestanden naar de server uploaden. Het waren andere tijden, alles was toen eenvoudiger dan nu.

Het opzetten van een CI/CD-pijplijn en automatisering van het werk met Docker

In de twee decennia die sindsdien zijn verstreken, is er veel veranderd. Websites zijn ingewikkelder geworden, ze moeten voor productie worden samengesteld. Eén enkele server is veranderd in meerdere servers die achter load balancers werken, en het gebruik van versiebeheersystemen is de norm geworden.

Voor mijn persoonlijke project had ik een speciale configuratie. En ik wist dat ik de mogelijkheid nodig had om de website in productie te brengen met slechts één actie: het publiceren van de code naar de branch master op GitHub. Ik wist ook dat ik, om mijn kleine webapplicatie te laten draaien, geen enorm Kubernetes-cluster wilde beheren, of Docker Swarm wilde gebruiken, of een serverpark met pods, agenten en allerlei andere complicaties wilde onderhouden. Om mijn doel van maximale vereenvoudiging te bereiken, moest ik me verdiepen in CI/CD.

Als je een klein project hebt (in ons geval een Node.js-project) en je wilt weten hoe je de implementatie van dit project kunt automatiseren, zodat hetgene wat in de repository staat exact overeenkomt met hetgeen dat in productie draait, dan denk ik dat je geïnteresseerd kunt zijn in dit artikel.

Vereisten

Het wordt verondersteld dat de lezer van dit artikel basiskennis heeft van het gebruik van de opdrachtregel en het schrijven van Bash-scripts. Bovendien heeft hij accounts nodig Travis CI en Docker Hub.

Doelen

Ik zal niet zeggen dat dit artikel zonder meer als een 'handleiding' kan worden bestempeld. Het is meer een document waarin ik beschrijf wat ik heb geleerd en het proces van het testen en implementeren van code in productie, dat in één geautomatiseerde stap wordt uitgevoerd.

Dit is uiteindelijk mijn werkproces geworden.

Voor code die naar een andere branch van de repository wordt gestuurd dan master, worden de volgende acties uitgevoerd:

  • De bouw van het project wordt gestart op Travis CI.
  • Alle modulaire, integratie- en end-to-end tests worden uitgevoerd.

Alleen voor code die komt in master, wordt het volgende uitgevoerd:

  • Alles wat hierboven is gezegd, plus...
  • Het opbouwen van een Docker-image op basis van de huidige code, instellingen en omgeving.
  • Het plaatsen van het image op Docker Hub.
  • Verbinding maken met de productie-server.
  • Het ophalen van het image van Docker Hub naar de server.
  • De huidige container stoppen en een nieuwe starten, gebaseerd op het nieuwe image.

Als je helemaal niets weet van Docker, images en containers – maak je geen zorgen. Ik zal je er alles over vertellen.

Wat is CI/CD?

De afkorting CI/CD staat voor "continuous integration/continuous deployment" – "continue integratie/continue implementatie".

▍Continue integratie

Continue integratie is het proces waarbij ontwikkelaars commits maken naar de hoofdrepository van de broncode van het project (meestal naar de branch master). Hierbij wordt de kwaliteit van de code gewaarborgd door middel van geautomatiseerde tests.

▍Continue implementatie

Continue implementatie is het frequent geautomatiseerd implementeren van code in de productie. Het tweede deel van de afkorting CI/CD wordt soms uitgelegd als "continuous delivery" ("continue levering"). Dit is in wezen hetzelfde als "continue implementatie", maar "continue levering" betekent dat handmatige bevestiging van wijzigingen vereist is voordat het implementatieproces van het project kan starten.

Aan de slag

De applicatie waarin ik dit allemaal heb geleerd, heet TakeNote. Dit is een webproject waaraan ik werk, bedoeld voor het maken van notities. Eerst probeerde ik een JAMStack-project of alleen een frontend-applicatie zonder server te maken, om gebruik te maken van de standaardmogelijkheden voor hosting en implementatie van projecten die worden aangeboden door Netlify. Naarmate de complexiteit van de applicatie toenam, moest ik ook een servergedeelte maken, wat betekende dat ik mijn eigen strategie voor geautomatiseerde integratie en geautomatiseerde implementatie van het project moest ontwikkelen.

In mijn geval is de applicatie een Express-server die draait in een Node.js-omgeving, die een single-page React-applicatie bedient en een beveiligde server-API ondersteunt. Deze architectuur volgt een strategie die je kunt vinden in dit handleiding voor full-stack-authenticatie.

Ik heb overlegd met een vriend, die een expert is op het gebied van automatisering, en vroeg hem wat ik moest doen zodat alles werkte zoals ik wilde. Hij gaf me het idee van hoe de geautomatiseerde workflow eruit zou moeten zien, zoals uiteengezet in de sectie 'Doelen' van dit artikel. Het stellen van dergelijke doelen betekende dat ik moest begrijpen hoe ik Docker moest gebruiken.

Docker

Docker is een tool die, dankzij containerisatietechnologie, het gemakkelijk maakt om applicaties te verspreiden, evenals om ze te implementeren en uit te voeren in dezelfde omgeving, zelfs als de Docker-platform zelf in verschillende omgevingen draait. Om te beginnen had ik toegang nodig tot de Command Line Interface (CLI) tools van Docker. De instructie voor het installeren van Docker is niet per se heel duidelijk of begrijpelijk, maar je kunt eruit opmaken dat om de eerste stap van de installatie te maken, je Docker Desktop (voor Mac of Windows) moet downloaden.

Docker Hub is ongeveer hetzelfde als GitHub voor git-repositories, of een registry npm voor JavaScript-pakketten. Dit is een online repository voor Docker-images. Dit is waar Docker Desktop verbinding mee maakt.

Dus om aan de slag te gaan met Docker, moet je twee dingen doen:

Daarna kun je de werking van de Docker CLI controleren door de volgende opdracht uit te voeren om de versie van Docker te controleren:

docker -v

Vervolgens log je in op Docker Hub door, wanneer daarom gevraagd, je gebruikersnaam en wachtwoord in te voeren:

docker login

Om Docker te gebruiken, moet je de concepten van images en containers begrijpen.

▍Images

Een image is te vergelijken met een plan dat instructies bevat voor het bouwen van een container. Het is een onveranderlijke snapshot van het bestandssysteem en de applicatie-instellingen. Ontwikkelaars kunnen gemakkelijk images uitwisselen.

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

Dit commando zal een tabel weergeven met de volgende kop:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

Vervolgens bekijken we enkele voorbeelden van commando's in dezelfde indeling - eerst de opdracht met commentaar, gevolgd door een voorbeeld van de uitvoer.

▍Containers

Een container is een uitvoerbaar pakket dat alles bevat wat nodig is om een applicatie uit te voeren. Bij deze aanpak werkt de applicatie altijd op dezelfde manier, ongeacht de infrastructuur: in een geïsoleerde omgeving en in dezelfde omgeving. Het gaat erom dat in verschillende omgevingen exemplaren van dezelfde afbeelding worden uitgevoerd.

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

▍Tags

Een tag is een aanwijzing voor een specifieke versie van een afbeelding.

▍Korte handleiding voor Docker-commando's

Hier is een overzicht van enkele vaak gebruikte Docker-commando's.

Opdracht

Context

Actie

docker build

Afbeelding

Een afbeelding bouwen vanuit een Dockerfile

docker tag

Afbeelding

Afbeelding taggen

docker images

Afbeelding

Een lijst van afbeeldingen weergeven

docker run

Container

Een container op basis van een afbeelding starten

docker push

Afbeelding

Een afbeelding naar de containerregistry verzenden

docker pull

Afbeelding

Een afbeelding uit de containerregistry downloaden

docker ps

Container

Een lijst van containers weergeven

docker system prune

Afbeelding/Container

Verwijderen van ongebruikte containers en afbeeldingen

▍Dockerfile

Ik weet hoe ik een applicatie lokaal kan starten voor productie. Ik heb een Webpack-configuratie die bedoeld is voor het bouwen van een kant-en-klaar React-app. Daarnaast heb ik een commando dat een server start, gebaseerd op Node.js, op poort 5000. Dit ziet er als volgt uit:

npm i         # afhankelijkheden installeren
npm run build # React-app bouwen
npm run start # Node-server starten

Ik moet opmerken dat ik geen voorbeeldapplicatie heb voor dit materiaal. Maar voor experimenten zal iedere eenvoudige Node-applicatie voldoen.

Om gebruik te maken van de container moet je instructies aan Docker geven. Dit doe je met behulp van een bestand genaamd Dockerfile, dat zich in de hoofdmap van het project bevindt. Dit bestand lijkt in het begin behoorlijk verwarrend.

Maar wat erin staat, beschrijft alleen met speciale commando's iets als het instellen van de werkomgeving. Hier zijn enkele van deze commando's:

  • FROM — Dit commando start het bestand. Het geeft de basisafbeelding aan waar de container op is gebaseerd.
  • COPY — Bestanden kopiëren vanuit een lokale bron naar de container.
  • WORKDIR — De werkdirectory instellen voor de volgende commando's.
  • RUN — Commando's uitvoeren.
  • EXPOSE — Het poortnummer instellen.
  • ENTRYPOINT — Het uitvoerende commando aangeven.

Dockerfile kan er ongeveer zo uitzien:

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

Afhankelijk van de gekozen basisafbeelding moet u mogelijk extra afhankelijkheden installeren. Sommige basisafbeeldingen (zoals Node Alpine Linux) zijn ontworpen om zo compact mogelijk te zijn. Hierdoor kunnen sommige programma's ontbreken die u verwacht.

▍Bouwen, taggen en uitvoeren van de container

Lokale bouw en uitvoering van de container zijn, zodra we hebben Dockerfile, vrij eenvoudig. Voordat u de afbeelding naar Docker Hub verzendt, moet u deze lokaal testen.

▍Bouwen

Eerst moet u afbeelding, met een naam, en optioneel een tag (als er geen tag wordt opgegeven, wijst het systeem automatisch een tag toe aan de afbeelding latest).

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

Na het uitvoeren van deze opdracht kunt u zien hoe Docker de afbeelding bouwt.

Sending build context to Docker daemon   2.88MB
Step 1/9 : FROM node:12-alpine
 ---> ...uitvoering van bouwstappen...
Succesvol gebouwd 123456789123
Succesvol getagd <image>:<tag>

Het bouwen kan een paar minuten duren — dit hangt ervan af hoeveel afhankelijkheden u heeft. Na voltooiing van de bouw kunt u de opdracht uitvoeren docker images en kijken naar de beschrijving van uw nieuwe afbeelding.

REPOSITORY          TAG               IMAGE ID            CREATED              SIZE
<image>             latest            123456789123        Ongeveer een minuut geleden   x.xxGB

▍Uitvoeren

De afbeelding is aangemaakt. Dit betekent dat u een container kunt starten op basis hiervan. Aangezien ik wil dat ik toegang heb tot de applicatie die in de container draait, op het adres localhost:5000, heb ik in de linkerhelft van de paar 5000:5000 in de volgende opdracht ingesteld 5000. In de rechterhelft bevindt zich de poort van de container.

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

Nu de container is aangemaakt en gestart, kunt u de opdracht gebruiken docker ps om informatie over deze container te bekijken (of u kunt de opdracht gebruiken docker ps -a, die informatie over alle containers toont, niet alleen de actieve).

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS                    NAMES
987654321234        <image>             "\/bin\/sh -c 'npm run…"   6 seconden geleden        Up 6 seconden                0.0.0.0:5000->5000\/tcp   stoic_darwin

Als u nu naar het adres gaat localhost:5000 — kunt u de webpagina van de draaiende applicatie zien, die er precies zo uitziet als de webpagina van de applicatie die in de productieomgeving draait.

▍Tag toekennen en publiceren

Om gebruik te maken van een van de gemaakte afbeeldingen op de productie-server, moeten we in staat zijn om deze afbeelding van Docker Hub te downloaden. Dit betekent dat we eerst een repository voor het project op Docker Hub moeten aanmaken. Daarna hebben we een plek waar we de afbeelding naartoe kunnen sturen. De afbeelding moet een naam krijgen die begint met onze gebruikersnaam op Docker Hub. Daarna volgt de naam van de repository. Aan het einde van de naam kan een willekeurige tag staan. Hieronder is een voorbeeld van hoe afbeeldingennamen volgens deze schema moeten worden gegeven.

Nu kunnen we de afbeelding samenstellen met een nieuwe naam en het commando uitvoeren docker push om deze naar de Docker Hub-repository te sturen.

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

# In de praktijk kan dit er bijvoorbeeld zo uitzien:
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

Als alles goed gaat, is de afbeelding beschikbaar op Docker Hub en kan deze eenvoudig op de server worden gedownload of aan andere ontwikkelaars worden overgedragen.

Volgende stappen

Tot nu toe hebben we bevestigd dat de applicatie, in de vorm van een Docker-container, lokaal werkt. We hebben de container naar Docker Hub geüpload. Dit betekent dat we al een eind op weg zijn naar ons doel. Nu moeten we nog twee vragen oplossen:

  • De CI-tool instellen voor het testen en uitrollen van de code.
  • De productie-server instellen zodat deze onze code kan downloaden en uitvoeren.

In ons geval gebruiken we als CI/CD-oplossing Travis CI. Als server gebruiken we — DigitalOcean.

Het is vermeldenswaard dat hier ook andere combinatie van diensten kan worden gebruikt. In plaats van Travis CI kan bijvoorbeeld CircleCI of Github Actions worden gebruikt. En in plaats van DigitalOcean — AWS of Linode.

We hebben besloten om met Travis CI te werken, en ik heb al iets ingesteld in deze service. Daarom zal ik nu kort uitleggen hoe je het voor gebruik kunt voorbereiden.

Travis CI

Travis CI is een tool voor het testen en uitrollen van code. Ik wil niet in detail treden over de instellingen van Travis CI, omdat elk project uniek is en dat niet veel nut zal hebben. Maar ik zal de basisprincipes uitleggen die u in staat stellen om te beginnen als u besluit Travis CI te gebruiken. Wat u ook kiest — Travis CI, CircleCI, Jenkins, of iets anders, de methoden voor instellingen zullen vergelijkbaar zijn.

Om te beginnen met Travis CI, ga naar de projectwebsite en maak een account aan. Integreer vervolgens Travis CI met uw GitHub-account. Tijdens het instellen van het systeem moet u de repository opgeven waarmee u automatisering wilt toepassen en toegang daartoe inschakelen. (Ik gebruik GitHub, maar ik ben er zeker van dat Travis CI ook kan integreren met BitBucket, GitLab en andere soortgelijke diensten).

Elke keer wanneer Travis CI aan de slag gaat, wordt er een server gestart die de in het configuratiebestand aangegeven commando's uitvoert, inclusief het implementeren van de bijbehorende takken van de repository.

▍Levenscyclus van een taak

Het configuratiebestand van Travis CI, dat wordt genoemd .travis.yml en dat zich in de hoofdmap van het project bevindt, ondersteunt het concept van gebeurtenissen levenscyclus van de taak. Dit zijn de gebeurtenissen, in de volgorde waarin ze plaatsvinden:

  • apt addons
  • cache componenten
  • before_install
  • install
  • before_script
  • script
  • before_cache
  • after_success of after_failure
  • before_deploy
  • deploy
  • after_deploy
  • after_script

▍Testen

In het configuratiebestand ga ik een lokale Travis CI-server instellen. Voor de taal heb ik gekozen voor Node 12 en heb ik het systeem aangegeven dat het de benodigde afhankelijkheden voor Docker moet installeren.

Alles wat vermeld staat in .travis.yml, zal worden uitgevoerd bij het verwerken van alle pull-verzoeken naar alle takken van de repository, tenzij anders aangegeven. Dit is een nuttige functie, omdat het betekent dat we de volledige code die naar de repository komt kunnen testen. Dit helpt te weten of de code klaar is om in de branch te worden geschreven master, en of het de buildprocessen van het project zal verstoren. In deze globale configuratie installeer ik alles lokaal, start de Webpack-ontwikkelaarsserver op de achtergrond (dit is een kenmerk van mijn workflow) en voer ik de tests uit.

Als u wilt dat er insignia's met informatie over de testcodecoverage in uw repository worden weergegeven, here vindt u een korte handleiding voor het gebruik van Jest, Travis CI en Coveralls voor het verzamelen en weergeven van deze informatie.

Dus, hier is de inhoud van het bestand .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

Hier eindigen de handelingen die worden uitgevoerd voor alle takken van de repository en voor pull-verzoeken.

▍Implementatie

Uitgaande van de veronderstelling dat alle geautomatiseerde tests succesvol zijn afgerond, kunnen we, wat niet verplicht is, de code op de productie-server implementeren. Aangezien we dit alleen willen doen voor de code uit de branch master, geven we het systeem de juiste instructies in de uitrolinstellingen. Voordat u de code die we hierna bespreken in uw project probeert te gebruiken, wil ik u waarschuwen dat u een echt script moet hebben dat wordt aangeroepen voor de uitrol.

deploy:
  # Bouw de Docker-container en upload deze naar Docker Hub
  provider: script
  script: bash deploy.sh
  on:
    branch: master

Het uitrolscript vervult twee taken:

  • Het bouwen, taggen en verzenden van het image naar Docker Hub met behulp van het CI-tool (in ons geval is dat Travis CI).
  • Het uploaden van het image naar de server, stoppen van de oude container en starten van de nieuwe (in ons geval draait de server op het DigitalOcean-platform).

Eerst moet het automatische proces voor het bouwen, taggen en verzenden van het image naar Docker Hub worden ingesteld. Dit lijkt erg op wat we al handmatig hebben gedaan, met uitzondering van het feit dat we hier een strategie voor het toekennen van unieke tags aan de images en automatisering van het inloggen nodig hebben. Ik had moeite met enkele details van het uitrolscript, zoals de tagstrategie, inloggen, codering van SSH-sleutels en het tot stand brengen van de SSH-verbinding. Maar gelukkig kan mijn vriend heel goed overweg met bash, net als met veel andere dingen. Hij hielp me dit script te schrijven.

Dus, het eerste deel van het script is het uploaden van het image naar Docker Hub. Dit is vrij eenvoudig te doen. De taggingstrategie die ik heb gebruikt, houdt in dat de git-hash en de git-tag worden gecombineerd, als deze bestaat. Dit zorgt ervoor dat er een unieke tag wordt aangemaakt en het vergemakkelijkt de identificatie van de build waarop deze is gebaseerd. DOCKER_USERNAME en DOCKER_PASSWORD — dit zijn gebruikersvariabelen die kunnen worden ingesteld via de interface van Travis CI. Travis CI verwerkt de geheimen automatisch zodat ze niet in verkeerde handen vallen.

Dit is het eerste deel van het 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}

Hoe het tweede deel van het script eruit zal zien, hangt volledig af van welke host u gebruikt en hoe de verbinding ermee is georganiseerd. In mijn geval, aangezien ik gebruik maak van Digital Ocean, worden de commando's gebruikt om verbinding te maken met de server doctl. Bij gebruik van Aws zal de utility aws, enzovoort, worden gebruikt.

Het configureren van de server was niet bijzonder moeilijk. Zo heb ik een droplet ingesteld op basis van een basisafbeelding. Het is vermeldenswaard dat het door mij gekozen systeem een eenmalige handmatige installatie van Docker en een eenmalige handmatige opstart van Docker vereist. Voor de installatie van Docker gebruikte ik Ubuntu 18.04, dus als jij ook Ubuntu gebruikt, kun je gewoon volgen deze eenvoudige handleiding.

Ik heb het hier niet over specifieke opdrachten voor de service, aangezien dit aspect in verschillende gevallen sterk kan variëren. Ik geef alleen een algemeen actieplan dat wordt uitgevoerd na het inloggen via SSH op de server waarop het project zal worden uitgerold:

  • Je moet de container vinden die momenteel draait en deze stoppen.
  • Daarna moet je, op de achtergrond, een nieuwe container starten.
  • Je moet de lokale serverpoort instellen op 80 — dit maakt het mogelijk om de site te bereiken via een adres zoals example.com, zonder de poort op te geven, in plaats van een adres zoals example.com:5000.
  • En tot slot moet je alle oude containers en afbeeldingen verwijderen.

Hier is het vervolg van het 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

Enkele dingen om op te letten

Misschien zie je een waarschuwing wanneer je verbinding maakt met de server via SSH vanuit Travis CI, die de installatie zal stoppen omdat het systeem op een reactie van de gebruiker wacht.

De authenticiteit van de host ' ()' kan niet worden vastgesteld.
RSA-sleutelvingerafdruk is .
Weet je zeker dat je wilt doorgaan met verbinden (ja/nee)?

Ik heb ontdekt dat de string sleutel kan worden gecodeerd in base64, zodat deze in een vorm wordt opgeslagen waarmee je er gemakkelijk en veilig mee kunt werken. Tijdens de installatie kan de publieke sleutel worden gedecodeerd en in een bestand worden opgeslagen known_hosts om de hierboven beschreven fout te vermijden.

echo  | base64 # geeft  weer

In de praktijk kan dit commando er zo uitzien:

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

En zo ziet het eruit — een string in base64-codering:

123.45.67.89 ssh-rsa AAAAB3Nza...user@example.com

Dit is de hierboven genoemde opdracht

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

Dezelfde benadering kan worden gebruikt met de privésleutel bij het tot stand brengen van de verbinding, aangezien je mogelijk de privésleutel nodig hebt om toegang te krijgen tot de server. Zorg ervoor dat je de sleutel veilig opslaat in de omgevingsvariabele Travis CI, zodat deze nergens wordt weergegeven.

Een ander punt om op te letten is dat je mogelijk het hele implementatiescript als één regel moet uitvoeren, bijvoorbeeld door middel van doctl. Dit kan wat extra inspanning vergen.

doctl compute ssh  --ssh-command "alle commando's komen hier &&& hier"

TLS/SSL en load balancing

Nadat ik alles had gedaan wat hierboven is genoemd, was het laatste probleem dat ik tegenkwam dat de server geen SSL had. Aangezien ik een Node.js-server gebruik, om ervoor te zorgen dat met werken reverse proxy Nginx en Let's Encrypt, is er behoorlijk wat werk mee gemoeid.

Ik wilde deze SSL-instellingen helemaal niet handmatig uitvoeren, dus heb ik gewoon een load balancer gemaakt en de gegevens ervan in de DNS vastgelegd. In het geval van DigitalOcean bijvoorbeeld, is het creëren van een automatisch vernieuwend zelfondertekend certificaat op de load balancer een eenvoudige, gratis en snelle procedure. Dit heeft ook het extra voordeel dat het, indien nodig, heel eenvoudig is om SSL in te stellen op meerdere servers die achter de load balancer draaien. Dit stelt de servers in staat om helemaal niet over SSL na te denken, maar het kan nog steeds normaal poort gebruiken. 80Het instellen van SSL op de load balancer is dus veel eenvoudiger en handiger dan alternatieve methoden voor het instellen van SSL.

Nu kan ik alle poorten op de server sluiten die inkomende verbindingen accepteren - behalve de poort 80, die wordt gebruikt voor communicatie met de load balancer, en de poort 22 voor SSH. Als gevolg hiervan zal de poging om rechtstreeks verbinding te maken met de server via andere poorten dan deze twee mislukken.

Conclusies

Nadat ik alles had gedaan waarover ik in dit artikel heb verteld, was ik niet langer bang voor het Docker-platform of de concepten van geautomatiseerde CI/CD-ketens. Ik kon een continue integratieketen instellen, waarin de code wordt getest voordat deze in productie wordt genomen en de code automatisch op de server wordt uitgerold. Dit alles is voor mij nog relatief nieuw, en ik ben ervan overtuigd dat er manieren zijn om mijn geautomatiseerde werkproces te verbeteren en efficiënter te maken. Dus als je ideeën hierover hebt - laat het me weten. mij Ik hoop dat dit artikel je heeft geholpen in je werkzaamheden. Ik wil graag geloven dat je, door het te lezen, net zoveel hebt geleerd als ik terwijl ik alles uitzocht wat ik erin heb beschreven.

P.S. In onze op de marktplaats is er een afbeelding Docker, die met één klik kan worden geïnstalleerd. U kunt de werking van de containers testen op VPS. Alle nieuwe klanten krijgen 3 dagen gratis om uit te proberen.

Geachte lezers! Maak je gebruik van CI/CD-technologieën in je projecten?

Het opzetten van een CI/CD-pijplijn en automatisering van het werk met Docker

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster