ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
Numărul 149
Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 64
Abonament PDF

Cum să nu folosim Docker

Robert Mălai
Engineering Manager @ 3Pillar Global



PROGRAMARE


Pe lângă documentaţia oficială Docker, există câteva resurse bune pe Internet unde puteţi citi despre cum puteţi începe să lucraţi pe un mediu Docker în proiectul vostru, aici incluzând tagul Stack Overflow Docker, imaginile oficiale Docker pentru MySQL și Postgres. Din nefericire, nu sunt multe locuri unde se poate citi despre pașii ce NU trebuie urmaţi în instalarea Docker pentru o serie de studii de caz comune. 

Poate vă întrebaţi "De ce ar fi cineva interesat de așa ceva?" Cred că semnificaţia acestor scenarii ţine de faptul că soluţiile se găsesc prin încercare și eșec - cam aceeași metodă aplicată de un elev de clasa a 2-a. Vă aflaţi într-o situaţie similară? Dacă da, ideile expuse mai jos vor fi utile pentru voi.

Dacă auziţi de Docker pentru prima oară, puteţi începe tutorialul, apoi să reveniţi la acest articol. Am utilizat Docker 1.12 pe macOS, în mod nativ -  Docker gestionând buildul în hypervisor.

Iniţializarea bazei de date: definirea datelor problemei

Toţi folosim baze de date. Este cel mai utilizat studiu de caz din orice serviciu distribuit, fie el mic sau mare sau din orice aplicaţie web. Dacă nu folosiţi un ORM unde entităţile să fie create "magic" de framework, atunci probabil că extrageţi date semnificative dintr-o bază de date pe care nu o deţineţi nativ. În acest caz, va trebuie să iniţializaţi datele, să creaţi baza de date și tabelele aplicaţiei.

Este important să înţelegeţi tiparul generic aplicat de MySQL sau Postgres pentru a obţine acest lucru:

Reţeta de bază va instala software-ul și orice alte utilităţi necesare, apoi aceasta va "urca" volumul de date și va lansa scriptul init (scriptul de iniţializare). Scriptul init va verifica dacă dosarul de date este gol sau nu, iar, în funcţie de starea de fapt, va lansa iniţializarea scripturilor din dosarul docker-entrypoint-initdb.d care au fost urcate/încărcate de utilizator.

Această reţetă va iniţializa baza voastră de date.

Dar ce se întâmplă în următorul caz în care folosim un container Docker în dezvoltare și emulăm baza de date reală cu cantităţi mari de date, să zicem un milion? Iniţializarea de mai sus va funcţiona, dar va dura foarte mult timp. Dacă la acest fapt mai adăugăm alte imagini într-o configuraţe Travis unde să rulaţi suita voastră de teste automate, atunci veţi avea de așteptat până containerul devine disponibil pentru o bună bucată de timp … să zicem 15 minute. Aceasta nu este o inconvenienţă în unele cazuri, dar poate fi în alte cazuri din următoarele motive:

Iniţializarea bazei de date: soluţie propusă

În unul din proiectele noastre, unde trebuie să emulăm o bază de date Redshift într-o configuraţie CI/CD, am întâmpinat problemele descrise mai sus. Pentru a le evita, ne-am gândit să iniţializăm baza de date în timpul construcţiei imaginilor. Am modificat scriptul de iniţializare al bazei de date, obţinând următorul proces:

Bucata de fișier Docker ce implementează funcţionalitatea de mai sus se află mai jos:

# source: https://github.com/kiasaki/
  docker-alpine-postgres
FROM alpine

RUN echo 
"@edge http://nl.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories && \
   apk update && \
   apk add curl "libpq@edge<9.7" 
   "postgresql-client@edge<9.7" "postgresql@edge<9.7"  
   "postgresql-contrib@edge<9.7" && \

 curl -o /usr/local/bin/gosu -sSL "https://github.com/tianon/gosu/releases/download/1.2/gosu-amd64" && \
    chmod +x /usr/local/bin/gosu && \
    apk del curl && \
    rm -rf /var/cache/apk/*

ENV LANG en_US.utf8
ENV PGDATA /var/lib/postgresql/data/

ENV POSTGRES_DB datastore
ENV POSTGRES_USER docker
ENV POSTGRES_PASSWORD letmein

RUN mkdir -p /opt/setup/data-scripts.d/
RUN mkdir -p /zdata/
COPY ./data-scripts.d/* /opt/setup/data-scripts.d/

WORKDIR /opt/setup/
COPY db-setup.sh /opt/setup/
COPY db-pack.sh /opt/setup/
COPY db-run.sh /opt/setup/

RUN ./db-setup.sh
RUN ./db-pack.sh

VOLUME $PGDATA

EXPOSE 5432

ENTRYPOINT [ "/opt/setup/db-run.sh" ]

CMD [ "postgres" ]

Din raţiuni de spaţiu, vom ignora procesele de împachetare/dezpachetare de scripturi, deși le puteţi găsi în aici. Partea care rămâne este raţionamentul produs la lansarea containerului - parte implementată în db-run.sh:

#!/bin/sh

set -e

if [ ! -f "$PGDATA/PG_VERSION" ]; then
    echo "Restoring $PGDATA ..."
    tar -xf /zdata/backup.tar -C $PGDATA
    sync
    echo "Done."
else
    echo 
      "$PGDATA was already there, skipping restore."
fi

echo "Launching command: $@ ..."
if [ "$1" = 'postgres' ]; then
    gosu postgres "$@"
else
    exec "$@"
fi

În timpul procesului de bootstrap al containerului, întreaga bază de date este dezpachetată și restaurată în datele din fișerul de încărcare, iar la final, serverul este lansat printr-un mnemonic "postgres".

Concluzii

Rularea containerului de mai sus a optimizat construirea de imagini cu aproape 15 minute - scripturile de iniţializare au conţinut aproape 2 milioane de intrări într-o tabelă, cu doar 5 câmpuri. Partea cea mai bună este că acest container a avut nevoie doar de 2 minute pentru procesul de bootstrap din imaginea de bază. Acest fapt a îmbunătăţit experienţa utilizatorului programator care va rula procesul debug local, utilizând o bază de date, foarte apropiată de ce se găsește în producţie.

Adaptările scripturilor de iniţializare a bazei de date sunt de dificultate moderată (nefiind deloc un aspect comun), dar rezultatul final a fost fiabil. Așadar, putem recomanda această abordare oricărei persoane care se află într-o situaţie similară.

NUMĂRUL 149 - Development with AI

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects