Budowanie frontendu przez Mavena w Dockerze

Budowanie frontendu przez Mavena w Dockerze
AP
  • Rejestracja:około 6 lat
  • Ostatnio:około 2 miesiące
  • Postów:164
1

Nie miałem pomysłu jak lepiej nazwać ten temat, postaram się więć wytłumaczyć.
Mam aplikację która składa się ze Springa oraz Angulara, całość znajduje się w jednym projekcie Mavenowym, podzielonym na dwa moduły. Dodatkowo nad wszystkim stoi Docker.
Mam więc folder parenta, który ma swój pom.xml

Kopiuj
    <groupId>com.example</groupId>
    <artifactId>parent-app</artifactId>
    <packaging>pom</packaging>
    <version>1.0</version>

    <parent>
       <groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.4.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modules>
        <module>app-ui</module>
        <module>app-server</module>
    </modules>

No i schodząc niżej, app-ui to wspomniany frontend Angularowy, który również ma swojego pom.xml, w którym odpalany jest plugin do zbudowania tego frontendu jak i zainstalowania node, npm, itp.

Kopiuj
	<parent>
		<groupId>com.example</groupId>
		<artifactId>parent-app</artifactId>
		<version>1.0</version>
	</parent>

     <artifactId>app-ui</artifactId>
     <version>1.0</version>

    <build>
        <plugins>
            <plugin>
                <groupId>com.github.eirslett</groupId>
                <artifactId>frontend-maven-plugin</artifactId>
                <version>1.3</version>
                <configuration>
                    <nodeVersion>v12.16.3</nodeVersion>
                    <npmVersion>6.12.1</npmVersion>
                    <workingDirectory>src/main/web/app-ui</workingDirectory>
                </configuration>
                <executions>
                    <execution>
                        <id>install node and npm</id>
                        <goals>
                            <goal>install-node-and-npm</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>npm install</id>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>npm run build</id>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                        <configuration>
                            <arguments>run build</arguments>
                        </configuration>
                    </execution>
                    <execution>
                        <id>prod</id>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                        <configuration>
                            <arguments>run-script build</arguments>
                        </configuration>
                        <phase>generate-resources</phase>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Jak się można domyśleć, w moim app-server jest plugin który kopiuje zbudowany /dist i wrzuca jako static resources mojej aplikacji Springowej.
No i to działa, gdy odpalam to bez dockera. Problem pojawia gdy wszystko odpalam poprzez Dockera, którego Dockerfile wygląda tak

Kopiuj
FROM maven:latest AS MAVEN_BUILD
COPY pom.xml /build/
COPY app-server/pom.xml /build/app-server/
COPY app-server/src /build/app-server/src
COPY app-ui/pom.xml /build/app-ui/
COPY app-ui/src /build/app-ui/src
WORKDIR /build
RUN mvn clean install

FROM openjdk:latest
WORKDIR /app
COPY --from=MAVEN_BUILD /build/app-server/target/app-server-1.0.war /app
EXPOSE 8080
CMD java -jar app-server-1.0.war

Problem zaczyna się pojawiać już przy budowaniu pierwszej częsci, czyli app-ui, w logach widzę że instalowany jest node i npm, czyli wszystko ok

[INFO] Installing node version v12.16.3
[INFO] Downloading https://nodejs.org/dist/v12.16.3/node-v12.16.3-linux-x64.tar.gz to /root/.m2/repository/com/github/eirslett/node/12.16.3/node-12.16.3-linux-x64.tar.gz

Ale potem, odpalane jest npm run build a pod spodem ng build, i to kończy się już błędem...

[INFO] > ng build
[INFO]
[ERROR] sh: ng: command not found
[ERROR] npm ERR! code ELIFECYCLE
[ERROR] npm ERR! syscall spawn
[ERROR] npm ERR! file sh
[ERROR] npm ERR! errno ENOENT
[ERROR] npm ERR! app-ui@0.0.0 build: ng build
[ERROR] npm ERR! spawn ENOENT
[ERROR] npm ERR!
[ERROR] npm ERR! Failed at the app-ui@0.0.0 build script.
[ERROR] npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

edytowany 2x, ostatnio: AngryProgrammer
NE
  • Rejestracja:ponad 7 lat
  • Ostatnio:4 miesiące
  • Postów:11
0

wewnątrz kontenera nie masz zainstalowanego angular cli globalnie (tak, żeby odpalać je z shella w dowolnym miejscu), możesz spróbować zainstalować go tak:

npm i -g @Angular/cli

AP
  • Rejestracja:około 6 lat
  • Ostatnio:około 2 miesiące
  • Postów:164
0

@Nevaan:
Jestem prawie pewien, że ten plugin mavenowy powinien to zrobić. W każdym razie, dorzuciłem takie coś na początku Dockerfile

Kopiuj
FROM node:latest
RUN npm i -g @angular/cli

Niestety, efekt jest taki sam jak wcześniej

NE
  • Rejestracja:ponad 7 lat
  • Ostatnio:4 miesiące
  • Postów:11
0

wiesz co, szczerze mówiąc nie korzystałem z dockerfile'ów które miały wiele komend FROM. z tego co widzę, że są osobne "warstwy". najprostszym rozwiązaniem powinno być dodatnie czegoś takiego do poma (przed npm run build):

Kopiuj
 <execution>
                        <id>npm install ng cli globally</id>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                        <configuration>
                            <arguments>install -g @angular/cli</arguments>
                        </configuration>
                    </execution>

AP
  • Rejestracja:około 6 lat
  • Ostatnio:około 2 miesiące
  • Postów:164
0

@Nevaan:
Zrobiłem tak jak mówisz

#15 131.8 [INFO] + @Angular/cli@11.0.5
#15 131.8 [INFO] added 254 packages from 201 contributors in 50.825s

A zaraz potem

#15 132.2 [ERROR] sh: ng: command not found

edytowany 1x, ostatnio: AngryProgrammer
NE
ja zwykle, jak trafie na taki problem, staram się wejść do kontenera (coś w stylu "docker exec -it ${id_kontenera} /bin/bash" ). u ciebie prawdopodobnie musisz usunąć ostatni block z FROM i oczywiście uruchomić jakiś proces tak, żeby kontener nie wyłączył się zaraz po wykonaniu poleceń z dockerfile
NE
no i jak uda ci się wejść do tego kontenera, to trzeba sprawdzić czy jest dostępna komenda "ng" w shellu
IV
  • Rejestracja:ponad 4 lata
  • Ostatnio:około 2 miesiące
  • Postów:30
0

Skoro w dockerze odbywa się budowanie to może zmień koncepcję i porzuć budowanie frontendu za pomocą mavena. Maven nadaje się do budowania aplikacji napisanych w javie, npm nadaje się do budowania aplikacji napisanych w angularze.
Przy okazji, każde FROM w Dockerfile to osobny stage w budowaniu dockerem, każdy stage to osobne pudełka, można kopiować pliki pomiędzy nimi, ale aplikacje nie są widoczne pomiędzy nimi.
Wracając do tematu, proponuję, abyś wywalił z pom.xml wszystko do budowania angulara i zrobił to mniej więcej tak:

Kopiuj
FROM node:latest AS node
SKOPIUJ PLIKI ANGULAROWE
ODPAL BUDOWANIE ANGULARA

FROM maven:latest AS maven
SKOPIUJ POM ORAZ ŹRÓDŁA JAVY
SKOPIUJ --from=node WYNIKI BUDOWANIA ANGULARA DO src/main/web/app-ui
ODPAL BUDOWANIE MAVEN

FROM openjdk:latest
SKOPIUJ --from=maven WYNIKI BUDOWANIA MAVENA
ODPAL APLIKACJE
AP
  • Rejestracja:około 6 lat
  • Ostatnio:około 2 miesiące
  • Postów:164
0

W końcu tak też zrobiłem, poszedłem nawet o krok dalej, tzn.

Kopiuj
FROM alpine:latest
RUN apk add maven
RUN apk add openjdk11
RUN apk add nodejs nodejs-npm
RUN npm install -g @angular/cli

I nawet to działa, w kolejnych krokach po prostu kopiuje /src i wszystko buduje, z Mavena wywaliłem plugin do budowania frontendu. Został jeden problem... odpalenie mongodb. Dorzuciłem coś takiego

Kopiuj
RUN echo 'http://dl-cdn.alpinelinux.org/alpine/v3.6/main' >> /etc/apk/repositories
RUN echo 'http://dl-cdn.alpinelinux.org/alpine/v3.6/community' >> /etc/apk/repositories
RUN apk update
RUN apk add mongodb
RUN mkdir -p data/db
RUN ./mongod &

Potem jest mvn clean install i java -jar ..., niestety problem w tym, że aplikacja nie wstaje, a to z powodu takiego że mongo nie działa. Jak wszedłem na ten kontener to faktycznie, mongo nie jest odpalone. Musiałem z poziomu CLI odpalić mongod i dopiero wtedy udało mi się odpalić aplikację. Czemu jednak nie mogę zrobić tego z poziomu Dockerfile?

Edit#
Jak w Dockerfile dam po prostu RUN ./mongod to wygląda to tak, mongo jest odpalone ale docker build image się po prostu nie kończy
screenshot-20201230225859.png

edytowany 1x, ostatnio: AngryProgrammer
IV
  • Rejestracja:ponad 4 lata
  • Ostatnio:około 2 miesiące
  • Postów:30
2

Wydaje mi się, że w dockerze jest przyjęta konwencja, że w kontenerze powinien być odpalony tylko jeden proces. Jak stopujesz kontener to do polecenia odpalonego za pomocą CMD jest wysyłany sygnał zatrzymania aplikacji. Tutaj mongo próbujesz odpalić w tle poza poleceniem CMD.
Jak chcesz mieć aplikację i bazę zdockeryzowaną to pownienieś odpalić dwa kontenery, a do jednego skryptu do odpalania kilku kontenerów może posłużyć docker compose.

Chciałbym jeszcze napisać, że budowanie za pomocą multistage w moim odczuciu jest lepszym rozwiązaniem niż użycie bazowego obrazu i instalowania na nim różnych aplikacji. Obraz puchnie, a przecież nie potrzebujesz nodejs ani mavena do uruchomienia aplikacji. Teraz w obrazie znajduje się wszystko co potrzebowałeś na każdym z kroków. Ale to tylko moja opinia.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)