Cel ćwiczenia: Wykorzystanie konteneryzacji do przygotowania środowiska deweloperskiego aplikacji o rozproszonej architekturze
Przed przejściem do wykonania zadania, przetestuj wpierw działanie aplikacji bez dockera.
Do uruchomienia aplikacji potrzebne są:
- Git do sklonowania repo
- Node.js w wersji 12.16.3 (aplikacja działa również na wersji 10.19.0, dostępnej domyślnie w repo apt na Ubuntu) jako środowisko uruchomieniowe serwera oraz npm do jego wystartowania i instalacji zależności
- Nginx do uruchomienia klienta (można również przez npm)
- mysql/mariadb jako baza danych
- Sklonuj repozytorium za pomocą
git clone
(lub wbudowanego narzędzia w IDE). - Uruchom bazę danych i wykonaj import ze skryptu:
Jeżeli wymagane jest hasło, dodaj opcję
mysql -uroot < /path/to/db.sql
-p
. Jest też możliwość wykorzystania poleceniasudo
do połączenia się przez Unix socket jako root (serwer BD musi znajdować się na maszynie, z której uruchamiane jest polecenie):sudo mysql < /path/to/db.sql
- Zainstaluj wszystkie zależności serwera, uruchamiając z katalogu server komendę
npm install
. - Uruchom serwer komendą
npm run dev
. - Zainstaluj zależności aplikacji klienckiej, uruchamiając w katalogu client komendę
npm install
. - Aplikację frontendową można uruchomić na dwa sposoby:
- W wersji deweloperskiej, z wykorzystaniem polecenia
npm start
. - Produkcyjnie: zbuduj projekt poleceniem
npm run build
. Zostanie utworzony katalog build z produkcyjną wersją aplikacji. Uruchom serwer nginx i umieść zawartość katalogu client w RootDirectory (Nginx). Przykładowa nazwa katalogu: docker-ui. Przykładowy config, za pomocą którego można uruchomić tą aplikację znajduje się w katalogu client/nginx.conf. Wymaga on pewnych modyfikacji.
- W wersji deweloperskiej, z wykorzystaniem polecenia
- W przeglądarce wejdź pod adres klienta z punktu 5. W przypadku nginx, domyślnie localhost/nazwa_serwisu, np. localhost/docker-ui. Jeżeli apka uruchamiana jest w wersji deweloperskiej, wówczas będzie to adres localhost:3000.
- Poprawnie skonfigurowana aplikacja wyświetli listę produktów.
- Uruchom aplikacje w dockerze, korzystając z docker-cli. Stwórz odpowiednie Dockerfile:
- Node.js. Uruchom serwer poleceniem
npm start
. Sprawdź poprawność działania, uruchamiając w przeglądarce endpoint: localhost:8080/api/. - MySQL lub MariaDB. Zaimportuj schemat ze skryptu db.sql. Wykorzystaj docker volume do przechowania stanu bazy danych. Import można wykonać wykorzystując docker-cli lub pisząc odpowiedni Dockerfile.
- Nginx. Kod źródłowy nie powinien znajdować się w kontenerze. Wykorzystaj w tym celu multi-stage build. W pierwszym stagu zbuduj projekt (
npm run build
), w drugim skopiuj build do nginx'a.
- Node.js. Uruchom serwer poleceniem
- Jeśli kontenery uruchamiają się bez błędów, przejdź do połączenia ich ze sobą, by klient wyświetlał poprawne dane.
- Serwer: Pamiętaj, by ustawić odpowiednie zmienne środowiskowe, zawarte w pliku .env, które wykorzystane zostały w configu.
- Baza danych: Sprawdź, czy istnieje możliwość podłączenia się do bazy:
docker exec -it container_name mysql -udockerdb -p
- Klient: W kontenerze należy uruchomić wersję produkcyjną aplikacji. Należy pamiętać, by nginx'a odwoływał się do poprawnych hostów. Config nginx powinien zawierać odpowiedni upstream do backendu, tak aby można było skonfigurować do niego proxy. Prawidłowy config znajduje się już w katalogu z klientem. Przeanalizuj jego budowę i opisz w sprawozdaniu.
- Połącz odpowiednie kontenery ze sobą, korzystając z nazw kontenerów, zamiast adresów IP, korzystając wyłącznie z docker-cli.
- Stwórz następującą konfigurację w formie docker-compose.yml. Za
x
podstaw wartość obliczoną wg wzoru:numer_albumu mod 200
. Na maszynę hosta udostępnij wyłącznie port do aplikacji klienckiej.
- Wydziel zmienne środowiskowe charakterystyczne dla różnych serwisów. Możesz w tym celu wykorzystać plik dotenv (.env).
- Wykorzystaj .dockerignore, by nie kopiować zbędnych plików i katalogów. Dotyczy to w szczególności kluczy, passphrasów, tokenów, itp. W niniejszym projekcie takie dane zawarte zostały w pliku .env.
- Jeżeli wskazana w zadaniu pula adresów koliduje z Waszym DHCP, możecie zmienić ją na inną.
- Przemyśl kwestię przechowywania stanu bazy danych. Usunięcie kontenera (lub
docker-compose down -v
) spowoduje usunięcie danych zawartych w bazie, w tym stworzonych wolumenów. Dla środowisk testowych nie jest to problemem, gdyż baza testowa zwykle nie ulega częstym zmianom i import ze skryptu wystarczy. Jednak w przypadku środowiska produkcyjnego jest to niedopuszczalne. Więcej info. - W sprawozdaniu należy przedstawić sposób dojścia do finalnego rozwiązania. Proszę zawrzeć stosowne Dockerfile, komendy CLI, a w przypadku ostatniego zadania docker-compose. Opis powinien być sformułowany w sposób umożliwiający odtworzenie przebiegu ćwiczenia.
- https://docs.docker.com/compose/networking/
- https://docs.docker.com/compose/
- https://docs.docker.com/network/network-tutorial-standalone/
- https://stackoverflow.com/questions/43322033/create-database-on-docker-compose-startup/43324472
- https://www.digitalocean.com/community/questions/how-to-ping-docker-container-from-another-container-by-name
- https://dev.to/sonyarianto/how-to-spin-mysql-server-with-docker-and-docker-compose-33b2
- https://runnable.com/docker/rails/docker-container-linking
- https://serverfault.com/questions/989046/docker-compose-only-exposing-one-network-to-the-outside-world