2016-08-04 19 views
5

Zostałem poproszony przez dev ops w firmie, w której pracuję, aby zrobić coś nieco innego z Dockerem, wtedy też jestem używany. Celem jest posiadanie 2 pojemników o następujących obowiązkach:Wymieniony wolumen Docker udostępniający kompilację nie aktualizuje się

Kontener A: Pojemnik węzła, który zbuduje aplikację reagującą na frontend i umieści pakiet w katalogu o nazwie app/dist/. Po zakończeniu pojemnik przestanie działać.

Kontener B: Pojemnik alpejski nginx, który będzie serwer plików statycznych z /usr/share/nginx/html/app.

Pliki, które zostały zbudowane w kontenerze A, zostaną dostarczone do kontenera B przy użyciu woluminu, który będzie montował <Container A>/app/dist na <Container B>/usr/share/nginx/html/app.

Należy zauważyć, że pomiędzy ogólnodostępnym portem a kontenerem nginx znajduje się warstwa HAProxy, która jest kontenerem o nazwie app.

Zadania powyżej są zaaranżowane przy użyciu pliku tworzenia, Döcker który wygląda tak:

version: '2' 
volumes: 
    webapp_build_volume: {} 
services: 
    webapp_build: 
    build: 
     context: . 
     dockerfile: 'config/nginx/dockerfile-builder' 
    volumes: 
     - webapp_build_volume:/app/dist 
     - webapp_static_volume:/app/src/app/static 
    app: 
    build: 
     context: 'config/haproxy' 
     dockerfile: 'dockerfile-app-haproxy' 
    links: 
     - web 
    volumes: 
     - /var/run/docker.sock:/var/run/docker.sock 
    ports: 
     - '80:80' 
     - '1936:1936' 
    web: 
    build: 
     context: . 
     dockerfile: 'config/nginx/dockerfile-web' 
    environment: 
     - EXCLUDE_PORTS=443 
     - VIRTUAL_HOST=* 
    depends_on: 
     - webapp_build 
    volumes: 
     - webapp_build_volume:/usr/share/nginx/html/app 

ten pracuje obecnie tylko za pierwszym razem plik komponować doker jest zbudowany. Pliki w woluminie nie są już aktualizowane po utworzeniu woluminu. Czytałem, że nazwane woluminy nie mogą być aktualizowane po ich utworzeniu, ale nie mogę tego potwierdzić. Znalazłem work arounds, które wymagają uruchomienia docker-compose rm --force && docker volume webapp_build rm, ale nie chciałbym zabijać kontenerów buforowanych, jeśli to możliwe, ponieważ usługa CI będzie działać zbyt wolno.

Proszę dać mi znać, jeśli mogę coś wyjaśnić (rozumiem, że tutaj jest dużo ruchomych części). Uwaga Używam również wersji beta docker 2, ale nie widzę, jak to mogło zmienić wszystko, co tutaj zrobiłem.

Odpowiedz

4

To trochę trudne do naśladowania, ale wygląda na to, że budujesz obraz, wyświetlając pliki w woluminie i próbujesz go użyć do wypełnienia nazwanego woluminu używanego przez inny uruchomiony kontener.

Najprawdopodobniej twój błąd polega na tym, że budowanie kontenera nie zajmuje się wolumenami, woluminy są montowane tylko w działających kontenerach. Nazwany wolumin ma funkcję, w której będzie zapełniany zawartością obrazu, ale tylko wtedy, gdy zamontowany zostanie nazwany wolumin, który jest pusty. Wygląda na to, że korzystasz z tej funkcji podczas pierwszego uruchomienia build +, ale nie będzie działać ponownie w przyszłych wersjach. Jeśli uruchomisz kontener budowania bez woluminu, okaże się, że Twoje pliki są tam, gdzie oczekiwano.

Możesz łatwo zaktualizować nazwany wolumin. Dwie opcje przychodzą na myśl. Jedną z nich jest użycie bieżącego procesu, ale zmiana punktu podłączenia woluminu na coś takiego jak "/ target" i jako CMD kontenera kompilacji, skopiuj zawartość źródła do "/ target". Że będzie wyglądać następująco:

Dockerfile

... 
RUN compile-cmd --output-to /local/build/dir 

entrypoint.sh:

cp -a /local/build/dir/* /target/ 

doker-komponować.yml:

version: '2' 
services: 
    webapp_build: 
    build: 
     context: . 
     dockerfile: 'config/nginx/dockerfile-builder' 
    volumes: 
     - webapp_build_volume:/target 
... 

Druga opcja to nie to zrobić w produkcji kontenerów w ogóle, ale raczej uczynić pojemnik z aplikacją kompilacji warunki. Następnie podłącz swój kod aplikacji jako wolumin do tego kontenera za pomocą CMD lub ENTRYPOINT, który pobiera zawartość woluminu kodu, kompiluje ją i wysyła do wymienionego woluminu, który jest również montowany. Następnie, zamiast budować kontener budujący, wystarczy uruchomić kontener kompilacji z zamontowanymi dwoma woluminami.

entrypoint.sh:

compile-cmd --input-src=/source --output-to /target 

dokowanym-compose.yml:

version: '2' 
services: 
    webapp_build: 
    volumes: 
     - app/source:/source 
     - webapp_build_volume:/target 
... 
+0

Próba Roztwór 1 obecnie. Wkrótce Cię powiadomię! – Shawn

+0

dziękuję. Twoje pierwsze rozwiązanie działało tam. Dlaczego powoduje to aktualizację woluminu, ale budowanie w katalogu nie było możliwe? – Shawn

+3

Zbudowałeś katalog, ale podczas kompilacji wolumin nie został zamontowany, a dzieje się to po uruchomieniu kontenera. Po zamontowaniu woluminu w uruchomionym kontenerze Docker kopiuje tylko zawartość z obrazu do woluminu, gdy wolumin jest pusty, aw późniejszym czasie ten krok inicjowania woluminu nie jest wykonywany (w przeciwnym razie można by zniszczyć zawartość, gdy próbujesz użyć woluminu w drugim pojemniku). – BMitch