Deploy pe server propriu

Va salut cu respect!
Cum am mai mentionat si in alte intrebari am un proiect la facultate practic e vorba de mai multe microservicii si cateva baze de date si poate si un front-end pe care il dezvoltam dar un coleg de al meu s-a oferit sa faca un server la el acasa ca sa hostam tot proiectul.
Problema e ca la viata mea ce am hostat a fost in cloud si nici nu stiu de unde sa apuc problema cand vine vorba de hostat vreo 8+ microservicii si 7 baze de date pe un server custom intr-un apartament.
Va trebui sa creez un pipeline si la fiecare push se va creea o noua imagine de docker care va rula pe server? Si asta pentru fiecare microserviciu?( fiecare echipa are repo separat)
Sau cum se procedeeaza?
Ce trebuie sa am in vedere?
Si o intrebare si mai importanta cum securizam un astfel de server?

Aș recomanda următoarele GitLab self-hosted (merge cu docker-compose) și GitLab runner (tot cu docker-compose rulate, în runnere ruleze pipeline-urile)

După ce ai GitLab funcțional, ai rezolvat următoarele:

  • git hosting
  • container registry
  • pipelineuri

Pe partea de deployment ai de ales cât de mult vrei să te complici. Varianta cea mai simplă cred că ar fi:

  • definești toate serviciile într-un docker-compose și le rulezi pe serverul respectiv
  • când construiești imaginile pui un tag nume-serviciu:latest și le push-uri în registry-ul din GitLab
  • în pipeline-ul unde vrei să faci deployment e de ajuns să faci SSH către server și să rulezi:
docker-compose pull # să downloadeze versiunile noi
docker-compose up -d # să repornească serviciile care au nevoie de update

Dezavantaje: când faci deployment o să fi downtime pentru serviciile respective. Dacă vrei uptime 100% se complică un pic lucrurile.

1 Like

Eu nu recomand docker compose daca aveti sisteme de operare diferite intre devi. (docker compose nu e standard precum docker) Plus docker compose ascunde comunicarea intre servicii, dupa cum am inteles folositi kafka, dar serviciile tot trebuie sa gaseasca bazele de date dupa domeniu intern de exemplu. E greu de setat sa porneasca serviciile in ordinea corecta ceea ce poate crea probleme la pornire.

Daca vreti o arhitectura moderna trebuie un cluster de kubernetes, dar e dificil, in mod ideal trebuie pornita toata arhitectura cu kubernetes in minte la Java. Daca puneti un service registry, precum eureka/consul/zookeper nu e deloc compatibil si problemele care apar sunt greu de inteles de un incepator.

Kubernetes local (si minimal) se poate cu k3d/minikube/kind.

La fostul loc de munca, ceva de genul ala era.
Din cand in cand mai faceam update la imagine, ca se intampla sa mai traga versiunea veche.

Poți detalia asta? Încă învăț docker și m-a băgat în ceață afirmația ta.

Pentru un client folosim docker-compose pe mai multe distribuții de linux, W11 și Mac și nu au fost probleme (ce-i drept, nici nu avem multe servicii: elastic search, redis și mysql).

Ce știu sigur că îl setezi relativ ușor să pornească serviciile în ordinea corectă:

1 Like

Depends on nu face nimic (verifica doar ca a pornit vm-ul de docker), serviciul pornit in docker nu inseamna ca a si pornit si e gata de utilizat (a incarcat datele in baza de date, serviciul s-a inregistrat, s-a inregistrat pe un canal in kafka, ca raspunde la ping pe un port si nu are latenta de 10 secunde…)
Vei avea servicii care depind de unul de altul, adica le trebuie un mod de a stii ca au pornit, altfel ori nu merg si dai refresh pana vezi ca merge (dar dau erori), ori tot repornesc pana isi gasesc serviciul de care depind.

Cel mai simplu exemplu, daca vrei sa stii ca e pornit mysql trebuie sa raspunda la un query sql cu un meta tabel sau la un query, nu e destul ca sa fi pornit containerul. (de exemplu daca folosesti liquibase trebuie sa ruleze de pe alt serviciu si doar dupa ce s-a incarcat consideri ca baza de date e pornita si celelalte servicii se pot apuca de treaba)

Dupa ai pattern-ul de service registry, in kubernetes asta se rezolva cu dns-uri interne pe serviciu. Poti seta aceste dns-uri si intern tot faci ping sau un get la ceva resursa ca sa stii ca sunt online, nu e destul ca sa iti porneasca doar containerul fiindca el poate sta 10 minute in loading sau in loop de restart pana isi gaseste toate dependentele online.

Problema cu docker compose apare cand folosesti Docker Desktop, daca te uiti putin docker compose are mai multe implementari, open-source sau nu.
O diferenta semnificativa e host.docker.internal sau kubernetes.docker.internal, ceea ce e setat doar daca folosesti Docker Desktop (pe linux abia recent au adaugat host.docker.internal). host.docker.internal e un domeniu care iti permite sa accesezi un serviciu de pe acelasi domeniu intern (intre VM-uri) si extern (in browser) ca sa nu ai probleme cu CORS/autentificare (token validation), altfel trebuie sa iti setezi un proxy precum traefik/nginx si e si mai complicat.

Practic docker-compose e doar pe jumatate open-source, daca folosesti alternativele Docker Desktop (ca nu vrei licenta/closed source) o sa vezi ca difera semnificativ intre ce ai pe OS X, linux si Windows sau WSL.

Pe Mac OS X cu imagini non-native daca totul porneste greu o sa porneasca si mai greu daca planetele trebuie sa se alinieze ca fiecare serviciu sa porneasca in ordinea corecta.

Plus daca pornesti totul deodata o sa ai de exemplu nevoie de 32Gb de ram in loc de 16Gb si dupa scade de fapt fiindca ai nevoie doar de 8-16 la rulare, dar tot iti va ocupa 32Gb fiindca la inceput a fost nevoie de un warm-up mare in paralel. (tipic JVM/.NET)

De fapt actualizez, Compose v3 are depends_on healthcheck, pe care nu l-am folosit, dar in opinia mea documentatia la compose e foarte proasta si totul e plin de if-uri in functie de versiunea de docker si compose, plus ce compose cli ai local pe ce OS.

3 Likes

Nu aș da vina pe docker-compose aici. Ai două variante în situația asta: healthcheck in container și/sau healthcheck in docker-compose. Și apoi adaugi conditions la depends_on. Din manual pare creat pentru situațiile descrise de tine. Din păcate foarte puțini le folosesc.


Simt că e de învățat aici. Așa că vin cu niște întrebări (posibil stupide):

Disclaimer: planuiesc să migrez de pe docker-compose pe k8s. Cunosc docker-compose destul de bine însă am zero experiență practică când vine vorba de setat k8s.

Nu același lucru ca și cu alias-urile din docker-compose? Oferă ceva extra? Ai subdomeniu individual pentru fiecare container?

Poți detalia un pic? Sau e doar vorba de situația în care folosești alternative Docker Desktop? Docker e free pentru personal use. În cazul de față cred că se încadrează.

E mai greu de setat un reverse proxy în nginx decât setat k8s?

Ai idee cum rezolvă k8s asta?

Mie nu imi e clara cerinta.

Ai incercat varianta cea mai simpla? Sa pornesti manual fiecare microserviciu? Baza de date sub acelasi server dar cu utilizatori diferiti.

Apoi automatizezi/izolezi treptat.

Avem urmatoarele sub-probleme pe care trebuie sa le rezolvam

  1. Cum trigger-uim un pipeline la code push
  2. Cum ajunge codul nou pe deploy server.
  3. Cum pornim aplicatia actualizata.

Eu as face in felul urmator, ca efortul sa fie minim, in timp ce avem si un oarecare reliability.

Pe acel server custom unde vrei sa faci deploy, as folosi de asemenea docker-compose pentru a porni si build-ui aplicatia. Chestia asta deja o ai pe local (cel putin fac aceasta asumare), iti merge, nu mai trebuie sa faci nimic in plus. Deci punctul 3 e rezolvat, daca mergem pe varianta asta. Ok, de fapt, va trebui totusi ca sa restartam serviciile docker, ruland o comanda de genul, de fiecare data:

docker-compose up -d --pull --build

Pentru asta poti folosi acest GitHub Action: GitHub - alex-ac/github-action-ssh-docker-compose: Simple github action to run docker-compose on remote host.

La punctul 1, se poate folosi ori WebHooks (un pic mai complicat), ori, mai simplu, cu GitHub Actions / Bitbucket Pipelines / GitLab CI. Toate 3 platforme stiu sa faca asta.

La punctul 2, varianta simpla si reliabila o vad sa construim, o imagine de docker cu noua versiune, ii facem push intr-un registry (GitHub Docker Registry), iar la punctul urmator vom folosi tot timpul image tag version :latest


TLDR;

GitHub + GitHub Actions + GitHub Docker Registry + Docker Compose = :heartpulse:

2 Likes

Stiu ca exista ceva de genul healthcheck, unde pui un sql simplu sa se execute (care sa aiba timp de executie mic).

Dadeam un count pe o tabela mica. Asta era un healthcheck pt baza de date.

Vazand ca se mai dau raspunsuri in continuare as dori sa precizeze, ca, am rezolvat situatia pentru ca profesorul s-a oferit sa ne achizitioneze un vps si am dat acolo deploy cu toate aferente, am incercat sa fac si un pipeline cu github actions.
Va multumesc insa pentru raspunsuri!

1 Like