Cosa ho imparato oggi

Coso ho imparato oggi

(professore FONTECEDRO https://www.youtube.com/watch?v=aqTmhBca7f8 )

Dopo aver insistito col farmi dare un server da poter usare per metterci redmine e gogs, mi sono ritrovato oggi a dover far girare i due docker insieme e farli interagire.

C’è da dire che di docker non ci capisco nulla, quindi oggi ho imparato ad usare quello che mi serve di docker.

Prima di tutto sono container, ovvero sono basati sull’esecuzione di un processo bindato (perché dire bendato non da abbastanza l’idea) rispetto al resto del sistema. In sostanza quasi una macchina virtuale, ma gira sullo stesso kernel dell’os nel quale lo si lancia, è basato su concetto di cgroups di linux, e siccome non lo so rimando a https://en.wikipedia.org/wiki/Cgroups

Quello che interessava a me era di tirar su una immagine docker di redmine e una di gogs e farle girare nel server, e in più collegare i due container integrare un sistema per il controllo del progetto che desse delle statistiche aggiornate della situazione.

Ecco, quest’ultima parte è particolarmente complicata se non sai niente di docker.

*Come si fa girare un docker.*

Sostastanzialmente ho capito che per far girare un docker devi prima prendere l’immagine e poi avviarlo. Inizialmente avevo inteso che bastasse riferirsi alla immagine e scrivere

docker run image/name [altrivari parametri]

e così esso faceva tutto. Ho poi scoperto che questa è una visione un po’ miope. In effetti mi sono trovato con immagini nelle quali era già definito lo script di start. In generale al comando “docker run” si specifica il nome dell’immagine (che docker scarica in una qualche maniera da un repository delle immagini) e il comando da eseguire all’interno del container contestualmente creato al momento in cui viene eseguito run. Frase contorta, disgustorama, come direbbe il professor Fontecedro. Ma in realtà il comando

$ docker run -d -p 80:80 my_image nginx -g ‘daemon off;’
60baacd90721 # valore restituito

carica l’immagine my_image, crea un container, e, all’interno di quello esegue il comando “nginx -g ‘daemon off;'”.
Ora, visto che si tratta di una immagine personale, evidentemente devi essere a conoscenza che contiene il programma nginx, e quindi lo puoi eseguire. In generale io ho immagini nelle quali è definito all’interno dello script start.sh l’avvio di un server.

Ecco esattamente quello è il concetto di immagine: cosa c’è dentro il microservice che viene eseguito tramite docker.

Importante è anche il concetto di container: l’esecuzione della immagine con i relativi parametri di esecuzione.

Così, mi pare di aver capito, che se eseguo “docker run” con tutti i parametri del caso, ottengo un container id, è una chiave unica, sembra sha256, che identifica il container. A quel punto posso fermarla o riavviarla alla bisogna. Così:

docker stop 60baacd90721
docker start 60baacd90721

e 60baacd90721 è l’id del container che viene restuito dal comando “docker run”

Ho poi capito che se ho bisogno di entrare nella “quasi-macchina-virtuale” posso eseguire un comando a piacere in un virtual terminal di quella macchina, così

docker exec -ti 60baacd90721 bash

e posso specificare l’utente col quale eseguirlo

docker exec -u redmine -ti 60baacd90721 bash

perché avevo il problema di dover controllare il risultato del comando “git ls-remote -h ssh://…” per controllare l’accessibilità all’altro container.

A proposito del far girare più container sulla stessa macchina, il problema è stato farli communicare tra loro (magari con una sola m). E per questo c’è

docker network

sembra che docker sia un’insieme di sotto programmi, un po’ come è git. Quindi

docker network ls

elenca le reti definite nel sistema.

docker network inspect [networkname]

mostra la definizione della rete

docker network connect [networkname] [containerid]

connette una rete al container. E questa cosa è magica. In pratica se 2 container non riescono a vedersi è perché, generalmente, sono stati definiti tramite il comando run o tramite docker-compose. Nel primo caso il container avrà associata la rete “bridge” di default, nel secondo caso viene creata una rete on-the-fly da docker (c’è da controllare cosa sia docker-compose, il comando, per capire perché), e il suo nome è dato dal nome della definizione col postfisso “_default” (cioè se docker-compose.yaml è nella cartella “sfortuna” al momento della esecuzione di docker-compose, la rete creata si chiamerà sfortuna_default), nel mio caso si chiamava bugs:

$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
e0af7dce8070 bridge bridge local
ac43047ffe4f bugs_default bridge local
e117f156b39d host host local
b2a366b4b71a none null local

host è un tipo particolare di network, consiste nel risiedere nella stessa interfaccia del server dove gira … posso solo immaginare i casini nella gestione, ma è più veloce, evidentemente, perché non è emulata.

Ora, quello che ho trovato veramente fantistico oggi (eh, ma ho sudato parecchio per arrivarci) è proprio

docker network connect [netname] [containerid]

e

docker network disconnect [netname] [containerid]

in pratica si opera su un container esistente, e in esecuzione, e gli si aggiunge una scheda di rete virtuale, e la si toglie.

Cosmico.

È così che il container di redmine può vedere la rete del container gogs, e può richiedere cose tipo

git ls-remote -h ssh://git@172.17.0.2:10022/danieldock/privatetest.git

Ovviamente il viaggio di oggi è stato infarcito di “boh … non funziona, lascio stare .. ma…” e dal leggere cose tipo “I’ll merge if it is the case” https://github.com/dergachev/redmine_git_remote/issues/34 (no, che dici, quanti devono ancora scoronare?)

 

Ok. Tutto funziona e abbiamo un sistema per monitorare l’andamento dello sviluppo delle features, la gestione delle anomalie, vediamo chi sta lavorando a cosa e come, eccetera.

Era ora.