
현재 내 서버에서 실행 중인 nginx를 컨테이너화하려고 합니다. 이를 위해 다음 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"
모든 것이 잘 작동하지만 문제는 호스트 시스템에서 여전히 php-fpm이 "기본적으로"(도커화되지 않음) 실행되고 있고 해당 소켓을 nginx 컨테이너에 사용하고 싶다는 것입니다(따라서 라인 volumes: - "/run/php:/run/php"
).
소켓의 권한은 입니다 srw-rw---- www-data:www-data
. 따라서 컨테이너 사용자를 그룹 33(내 호스트 시스템의 www-data -> group_add: ["33"]
)에 추가했습니다. 컨테이너에서 그룹 ID를 체크인하면 해당 ID가 33
실제로 현재 로그인된 사용자에게 추가됩니다.
/ # id -G
0 1 2 3 4 6 10 11 20 26 27 33
/ # id -u
0
/ # whoami
root
그럼에도 불구하고 PHP로 구동되는 웹사이트를 호출하면 다음과 같은 오류 메시지가 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"
작동시키기 위해 누락될 수 있는 힌트나 해결책이 있습니까?
답변1
좀 파헤쳐 봤습니다 :)
nginx 이미지를 실행하는 컨테이너에 들어가면 두 개의 nginx 프로세스가 실행되고 있는 것을 볼 수 있습니다.
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
일부는 으로 실행되고 root
일부는 사용자로 실행됩니다 nginx
.
root
docker-compose 파일 내의 그룹 에 사용자를 추가했지만 www-data
그렇게 하지 않더라도 루트 사용자는 php unix 소켓에 액세스하는 데 필요한 모든 권한을 가져야 합니다.
명령 을 사용하여 권한을 테스트할 수 있습니다 test
. 명령이 성공했는지 여부를 확인하려면 종료 코드를 출력하십시오. 보시다시피 루트 사용자는 소켓 파일을 읽을 수 있지만 실행할 수는 없습니다.
/run/php # whoami
root
/run/php # test -r php8.1-fpm.sock; echo $?
0
/run/php # test -x php8.1-fpm.sock; echo $?
1
따라서 permission denied
오류는 프로세스에서 발생했을 수 nginx worker
있으며 사용자로 실행됩니다 nginx
.
먼저 도커 컨테이너 내부의 파일에 대한 권한을 확인해 보겠습니다.
ls -al
다음과 같은 출력을 제공합니다.
srw-rw---- 1 xfs xfs 0 Jan 25 08:58 php8.1-fpm.sock
소켓 파일은 "xfs"가 소유하고 있다고 말합니다. /etc/group
컨테이너 내부의 파일을 잠깐 살펴보면 xfs
그룹 의 ID가 표시됩니다 33
. 이는 그룹의 호스트 시스템에 있는 ID와 동일합니다 www-data
.
컨테이너 내에서 nginx 사용자를 xfs 그룹에 추가할 수 있습니다.
addgroup nginx xfs
이제 문제가 해결되어야 합니다.
이것을 작성 파일에 직접 추가하는 방법을 잘 모르겠습니다(그룹에 추가할 사용자를 어떻게 지정합니까?). 하지만 새 이미지를 만들 수 있다면 Dockerfile에서 이를 수행할 수 있습니다.
하지만 컨테이너를 다시 시작한 후에도 권한이 유지되는 것 같습니다.
답변2
호스트에서 PHP-FPM이 실행 중인 사용자 및 그룹을 확인합니다. 일반적으로 이 정보는 PHP-FPM 구성 파일(일반적으로 /etc/php/7.x/fpm/pool.d/www.conf에 있음)에서 찾을 수 있습니다.
그런 다음 docker-compose를 업데이트하고 이것을 추가하십시오.
user: "your_php_user:your_php_group"
답변3
모든 것이 잘 작동하지만 문제는 호스트 시스템에서 php-fpm이 여전히 "기본적으로"(도커화되지 않음) 실행되고 있고 해당 소켓을 nginx 컨테이너에 사용하고 싶다는 것입니다(따라서 라인 볼륨: -
"/run/php:/run/php"
).
이는 불가능하거나 합리적이지 않습니다.
Docker는 자체 네트워크 네임스페이스를 생성하므로 자체 방화벽 스택, IP 스택 및 Unix 네트워크 스택을 갖게 됩니다.
docker exec
권한 문제를 해결하더라도 예를 들어 소켓 파일 666을 사용 하여 컨테이너에 수동으로 로그인한다고 가정 chmod
하고 간결성을 위해 사용자 네임스페이스도 없다고 가정하겠습니다.
귀하가 요청하는 작업은 다음과 같습니다.
- Unix 소켓을 사용하여
php-fpm
인스턴스 실행system1
/var/run/php-fpm.sock
/var/run
에서 NFS를 통해 경로를 내보내는 중 입니다system1
.system1:/var/run
에 장착 중 입니다system2
. 완전히 분리된 시스템입니다.connect()
Unix 소켓 소켓을 켜 려고 시도system2
하고 .system1
php-fpm
실제로 이 작업을 수행해야 하는 방식(실제로 수행해야 함)원하다이를 수행하는 것은 별도의 문제입니다.) IP를 사용하여 인스턴스를 수신하는 것입니다 . 예를 들어 php-fpm
이를 바인딩합니다 . 그런 다음 in을 host_system:12345
사용하여 에 연결합니다 .nginx
container
host_system:12345
이것은 모두 잘못된 것입니다. 내 말을 듣지 마세요. 이름이 잘 지정된 Unix 소켓을 만들고 두 네임스페이스 중 하나에 노출되고 경로가 두 네임스페이스 간에 공유되는 경우 해당 Unix 소켓에 연결하면 다른 네임스페이스에 연결됩니다!
https://lore.kernel.org/all/[이메일 보호됨]/티/
이번 패치에서는 이 문제를 구체적으로 해결합니다. 내가 테스트했을 때 이것은 분명히 오래 전의 일이었습니다! :)
이것이 사실이 아닌 것으로 보이는 유일한 경우는 익명 Unix 소켓 생성 사례이지만 그 중 하나는 Linux에만 해당되며 Unix 소켓의 기능은 자주 사용되지 않습니다.