Próbuję połączyć 2 oddzielne kontenery:
Problem w tym, że skrypty php nie działają. Być może konfiguracja php-fpm jest nieprawidłowa. Oto kod źródłowy, który jest w moim repozytorium . Oto plik docker-compose.yml
:
nginx:
build: .
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www/test/
links:
- fpm
fpm:
image: php:fpm
ports:
- "9000:9000"
i Dockerfile
którego użyłem do zbudowania niestandardowego obrazu na podstawie nginx:
FROM nginx
# Change Nginx config here...
RUN rm /etc/nginx/conf.d/default.conf
ADD ./default.conf /etc/nginx/conf.d/
Na koniec, oto moja niestandardowa konfiguracja wirtualnego hosta Nginx:
server {
listen 80;
server_name localhost;
root /var/www/test;
error_log /var/log/nginx/localhost.error.log;
access_log /var/log/nginx/localhost.access.log;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/.+\.php(/|$) {
fastcgi_pass 192.168.59.103:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
Czy ktoś mógłby mi pomóc poprawnie skonfigurować te kontenery do wykonywania skryptów php?
PS Kontenery uruchamiam przez docker-composer w ten sposób:
docker-compose up
z katalogu głównego projektu.
php
nginx
docker
dockerfile
docker-compose
Victor Bocharsky
źródło
źródło
docker exec
przejść do uruchomionego kontenera i pingować fpm?Nginx
iPHP-FPM
razem z Vagrant i Ansible. Sprawdź moje repozytorium github.com/bocharsky-bw/vagrant-ansible-docker, jeśli chcesz.Odpowiedzi:
Nie koduj na stałe adresu IP kontenerów w konfiguracji nginx, link docker dodaje nazwę hosta połączonej maszyny do pliku hosts kontenera i powinieneś być w stanie pingować według nazwy hosta.
EDYCJA: Docker 1.9 Networking nie wymaga już łączenia kontenerów, gdy wiele kontenerów jest podłączonych do tej samej sieci, ich plik hosts zostanie zaktualizowany, aby mogły się ze sobą łączyć za pomocą nazwy hosta.
Za każdym razem, gdy kontener docker obraca się z obrazu (nawet zatrzymuje / uruchamia istniejący kontener), kontenery otrzymują nowe adresy IP przypisane przez hosta dockera. Te adresy IP nie znajdują się w tej samej podsieci, co rzeczywiste komputery.
zobacz dokumenty z linkami do dockera (tego używa redagowanie w tle)
ale dokładniej wyjaśniono w
docker-compose
dokumentach na temat linków i ekspozycjia jeśli skonfigurujesz swój projekt, aby uzyskać porty i inne dane uwierzytelniające za pośrednictwem zmiennych środowiskowych, łącza automatycznie ustawią kilka zmiennych systemowych :
źródło
--links
są teraz przestarzałe, zgodnie z dokumentacją dockera, do której się odnosisz. Są one nadal aktualnie obsługiwane, ale pozorny plan jest dla nich być zastąpiony.Wiem, że to dość stary post, ale miałem ten sam problem i nie mogłem zrozumieć, dlaczego twój kod nie działa. Po wielu testach dowiedziałem się, dlaczego.
Wygląda na to, że fpm otrzymuje pełną ścieżkę z nginx i próbuje znaleźć pliki w kontenerze fpm, więc musi być dokładnie taka sama jak
server.root
w konfiguracji nginx, nawet jeśli nie istnieje w kontenerze nginx.Aby zademonstrować:
docker-compose.yml
/etc/nginx/conf.d/default.conf
Dockerfile
źródło
/var/www/html
z niepowodzeniem.:9000
jest to port używany w kontenerze, a nie ten, który jest widoczny dla twojego hosta. Zajęło mi to 2 godziny, zanim to rozgryzłem. Miejmy nadzieję, że nie musisz.services.fpm.ports is invalid: Invalid port ":9000", should be [[remote_ip:]remote_port[-remote_port]:]port[/protocol]
ports
sekcji. Możesz go po prostu potrzebowaćexpose
, jeśli nie ma go już na obrazie (a prawdopodobnie tak jest). Jeśli wykonujesz komunikację między kontenerami, nie powinieneś ujawniać portu PHP-FPM.AH01071: Got error 'Primary script unknown\n'
i że kontener php-fpm musi dzielić ten sam katalog z węzłami sieciowymi, było rozwiązaniem!Jak wspomniano wcześniej, problem polegał na tym, że pliki nie były widoczne przez kontener fpm. Jednak do udostępniania danych między kontenerami zalecany wzorzec używa kontenerów tylko do danych (jak wyjaśniono w tym artykule ).
Krótko mówiąc: utwórz kontener, który po prostu przechowuje Twoje dane, udostępnij go woluminowi i połącz ten wolumin w swoich aplikacjach z
volumes_from
.Używając redagowania (1.6.2 na moim komputerze),
docker-compose.yml
plik miałby postać:Zwróć uwagę, że
data
publikuje wolumin połączony z usługaminginx
ifpm
. NastępnieDockerfile
za dane usługi, która zawiera kod źródłowy:A
Dockerfile
dla nginx, który po prostu zastępuje domyślną konfigurację:Ze względu na zakończenie, oto plik konfiguracyjny wymagany do działania przykładu:
który po prostu mówi nginx, aby używał współdzielonego woluminu jako katalogu głównego dokumentu i ustawia odpowiednią konfigurację dla nginx, aby móc komunikować się z kontenerem fpm (tj: prawo
HOST:PORT
, które jestfpm:9000
dzięki nazwom hostów zdefiniowanym przez compose iSCRIPT_FILENAME
).źródło
Dockerfile
kontener danych kopiuje źródła do kontenera w czasie kompilacji. Dlatego nie zostaną zaktualizowane, jeśli zmienisz pliki na hoście. Jeśli chcesz udostępniać źródła między hostem a kontenerem, musisz zamontować katalog. Zmieńdata
usługę w pliku redagowania do załadowaniaimage: busybox
, awvolumes
sekcji wprowadź./sources:/var/www/html
, gdzie./sources
jest ścieżka do źródeł na hoście.Nowa odpowiedź
Docker Compose został zaktualizowany. Mają teraz format pliku w wersji 2 .
Obsługują teraz funkcję sieciową Dockera, która po uruchomieniu konfiguruje domyślną sieć o nazwie myapp_default
Z ich dokumentacji Twój plik wyglądałby jak poniżej:
Ponieważ te kontenery są automatycznie dodawane do domyślnej sieci myapp_default , będą mogły ze sobą rozmawiać. Miałbyś wtedy w konfiguracji Nginx:
fastcgi_pass fpm:9000;
Jak wspomniał @treeface w komentarzach, pamiętaj, aby upewnić się, że PHP-FPM nasłuchuje na porcie 9000, można to zrobić edytując
/etc/php5/fpm/pool.d/www.conf
tam, gdzie będzie to potrzebnelisten = 9000
.Stara odpowiedź
Zachowałem poniżej tutaj dla tych, którzy używają starszej wersji tworzenia Docker / Docker i chcą uzyskać informacje.
Ciągle natknąłem się na to pytanie w Google, próbując znaleźć odpowiedź na to pytanie, ale nie było to do końca to, czego szukałem, ze względu na nacisk Q / A na docker-compose (który w czasie pisania ma tylko eksperymentalne wsparcie dla funkcje sieciowe Dockera). Oto moje spojrzenie na to, czego się nauczyłem.
Docker niedawno wycofał funkcję łącza na rzecz funkcji sieci
Dlatego za pomocą funkcji Docker Networks można łączyć kontenery, wykonując następujące kroki. Aby uzyskać pełne wyjaśnienia dotyczące opcji, przeczytaj wcześniej powiązane dokumenty.
Najpierw utwórz swoją sieć
Następnie uruchom kontener PHP-FPM, otwierając port 9000 i przypisując go do nowej sieci (
mynetwork
).Ważny jest tutaj
--name php-fpm
koniec polecenia, którym jest nazwa, będziemy potrzebować później.Następnie ponownie uruchom kontener Nginx i przypisz go do utworzonej sieci.
W przypadku kontenerów PHP i Nginx możesz również dodać
--volumes-from
polecenia itp. Zgodnie z wymaganiami.Teraz nadchodzi konfiguracja Nginx. Który powinien wyglądać podobnie do tego:
Zwróć uwagę na
fastcgi_pass php-fpm:9000;
w bloku lokalizacji. To mówi kontener kontaktowyphp-fpm
w porcie9000
. Po dodaniu kontenerów do sieci mostu Docker wszystkie one automatycznie otrzymują aktualizację pliku hostów, która umieszcza nazwę kontenera w stosunku do adresu IP. Więc kiedy Nginx zobaczy, że będzie wiedział, jak skontaktować się z kontenerem PHP-FPM, który nazwałeśphp-fpm
wcześniej i przypisałeś do swojejmynetwork
sieci Docker.Możesz dodać tę konfigurację Nginx podczas procesu budowania kontenera Docker lub później, zależy to od Ciebie.
źródło
php-fpm
nasłuchuje na porcie 9000. To będzielisten = 9000
w/etc/php5/fpm/pool.d/www.conf
.Tak jak poprzednie odpowiedzi rozwiązały, ale należy to wyraźnie określić: kod php musi znajdować się w kontenerze php-fpm, podczas gdy pliki statyczne muszą znajdować się w kontenerze nginx. Dla uproszczenia większość ludzi właśnie dołączyła cały kod do obu, tak jak to zrobiłem poniżej. Jeśli w przyszłości prawdopodobnie wyodrębnię te różne części kodu we własnych projektach, aby zminimalizować, które kontenery mają dostęp do których części.
Zaktualizowałem moje przykładowe pliki poniżej o najnowsze objawienie (dziękuję @alkaline)
Wydaje się, że jest to minimalna konfiguracja dla Dockera 2.0 do przodu (ponieważ w Docker 2.0 jest dużo łatwiej)
docker-compose.yml:
( ZAKTUALIZOWANO powyższy docker-compose.yml : w przypadku witryn, które mają css, javascript, pliki statyczne itp., Będziesz potrzebować tych plików dostępnych dla kontenera nginx. Cały kod php będzie nadal dostępny dla kontenera fpm. Ponownie, ponieważ mój kod podstawowy to niechlujna mieszanka css, js i php, ten przykład po prostu dołącza cały kod do obu kontenerów)
W tym samym folderze:
site.conf:
W kodzie folderu:
./code/index.php:
i nie zapomnij zaktualizować pliku hosts:
i uruchom docker-compose
i wypróbuj adres URL ze swojej ulubionej przeglądarki
źródło
Myślę, że musimy również nadać pojemnikowi fpm objętość, prawda? Więc =>
Jeśli tego nie zrobię, napotkam ten wyjątek podczas uruchamiania żądania, ponieważ fpm nie może znaleźć żądanego pliku:
źródło
Nginx
iPHP-FPM
na GitHubDla kogokolwiek innego
podczas używania
index.php
whileindex.html
działa doskonale i po uwzględnieniuindex.php
w indeksie w bloku serwera konfiguracji witryny w formaciesites-enabled
Upewnij się, że plik nginx.conf w
/etc/nginx/nginx.conf
rzeczywistości ładuje konfigurację witryny whttp
bloku ...źródło