Autor: Alex Barashkov

Mój obecny podstawowy pakiet technologii to Node.js / Javascript i, podobnie jak wiele zespołów, przeniosłem nasze środowiska programistyczne i produkcyjne do kontenerów Docker’a. Jednak gdy zacząłem uczyć się Dockera, zdałem sobie sprawę, że większość artykułów dotyczy środowisk programistycznych lub produkcyjnych i nie można znaleźć nic na temat tego, jak należy zorganizować konfigurację Docker’a, aby był elastyczny w obu przypadkach.

W tym artykule przedstawiam różne przypadki użycia i przykłady plików Node.js Dockerfiles, wyjaśnię proces podejmowania decyzji i pomogę wyobrazić sobie, w jaki sposób najlepiej korzystać z Docker’a. Zaczniemy od prostego przykładu, następnie przyjrzymy się bardziej skomplikowanym scenariuszom, aby zapewnić spójność pracy z Dockerem lub bez niego.

UWAGA: ten przewodnik jest duży i koncentruje się na różnych odbiorcach o różnych poziomach znajomości Docker’a; w niektórych punktach podane instrukcje będą dla ciebie oczywiste, ale postaram się dodać do nich odpowiednie punkty, aby zapewnić kompletną wizję ostatecznej konfiguracji.

Wymagania wstępne

  • VS Code
  • Docker
  • Rozszerzenie Docker dla VS Code

Opisane przypadki

  • Podstawowy plik Node.js Dockerfile i docker-compose
  • Nodemon w fazie rozwoju, węzeł w produkcji
  • Trzymanie obrazu Docker produkcyjnego z dala od devDependecies
  • Użycie wieloetapowej kompilacji dla obrazów wymagało obsługi node-gyp

Dodaj plik .dockerignore

Zanim zaczniemy konfigurować nasz plik Dockerfile, dodajmy plik .dockerignore do folderu aplikacji. Plik .dockerignore wyklucza się podczas kopiowania plików poleceń COPY / ADD opisanych w pliku.

Podstawowy plik Dockerfile Node.js

Aby zapewnić jasne zrozumienie, zaczniemy od podstawowego pliku Dockerfile, który można wykorzystać do prostych projektów Node.js. Mówiąc prościej, mam na myśli to, że twój kod nie ma żadnych dodatkowych natywnych zależności lub logiki budowania.

Znajdziesz coś takiego w każdym artykule Docker Node.js. Pokrótce przejdźmy przez to.

Workdir jest rodzajem domyślnego katalogu używanego dla instrukcji RUN, CMD, ENTRYPOINT, COPY i ADD. W niektórych artykułach zobaczysz, że ludzie robią mkdir / app, a następnie ustawiają go jako workdir, ale nie jest to najlepsza praktyka. Użyj wcześniej istniejącego folderu / usr / src / app, który jest lepiej przystosowany do tego.

Oto kolejne wykorzystanie najlepszych praktyk: skopiuj plik package.json i package-lock.json przed skopiowaniem kodu do kontenera. Docker będzie buforował zainstalowane moduły node_modules jako osobną warstwę, a następnie, jeśli zmienisz kod aplikacji i wykonasz polecenie budowania, moduł node_modules nie zostanie zainstalowany ponownie, jeśli nie zmienisz pliku package.json. Mówiąc ogólnie, nawet jeśli zapomnisz dodać tę linię, nie napotkasz wiele problemów. Zwykle trzeba uruchomić kompilację dockera tylko wtedy, gdy zmieniono pakiet package.json, co i tak prowadzi do instalacji od zera. W innych przypadkach nie uruchamia się zbyt często budowania dockera po początkowej kompilacji w środowisku programistycznym.

Moment, w którym wkracza doker-compose

Zanim zaczniemy uruchamiać naszą aplikację w produkcji, musimy ją rozwijać. Najlepszym sposobem na porządkowanie i uruchamianie środowiska dokowania jest korzystanie z funkcji dokowania. Zdefiniuj listę kontenerów / usług, które chcesz uruchomić i instrukcje dla nich w łatwej do użycia składni do dalszego działania w pliku YAML.

W przykładzie podstawowej konfiguracji docker-compose.yaml powyżej, kompilacja wykonana przy użyciu Dockerfile wewnątrz folderu aplikacji, wtedy folder aplikacji jest podłączony do kontenera, a node_modules, które są zainstalowane wewnątrz kontenera podczas kompilacji, nie zostaną przesłonięte przez twój obecny folder. Port 3000 jest narażony na twój localhost, zakładając, że masz uruchomiony serwer sieciowy. 9229 służy do ujawnienia portu debugowania. Czytaj więcej tutaj.

Teraz uruchom swoją aplikację za pomocą:

Lub użyj rozszerzenia VS Code do tego samego celu.

Za pomocą tego polecenia udostępniamy porty 3000 i 9229 w aplikacji Dockerized na localhost, następnie montujemy bieżący folder z aplikacją do / usr / src / app i używamy hacka, aby zapobiec nadpisywaniu modułów węzłów z komputera lokalnego przez Docker.

Czy możesz użyć tej Dockerfile w rozwoju i produkcji?
Tak i nie.

Różnice w CMD

Po pierwsze, zwykle chcesz, aby aplikacja środowiska programistycznego przeładowywała się podczas zmiany pliku. W tym celu możesz użyć nodemon. Ale w produkcji chcesz bez niego działać. Oznacza to, że CMD (polecenie) dla środowisk programistycznych i produkcyjnych musi być inne.

Istnieje kilka różnych opcji:

  1. Zastąp CMD poleceniem uruchomienia aplikacji bez nodemon, które może być oddzielnym zdefiniowanym poleceniem w pliku package.json, takim jak:

W takim przypadku plik Docker może wyglądać następująco:

Ponieważ jednak korzystasz z pliku do tworzenia dokowanego w środowisku programistycznym, możemy mieć w środku inne polecenie, dokładnie tak, jak w poprzednim przykładzie:

  1. Jeśli istnieje większa różnica lub używasz funkcji tworzenia dokowania do programowania i produkcji, możesz utworzyć wiele plików do tworzenia dokowanego lub plik Docker w zależności od różnic. Takich jak docker-compose.dev.yml lub Dockerfile.dev.

Zarządzanie instalacją pakietów

Zasadniczo lepiej jest, aby rozmiar obrazu produkcyjnego był jak najmniejszy i nie chcesz instalować zależności modułów węzłów, które są niepotrzebne do produkcji. Rozwiązanie tego problemu jest nadal możliwe dzięki zachowaniu jednego zunifikowanego pliku Docker.

Ponownie sprawdź plik package.json i podziel devDependencies niezależnie od zależności. Czytaj więcej tutaj. W skrócie, jeśli uruchomisz swoją instalację npm z flagą –production lub ustawisz NODE_ENV jako produkcję, wszystkie devDependencies nie zostaną zainstalowane. Dodamy dodatkowe linie do naszego pliku dokowanego, aby obsłużyć to:

Aby dostosować zachowanie, którego używamy

Docker obsługuje przekazywanie argumentów kompilacji za pomocą polecenia docker lub docker-compose. NODE_ENV = development będzie używany domyślnie, dopóki nie nadpiszemy go inną wartością. Dobre wyjaśnienie, które można znaleźć tutaj.

Teraz, kiedy budujesz swoje pojemniki za pomocą pliku do tworzenia dokowanego, wszystkie zależności zostaną zainstalowane, a kiedy budujesz je do produkcji, możesz przekazać argument budowania, ponieważ produkcja i zależności będą ignorowane. Ponieważ używam usług CI do budowania kontenerów, po prostu dodaję tę opcję do ich konfiguracji. Czytaj więcej tutaj

Używanie wieloetapowej kompilacji dla obrazów wymagających obsługi node-gyp

Nie każda aplikacja, którą spróbujesz uruchomić w Dockerze, będzie korzystać wyłącznie z zależności JS, niektóre z nich wymagają zainstalowanych bibliotek węzłowych i dodatkowych natywnych zainstalowanych bibliotek.

Aby rozwiązać ten problem, możemy użyć wieloetapowych kompilacji, które pomagają nam instalować i budować wszystkie zależności w oddzielnym kontenerze i przenosić tylko wynik instalacji bez żadnych śmieci do końcowego kontenera. Plik Docker może wyglądać tak:

W tym przykładzie zainstalowaliśmy i skompilowaliśmy wszystkie zależności w oparciu o środowisko na pierwszym etapie, a następnie skopiowaliśmy moduł node_modules w drugim etapie, który wykorzystamy w środowisku programistycznym i produkcyjnym.

Wiersz RUN apk –no-cache add python make g ++ może się różnić od projektu do projektu, prawdopodobnie dlatego, że będziesz potrzebował dodatkowych zależności.

W tej linii kopiujemy folder node_modules z pierwszego etapu do folderu node_modules w drugim etapie. Z tego powodu w drugim etapie ustawiamy WORKDIR jako / usr / src / app, moduł node_modules zostanie skopiowany do tego folderu.

Podsumowanie

Mam nadzieję, że ten przewodnik pomógł wam zrozumieć, jak zorganizować plik Dockerfile i czy służy on waszym potrzebom zarówno w środowiskach programistycznych, jak i produkcyjnych.

Możemy podsumować nasz poradnik w następujący sposób:

  • Spróbuj ujednolicić plik Dockerfile dla środowisk programistycznych i produkcyjnych; jeśli to nie działa, podziel je.
  • Nie instaluj dev node_modules dla wersji produkcyjnych.
  • Nie pozostawiaj zależności natywnych rozszerzeń wymaganych do instalacji modułu node-gyp i węzłów w obrazie końcowym.
  • Użyj funkcji doker-compose, aby sterować konfiguracją programistyczną.

Alex Barashkov
– CEO Pixel Point. Doświadczony Web Developer, Product Manager, z ośmioletnim doświadczeniem w prowadzeniu wszystkich aspektów różnorodnych projektów.

 

 

IT-Leaders.pl – to platforma rekrutacyjna dla sektora IT, która odwraca tradycyjne role: Kandydat – Rekruter. Szybki sposób kojarzenia kandydatów z pracodawcami i z góry znane oczekiwania finansowe sprawiają, że strony nie tracą czasu na rozmowy z niedopasowanymi firmami czy kandydatami.

Wystarczy, że raz założysz konto, określisz oczekiwania finansowe a pracodawcy sami będą do Ciebie aplikować.

Zmieniamy zasady gry. To Ty wybierasz pracodawcę!
www.it-leaders.pl