
Tento colocar em contêiner meu nginx em execução atualmente em meu servidor. Para isso criei o seguinte arquivo docker compose:
version: "3.8"
services:
nginx:
image: nginx:stable-alpine
container_name: nginx
restart: unless-stopped
group_add: ["33"]
volumes:
- "/etc/nginx-docker:/etc/nginx/conf.d:ro"
- "/run/php:/run/php"
- "/var/www:/var/www:ro"
ports:
- "8111:80"
- "8443:443"
Tudo funciona bem, mas o problema é que ainda tenho php-fpm rodando "nativamente" (não encaixado) em meu sistema host e quero usar seus soquetes para meu contêiner nginx (daí a linha volumes: - "/run/php:/run/php"
).
As permissões dos soquetes são srw-rw---- www-data:www-data
. Portanto, adicionei o usuário contêiner ao grupo 33 (que é www-data no meu sistema host -> group_add: ["33"]
). Quando eu verifico no contêiner os IDs do grupo, o ID 33
é realmente adicionado ao usuário conectado no momento:
/ # id -G
0 1 2 3 4 6 10 11 20 26 27 33
/ # id -u
0
/ # whoami
root
No entanto, quando ligo para um site desenvolvido com PHP, recebo a seguinte mensagem de erro nos logs do nginx:
2024/01/21 08:58:53 [crit] 21#21: *1 connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.192.68, server: _, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "op---s:8111"
Alguma dica ou solução que possa estar faltando para que funcione?
Responder1
Eu fiz algumas pesquisas :)
Se você entrar no contêiner que executa a imagem nginx, poderá ver que há alguns processos nginx em execução:
docker exec -it 43b5b971c433 /bin/sh
/ # ps -ef |grep nginx
1 root 0:00 nginx: master process nginx -g daemon off;
21 nginx 0:00 nginx: worker process
22 nginx 0:00 nginx: worker process
23 nginx 0:00 nginx: worker process
24 nginx 0:00 nginx: worker process
42 root 0:00 grep nginx
Alguns são executados como root
e outros como nginx
usuário.
Você adicionou o usuário root
ao www-data
grupo dentro do seu arquivo docker-compose, mas mesmo sem fazer isso, o usuário root deve ter todas as permissões necessárias para acessar o soquete php unix.
Você pode testar as permissões com o test
comando. Envie o código de saída para ver se o comando foi bem-sucedido ou não. Como você pode ver, o usuário root pode ler o arquivo socket, mas não executá-lo:
/run/php # whoami
root
/run/php # test -r php8.1-fpm.sock; echo $?
0
/run/php # test -x php8.1-fpm.sock; echo $?
1
Então o permission denied
erro provavelmente vem do nginx worker
processo executado como nginx
usuário.
Vamos primeiro verificar as permissões dos arquivos dentro do contêiner do docker ...
ls -al
fornece a seguinte saída:
srw-rw---- 1 xfs xfs 0 Jan 25 08:58 php8.1-fpm.sock
dizendo que o arquivo de soquete pertence ao "xfs". Uma rápida olhada no /etc/group
arquivo dentro do contêiner mostra que o ID do xfs
grupo é 33
igual ao ID na máquina host do grupo www-data
.
Dentro do contêiner, você pode adicionar o usuário nginx ao grupo xfs:
addgroup nginx xfs
O problema deve ser resolvido agora.
Não tenho certeza de como adicionar isso diretamente ao seu arquivo de composição (como você especifica qual usuário adicionar ao grupo?) - mas você pode fazer isso no seu Dockerfile se puder criar uma nova imagem.
Depois de reiniciar o contêiner, as permissões parecem persistir.
Responder2
Determine o usuário e o grupo que o PHP-FPM está executando no host. Geralmente você pode encontrar essas informações no arquivo de configuração do PHP-FPM (geralmente localizado em /etc/php/7.x/fpm/pool.d/www.conf)
Em seguida, atualize seu docker-compose e adicione isto
user: "your_php_user:your_php_group"
Responder3
Tudo funciona bem, mas o problema é que ainda tenho php-fpm rodando "nativamente" (não dockerizado) em meu sistema host e quero usar seus soquetes para meu contêiner nginx (daí a linha volumes: -
"/run/php:/run/php"
).
Isso não é possível ou sensato.
O Docker gera seu próprio namespace de rede, para que você obtenha sua própria pilha de firewall, pilha de IP e pilha de rede Unix.
Mesmo se você corrigir o problema de permissões, digamos, por exemplo, que você faça login no contêiner manualmente com docker exec
o chmod
arquivo de soquete 666 e, por uma questão de brevidade, vamos supor que não haja namespaces de usuário no caminho também.
O que você está pedindo para fazer é equivalente a:
- Executando uma
php-fpm
instânciasystem1
com um soquete Unix ativado/var/run/php-fpm.sock
- Exportando o
/var/run
caminho por NFS nosystem1
. - Montagem
system1:/var/run
emsystem2
. Um sistema completamente separado. - Tentando
connect()
ligar o soquete Unixsystem2
e esperandosystem1
responder comphp-fpm
.
A maneira como você realmente deveria fazer isso (deveria realmentequererpara fazer isso, que é um assunto separado) é escutar a php-fpm
instância usando IP - vinculando-a, host_system:12345
por exemplo. Em seguida, use nginx
in container
para conectar-se a host_system:12345
.
Isso tudo está errado. Não me escute. Se você criar um soquete unix bem nomeado, exposto em qualquer um dos namespaces e o caminho for compartilhado entre os dois namespaces, conectando-se a esse soquete unix, conecte-se ao outro namespace!
https://lore.kernel.org/all/[e-mail protegido]/T/
Este patch aborda especificamente isso. Claramente, quando testei, isso foi há muito tempo! :)
A única vez que isso não parece ser o caso é no caso de criação anônima de soquete Unix, no entanto, esse é um recurso bastante específico do Linux e pouco usado em soquetes Unix.