Introducció
Hi ha moltes aplicacions que no poden funcionar soles, sinó que necessiten altres aplicacions per funcionar.
Per exemple el Wordpress necessita una base de dades.
Mitjançant Docker Compose podem crear un conjunt de serveis de manera declarativa, dient a docker el resultat que volem i que docker s’encarregui d’executar les ordres corresponents.
Xarxa privada
Crea un carpeta cluster
i dins d'aquesta carpeta un fitxer docker-compose.yml
.
$ mkdir cluster
$ cd cluster
$ nano docker-compose.yml
A continuació tens el contingut del fitxer en format YAML:
services:
apache:
image: httpd:2.4
ports:
- 80:80
-
Pots veure que el fitxer defineix un conjunt de serveis.
-
Cada servei te un nom, en aquest cas
apache
, que es farà servir per donar nom al contenidor. -
A continuació per cada servei has de dir quina imatge es farà servir i definir els "port forward" pertinents.
Amb docker compose pots arrencar els contenidors definits perl fitxer docker-compose.yaml
amb aquesta ordre:
$ docker compose up -d
Creating network "cluster_default" with the default driver
Pulling apache (httpd:2.4)...
...
Creating cluster_apache_1 ... done
Pots veure que es crea una xarxa amb el nom cluster_default
i un contenidor amb el nom cluster_apache_1
.
Per defecte, Docker Compose afegeix el nom de la carpeta on està el fitxer docker-compose.yml
com a prefix de tots els recursos que crea, en aquest cas cluster_
.
Pots verificar que s'ha creat la xarxa:
$ docker network ls | grep cluster
49fca8deb35b cluster_default bridge local
Que és correspon a una interfície de xarxa virtual (fan servir el mateix id):
$ ip -brief addr | grep 49f
br-49fca8deb35b UP 172.18.0.1/16 fe80::42:76ff:fe7e:e33d/64
I que el contenidor està en la xarxa 172.18.0.1/16
:
$ docker exec cluster_apache_1 more /etc/hosts | grep 172
172.18.0.2 6ce60b066200
✅ Docker Compose crea una xarxa privada que permet a un conjunt de contenidors estar connectats de manera aïllada del reste d'aplicacions que s'estan executant a la màquina.
Serveis
Un fitxer docker-compose.yml
et permet definir un conjunt de serveis.
Un servei és una aplicació que s'està executant dins un contenidor i que pot ser accedida per qualsevol altre aplicació que tingui accés a la xarxa privada en que està el contenidor.
Modifica el fitxer docker-compose.yml
amb tres serveis apache:
services:
apache_1:
image: httpd:2.4
ports:
- 81:81
apache_2:
image: httpd:2.4
ports:
- 82:80
apache_3:
image: httpd:2.4
ports:
- 83:80
Desplega aquesta nova configuració:
$ docker compose up -d
WARNING: Found orphan containers (cluster_apache_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Creating cluster_apache_3_1 ... done
Creating cluster_apache_2_1 ... done
Creating cluster_apache_1_1 ... done
Pots veure que docker arrencar 3 contenidors, però no elimina el que està en execució.
Un contenidor pot guardar estat (fitxers modificats, dades, etc.) i si elimines el contenidor aquestes estat es perd.
Per tant, per defecte, docker es conservador per evitar que sense voler facis el que no havies de fer:
docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"
CONTAINER ID NAMES STATUS
8ae4c9a9b99e cluster_apache_1_1 Up 16 seconds
576213c0c870 cluster_apache_3_1 Up 16 seconds
a242c257b255 cluster_apache_2_1 Up 16 seconds
0b092e9e2196 cluster_apache_1 Up 4 minutes
✅ Amb l'opció --format
podem limitar la informació que ens mostra l'ordre docker
ps`.
Verifica amb nmap
que els 4 contenidors estan escoltant als ports respectius:
$ nmap -p80-83 127.0.0.1
...
PORT STATE SERVICE
80/tcp open http
81/tcp open hosts2-ns
82/tcp open xfer
83/tcp open mit-ml-dev
Si estas segur del que estas fent pots demanar a docker que elimini el servei que ja no està declarat amb l'opció --remove-orphans
:
$ docker compose up -d --remove-orphans
Removing orphan container "cluster_apache_1"
cluster_apache_1_1 is up-to-date
cluster_apache_2_1 is up-to-date
cluster_apache_3_1 is up-to-date
Verifica que el contenidor cluster_apache_1
s'ha eliminat:
docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"
CONTAINER ID NAMES STATUS
8ae4c9a9b99e cluster_apache_1_1 Up 10 minutes
576213c0c870 cluster_apache_3_1 Up 10 minutes
a242c257b255 cluster_apache_2_1 Up 10 minutes
Volum
Al fitxer docker-compose.yml
també pots definir volums:
services:
apache_1:
image: httpd:2.4
volumes:
- htdocs:/usr/local/apache2/htdocs
ports:
- 81:80
apache_2:
image: httpd:2.4
volumes:
- htdocs:/usr/local/apache2/htdocs
ports:
- 82:80
apache_3:
image: httpd:2.4
volumes:
- htdocs:/usr/local/apache2/htdocs
ports:
- 83:80
volumes:
htdocs:
Torna a arrencar els contenidors:
$ docker-compose up -d
Creating volume "cluster_htdocs" with default driver
Recreating cluster_apache_1_1 ... done
Recreating cluster_apache_3_1 ... done
Recreating cluster_apache_2_1 ... done
Com que el fitxer declara un volum htdocs
, docker s’encarrega de crear aquest volum.
Fixa’t que al igual que ha fet amb la xarxa i els contenidors el prefix és cluster
:
$ docker volume ls
DRIVER VOLUME NAME
local cluster_htdocs
També que s'han tornar a crear els contenidors httpd
.
Modifica el contingut htdocs
d’un dels contenidors.
docker exec cluster_apache_1_1 /bin/sh -c "echo 'hello' > htdocs/index.html"
A continuació verificar que tots el contenidors comparteixen el mateix volum:
$ curl localhost:81
hello
$ curl localhost:82
hello
$ curl localhost:83
hello
Com que el contingut de la carpeta htdocs
està montant en un volum podem eliminar el contenidors sense perdre l'estat:
$ docker compose down
Stopping cluster_apache_1_1 ... done
Stopping cluster_apache_2_1 ... done
Stopping cluster_apache_3_1 ... done
Removing cluster_apache_1_1 ... done
Removing cluster_apache_2_1 ... done
Removing cluster_apache_3_1 ... done
Removing network cluster_default
Pots veure que es borra tot (incloent la xarxa) excepte el volum:
$ docker volume ls
DRIVER VOLUME NAME
local cluster_htdocs
Si tornem a desplegar la composició tot torna a funcionar:
$ docker compose up -d
...
$ curl localhost:81
hello
Proxy
A continuació crearem un proxy pels tres servidors web.
Crea un fitxer haproxy.cfg
:
frontend proxy
bind :80
default_backend webservers
backend webservers
server s1 apache_1:80 check
server s2 apache_2:80 check
server s3 apache_3:80 check
Modifica el fitxer docker-compose.yml
:
services:
proxy:
image: haproxy:2.9
sysctls:
net.ipv4.ip_unprivileged_port_start: 0
volumes:
- ${PWD}/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
ports:
- 80:80
- 8404:8404
apache_1:
image: httpd:2.4
volumes:
- htdocs:/usr/local/apache2/htdocs
apache_2:
image: httpd:2.4
volumes:
- htdocs:/usr/local/apache2/htdocs
apache_3:
image: httpd:2.4
volumes:
- htdocs:/usr/local/apache2/htdocs
volumes:
htdocs:
Per muntar el fitxer fem servir un volum anònim.
Si vols saber perquè afegim systctls
ves a https://hub.docker.com/_/haproxy/
Para i arrenca de nou els contenidors:
$ docker compose stop
...
$ docker compose up -d
...
Starting cluster_apache_2_1 ... done
Creating cluster_proxy_1 ... done
És molt important que el fitxer haproxy.cfg
acabi amb un LF
en la última linia.
Si no tindràs aquest error:
$ curl localhost
curl: (7) Failed to connect to localhost port 80 after 0 ms: S’ha refusat la connexió
I si mires el log del contenidor trobaràs aquesta explicació:
$ docker logs cluster_proxy_1
...
[ALERT] (1) : config : parsing [/usr/local/etc/haproxy/haproxy.cfg:8]: Missing LF on last line, file might have been truncated at position 30.
[ALERT] (1) : config : Error(s) found in configuration file : /usr/local/etc/haproxy/haproxy.cfg
[ALERT] (1) : config : Fatal errors found in configuration.
✅ Si no t'ha passat modifica el fitxer haproxy.cfg
perquè doni aquest error. És important que aprenguis a solucionar aquestes situacions per tu mateix ja que ChatGPT no ho farà per tu.
Verifica que el proxy funciona:
$ curl localhost
TODO
A Xarxa vam configurar un proxy de manera imperativa.
Ara tenim un fitxer docker-compose.yml
que ens permet configurar un proxy de manera declarativa.
Elimina els contenidors:
$ docker compose stop
$ docker compose rm
Exemples
A continuació tens conjunt d’aplicacions web que es composen de diversos components que s’han desplegat mitjançant Docker Compose.
Aquestes aplicacions s’utilitzen en diferents activitats formatives:
Etherpad | Etherpad és un editor col·laboratiu en temps real de codi obert i basat en web, que permet als autors editar simultàniament un document de text i veure totes les edicions dels participants en temps real. |
Cryptpad | CryptPad és una suite de col·laboració encriptada i de codi obert d'extrem a extrem. |
Wordpress | undefined |
Odoo | Odoo és un ERP i CRM de còdi obert creat amb Python |