Estou tentando vincular 2 contêineres separados:
O problema é que os scripts php não funcionam. Talvez a configuração do php-fpm esteja incorreta. Aqui está o código-fonte, que está em meu repositório . Aqui está o arquivo docker-compose.yml
:
nginx:
build: .
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www/test/
links:
- fpm
fpm:
image: php:fpm
ports:
- "9000:9000"
e Dockerfile
que usei para criar uma imagem personalizada com base no nginx:
FROM nginx
# Change Nginx config here...
RUN rm /etc/nginx/conf.d/default.conf
ADD ./default.conf /etc/nginx/conf.d/
Por último, aqui está minha configuração de host virtual Nginx personalizada:
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;
}
}
Alguém poderia me ajudar a configurar esses containers corretamente para executar scripts php?
PS: Eu executo contêineres por meio do docker-composer assim:
docker-compose up
do diretório raiz do projeto.
php
nginx
docker
dockerfile
docker-compose
Victor Bocharsky
fonte
fonte
docker exec
entrar no contêiner em execução e executar ping no fpm?Nginx
e emPHP-FPM
conjunto com o Vagrant e o Ansible. Verifique meu repositório github.com/bocharsky-bw/vagrant-ansible-docker se desejar.Respostas:
Não codifique o ip dos contêineres na configuração do nginx, o docker link adiciona o nome do host da máquina vinculada ao arquivo hosts do contêiner e você deve ser capaz de fazer ping pelo nome do host.
EDIT: Docker 1.9 Networking não requer mais que você vincule containers, quando vários containers estão conectados à mesma rede, seu arquivo de hosts será atualizado para que eles possam se comunicar pelo nome do host.
Cada vez que um contêiner docker gira a partir de uma imagem (mesmo parando / iniciando um contêiner existente), os contêineres recebem novos IPs atribuídos pelo host docker. Esses ips não estão na mesma sub-rede que suas máquinas reais.
ver docs de vinculação do docker (é isso que o Compose usa em segundo plano)
mas explicado de forma mais clara nos
docker-compose
documentos sobre links e exposiçãoe se você configurar seu projeto para obter as portas + outras credenciais por meio de variáveis de ambiente, os links definirão automaticamente um monte de variáveis de sistema :
fonte
--links
agora estão obsoletos, de acordo com a documentação do docker que você faz referência. Eles ainda são suportados atualmente, mas o plano aparente é que se tornem obsoletos.Eu sei que é um post antigo, mas eu tive o mesmo problema e não conseguia entender porque seu código não funcionava. Depois de MUITOS testes, descobri o porquê.
Parece que o fpm recebe o caminho completo do nginx e tenta encontrar os arquivos no contêiner fpm, então deve ser exatamente o mesmo que
server.root
na configuração do nginx, mesmo que não exista no contêiner nginx.Para demonstrar:
docker-compose.yml
/etc/nginx/conf.d/default.conf
Dockerfile
fonte
/var/www/html
com falha.:9000
é a porta que está sendo usada no contêiner, não a que está exposta ao seu host. Levei 2 horas para descobrir isso. Felizmente, você não precisa.services.fpm.ports is invalid: Invalid port ":9000", should be [[remote_ip:]remote_port[-remote_port]:]port[/protocol]
ports
seção aqui. Você só precisa fazerexpose
isso se ainda não estiver na imagem (o que provavelmente está). Se você estiver fazendo comunicação entre contêineres, não deve expor a porta PHP-FPM.AH01071: Got error 'Primary script unknown\n'
e que o container php-fpm tivesse que compartilhar o mesmo diretório com os nós da web foi a solução!Como apontado antes, o problema era que os arquivos não eram visíveis pelo contêiner fpm. No entanto, para compartilhar dados entre contêineres, o padrão recomendado é usar contêineres somente de dados (conforme explicado neste artigo ).
Resumindo a história: crie um contêiner que apenas armazene seus dados, compartilhe-os com um volume e vincule esse volume em seus aplicativos com
volumes_from
.Usando compose (1.6.2 em minha máquina), o
docker-compose.yml
arquivo seria:Observe que
data
publica um volume que está vinculado aos serviçosnginx
efpm
. Em seguida,Dockerfile
para o serviço de dados , que contém seu código-fonte:E o
Dockerfile
para nginx, que apenas substitui a configuração padrão:Para fins de conclusão, aqui está o arquivo de configuração necessário para o exemplo funcionar:
que apenas diz ao nginx para usar o volume compartilhado como raiz do documento e define a configuração correta para que o nginx seja capaz de se comunicar com o contêiner fpm (isto é: o correto
HOST:PORT
, que éfpm:9000
graças aos nomes de host definidos por compose, e oSCRIPT_FILENAME
).fonte
Dockerfile
do contêiner de dados está copiando suas fontes para o contêiner em tempo de construção. É por isso que eles não serão atualizados se você alterar os arquivos no host. Se você deseja compartilhar as fontes entre o host e o contêiner, você precisa montar o diretório. Altere odata
serviço no arquivo de composição a ser carregadoimage: busybox
e, navolumes
seção entre./sources:/var/www/html
, onde./sources
está o caminho para suas fontes no host.Nova Resposta
O Docker Compose foi atualizado. Eles agora têm um formato de arquivo da versão 2 .
Eles agora suportam o recurso de rede do Docker que, quando executado, configura uma rede padrão chamada myapp_default
Pela documentação, seu arquivo seria parecido com o seguinte:
Como esses contêineres são adicionados automaticamente à rede padrão myapp_default , eles podem se comunicar entre si. Você teria então na configuração do Nginx:
fastcgi_pass fpm:9000;
Também como mencionado por @treeface nos comentários, lembre-se de garantir que o PHP-FPM esteja ouvindo na porta 9000, isso pode ser feito editando
/etc/php5/fpm/pool.d/www.conf
onde for necessáriolisten = 9000
.Resposta Antiga
Eu mantive o abaixo aqui para aqueles que usam uma versão mais antiga do Docker / Docker compose e gostariam das informações.
Continuei tropeçando nessa questão no Google ao tentar encontrar uma resposta para ela, mas não era bem o que eu estava procurando devido à ênfase de Q / A em docker-compose (que no momento em que este artigo foi escrito apenas tem suporte experimental para recursos de rede do docker). Portanto, aqui está minha opinião sobre o que aprendi.
Docker suspendeu recentemente seu recurso de link em favor de seu recurso de rede
Portanto, usando o recurso Docker Networks, você pode vincular containers seguindo estas etapas. Para obter explicações completas sobre as opções, leia os documentos vinculados anteriormente.
Primeiro crie sua rede
Em seguida, execute seu contêiner PHP-FPM garantindo que você abra a porta 9000 e atribua à sua nova rede (
mynetwork
).A parte importante aqui é o
--name php-fpm
no final do comando que é o nome, vamos precisar disso mais tarde.Em seguida, execute seu contêiner Nginx novamente para atribuir à rede que você criou.
Para os contêineres PHP e Nginx, você também pode adicionar
--volumes-from
comandos, etc., conforme necessário.Agora vem a configuração do Nginx. Que deve ser semelhante a isto:
Observe o
fastcgi_pass php-fpm:9000;
no bloco de localização. Isso está dizendo contêiner de contatophp-fpm
no porto9000
. Quando você adiciona contêineres a uma rede de ponte Docker, todos eles obtêm automaticamente uma atualização do arquivo de hosts que coloca o nome do contêiner em relação ao endereço IP. Portanto, quando o Nginx vir que saberá entrar em contato com o contêiner PHP-FPM que você nomeouphp-fpm
anteriormente e atribuiu à suamynetwork
rede Docker.Você pode adicionar essa configuração do Nginx durante o processo de criação do seu contêiner do Docker ou depois disso, depende de você.
fonte
php-fpm
está escutando na porta 9000. Isso serialisten = 9000
em/etc/php5/fpm/pool.d/www.conf
.Como as respostas anteriores resolveram, mas devem ser declaradas muito explicitamente: o código php precisa viver no contêiner php-fpm, enquanto os arquivos estáticos precisam viver no contêiner nginx. Para simplificar, a maioria das pessoas apenas anexou todo o código a ambos, como também fiz abaixo. No futuro, provavelmente irei separar essas diferentes partes do código em meus próprios projetos para minimizar quais contêineres têm acesso a quais partes.
Atualizei meus arquivos de exemplo abaixo com esta última revelação (obrigado @alkaline)
Esta parece ser a configuração mínima para docker 2.0 forward (porque as coisas ficaram muito mais fáceis no docker 2.0)
docker-compose.yml:
( ATUALIZADO o docker-compose.yml acima : Para sites que têm css, javascript, arquivos estáticos, etc, você precisará desses arquivos acessíveis ao contêiner nginx. Embora ainda tenha todo o código php acessível ao contêiner fpm. Novamente, porque meu código base é uma mistura confusa de css, js e php, este exemplo apenas anexa todo o código a ambos os contêineres)
Na mesma pasta:
site.conf:
No código da pasta:
./code/index.php:
e não se esqueça de atualizar seu arquivo hosts:
e execute seu docker-compose
e tente o URL do seu navegador favorito
fonte
Acho que também precisamos dar o volume ao container fpm, não é? Então =>
Se eu não fizer isso, encontro essa exceção ao disparar uma solicitação, pois o fpm não consegue encontrar o arquivo solicitado:
fonte
Nginx
ePHP-FPM
no GitHubPara qualquer outra pessoa recebendo
ao usar
index.php
enquantoindex.html
funciona perfeitamente e tendo incluídoindex.php
no índice no bloco de servidor de sua configuração de site emsites-enabled
Certifique-se de que o arquivo nginx.conf
/etc/nginx/nginx.conf
carregue realmente a configuração do seu site nohttp
bloco ...fonte