Docker Compose 및 PHP 권한 문제 해결

8771 단어 dockerphp
지난 1년 동안 저는 기본적인 Docker Compose setup for Laravel을 유지하고 교체해 왔습니다.이것은 현지의 발전에 있어서 이미 충분하다. 이것이 바로 내가 처음에 원했던 것이다.그러나 내가 그것을 발표한 이래로 많은 사람들이 나에게 권한 문제에 대한 우려와 GitHub 문제를 보냈다.
환매 협의의 생명 주기 동안 나는 여러 가지 다른 복구 방법을 시도했지만, 최근에야 비로소 믿을 만한 해결 방안을 찾았다. 이것은 현지와 생산에서 각종 흔한 플랫폼과 운영체제와 협조하여 사용할 수 있을 것 같다.
그래서 우리는 그것을 깊이 이해하자!

문제.


해결 방안을 토론하기 전에, 나는 이 문제들과 그것들의 근본 원인을 간략하게 개술할 것이다.만약 당신이 직접 복구 프로그램에 들어가고 싶다면, 이것을 건너뛸 수 있습니다!
그래, 우리 계속하자.
먼저 Docker Compose 파일을 함께 놓고 올바른 디렉터리에 Laravel 프로그램을 설정합니다.docker-compose up -d을 사용하여 용기 네트워크를 시작하면 터미널의 모든 내용이 정상적으로 되돌아오고 구축 과정에서 오류 팝업을 보지 못했습니다.
그러나 내 브라우저를 열고 웹 사이트를 방문하면 다음과 같은 결과가 발생합니다.

Docker 컨테이너를 통해 브라우저에서 artisan 또는 composer 명령을 사용하려고 시도할 때, 나도 비슷한 오류가 발생할 수 있습니다.더 실망스러운 것은 직접 이미지나 컴파일된 자산에 접근하면 잘 되돌아온다는 것이다.
이러한 상황이 발생한 이유는 PHP 컨테이너가 내 Laravel 응용 프로그램 파일이 있는 파일 시스템에 쓸 수 있는 권한이 없기 때문입니다.그런데 왜?Docker 컨테이너가 폐쇄적이고 고립된 시스템이라는 점을 감안하면 무의미할 것이다.
이것은 사실의 절반이다. 가장 큰 차이점은 내가 어떻게 응용 프로그램 데이터를 용기에 도입했는가에 있다.
Docker에서는 컨테이너에 데이터를 가져오는 두 가지 주요 방법이 있습니다.
첫 번째 방법은 DockerFile에서 추가/복사 명령을 사용하는 것입니다.파일이나 폴더의 내용을 가져와 용기에 지정한 디렉터리로 복사합니다.프로그램의 원본 파일을 나누어 주지 않아도 되고 Docker 이미지에 포함되어 있기 때문에 이식성이 가장 큰 장점입니다.그러나 프로그램의 파일에 대한 변경 사항은 로컬 컴퓨터에서 쉽게 접근할 수 없습니다.
두 번째는 볼륨을 사용하는 것입니다.볼륨은 호스트의 로컬 파일 또는 폴더와 컨테이너 내 파일 또는 폴더 간의 기호 링크로 사용됩니다.이 방법의 가장 큰 장점은 이 파일들에 대한 어떠한 변경도 볼륨의 양측에 반영된다는 것이다.이것은 원본 코드가 빠르게 변화하는 개발 환경에 있어서 매우 좋은 것이다.
나는 문장 맨 위에 있는 링크의 설정에 두 번째 방법을 사용했다.Docker Compose 및 mounted Volume은 응용 프로그램이 브라우저에 표시되도록 내 사이트의 데이터와 파일을 컨테이너에 넣습니다.이렇게 하면, 나는 응용 프로그램을 개발하여 로컬에서 이 파일들을 브라우저에 즉시 반영하도록 변경할 수 있다.
하지만 함정이 하나 있다.
볼륨이 컨테이너에 불러올 때마다 호스트 시스템의 파일과 디렉터리 소유권도 컨테이너에 전달됩니다.
왜 이게 문제야?로컬 컴퓨터에서 Docker 실례를 실행하고 있고, 프로그램 파일은andrew, ID 502라는 사용자가 소유하고 있다고 가정하십시오.PHP 컨테이너는 Www 데이터라는 사용자에서 php을 실행하고 있으며, 이 사용자의 ID는 1001입니다.응용 프로그램 디렉토리의 파일(예: 쓰기 캐시 또는 이미지 저장)을 수정하려고 하면 두 소유권의 차이로 인해 사용 권한이 충돌하고 처리 오류가 발생합니다.
해결 방법은 매우 간단한 것 같다.단지 ssh를 용기에 넣고 정확한 권한을 사용하여 응용 프로그램 파일에chmod를 진행합니다!
하지만 이것은 영구적인 것이 아니다.용기를 뜯어 돌리면 권한이 초기화되어 다시 실행해야 합니다.
좋습니다. 컨테이너를 구축할 때마다 이 동작을 수행할 수 있도록 Dockerfile에 명령을 추가합니다.
불행히도 이것도 통하지 않는다.이러한 볼륨은 컨테이너 구축 프로세스가 실행된 후 로드되므로 Docker 파일에 어떤 명령이 있더라도 Docker Compose에서 로드된 파일에는 영향을 주지 않습니다.
나는 신뢰할 수 있고 자주적이며 가장 중요한 것은 복제 가능한 복구 프로그램이 필요하다.

복구


만약 내가 용기에 추가된 파일에 직접적인 영향을 주지 못한다면, 내가 할 수 있는 가장 좋은 일은 용기에 사용된 권한을 복제하는 것이다.
PHP 컨테이너의 경우 php-fpm-alpine 이미지를 기반으로 하는 사용자 정의 Dockerfile을 사용하여 구성합니다.그곳에서, 나는 laravel이라는 그룹을 만들었는데, 그 그룹 id는 로컬 기기에서 나의 응용 프로그램 파일을 가지고 있는 그룹과 같다.그게 중요해.나도 사용자에게 똑같은 일을 해서 laravel이라는 사용자를 만들었다.
이러한 명령은 다음과 같습니다.
RUN addgroup -g ${GID} --system laravel
RUN adduser -G laravel --system -D -s /bin/sh -u ${UID} laravel
Alpine Linux를 실행하기 때문에 Ubuntu와는 조금 다릅니다.그러나 각 명령에 대한 간략한 기능은 다음과 같습니다.

  • ddgroup 실행
  • -g에서 그룹 ID를 전송했습니다. 새 그룹
  • 에 추가하고 싶습니다.
  • ${GID} Docker Compose를 통해 전달되는 그룹 ID의 환경 변수
  • --system 전체 시스템 그룹
  • laravel 우리가 만들고 있는 그룹의 이름

  • adduser 실행
  • -G 이 사용자를 할당할 그룹의 이름입니다. 예를 들어, 이것은 우리가 새로 만든 그룹
  • 입니다.
  • --system은 전체 시스템 사용자
  • -D 이 사용자에 대한 암호를 생성하지 않음
  • -s /bin/sh Alpine Linux 셸
  • -u ${UID}은 이 새 사용자에게 추가하고자 하는 사용자 ID를 그룹 ID와 같이 환경 변수
  • 을 통해 전송합니다.
  • laravel 생성 중인 사용자의 이름
  • 그래서 저는 laravel이라는 그룹과 사용자를 만들었습니다. 그들은 모두 특정한 ID를 가지고 있기 때문에 저는 그들을 연결했습니다.그러나 기본적으로 www-data을 사용하기 때문에 용기에서 실제 PHP를 실행하는 사용자를 수정해야 합니다.수정된 php를 복사할 수 있습니다.ini 파일이지만 몇 글자만 변경되었기 때문에 같은 Dockerfile에서 몇 개의 명령을 사용하기로 결정했습니다.
    RUN sed -i "s/user = www-data/user = laravel/g" /usr/local/etc/php-fpm.d/www.conf
    RUN sed -i "s/group = www-data/group = laravel/g" /usr/local/etc/php-fpm.d/www.conf
    
    이것은 단지 sed를 사용하여 두 줄 코드를 교체할 뿐입니다. 이 두 줄 코드는 사용자와 그룹 PHP 실행을 우리가 방금 만든 사용자와 그룹 laravel로 정의합니다.우리가 필요로 하는 ID는 프로그램 파일 소유자의 ID이기 때문에, 나는 반드시 그것을 찾아야 한다.
    내 터미널에서 나는 이 두 파일을 얻기 위해 id -uid -g을 실행할 수 있다. 현재 로그인한 사용자가 내가 개발하고 있는 Laravel 응용 프로그램 파일의 소유자라고 가정하자.

    네, 501과 20입니다.
    PHP Dockerfile로 돌아가려면 이미지를 구성할 때 두 ID를 사용할 환경 변수를 만들어야 합니다.맨 위에 다음과 같은 내용이 추가되었습니다.
    ENV UID=501
    ENV GID=20
    
    하지만 잠깐만, 나는 정말 이 값들을 억지로 인코딩하고 싶지 않아.특히 이 초보자 패키지를 공개적으로 구매하고 있기 때문에 어떤 팀과 사용자 ID가 필요할지 모르겠습니다!
    우리는 파라미터를 사용하여 이 문제를 해결하고, 그것들을 docker compose에 전달할 수 있다.yml 파일.그래서 저는 상술한 방법을 사용하지 않고 다음과 같은 방법을 사용했습니다.
    ARG UID
    ARG GID
    
    ENV UID=${UID}
    ENV GID=${GID}
    
    이것은 보기에는 이상하고 중복될 수도 있지만, 우리는 Docker Compose를 통해 Docker File을 구축하여 매개 변수라는 것을 사용할 수 있다.이러한 파일은 다음과 같이 docker-compose.yml 파일에 차례로 사용됩니다.
    php:
        build:
          context: .
          dockerfile: php.dockerfile
          args:
            - UID=${UID:-1000}
            - GID=${GID:-1000}
    
    마찬가지로 더 많은 중복이 있지만 결국은 다음과 같다. 파라미터 UID와 GID는 모두 터미널에서 추출한 환경 변수를 사용한다.UID 또는 GID를 찾을 수 없는 경우 각 UID 또는 GID의 값은 기본값인 :- 구분자로 설정됩니다.
    그래, 그럼 이 두 가지는 어떻게 결합되었을까?
    터미널에서 우리는 먼저 echo $UIDecho $GID을 실행함으로써 이러한 환경 변수가 존재하는지 확인해야 한다.만약 네가 둘 다 가치가 있는 것을 본다면, 그것은 매우 좋다.없는 경우 다음 명령을 실행하여 내보내야 합니다.
    export UID=$(id -u) && export GID=$(id -g)
    
    그리고 당신이 해야 할 일은 평소와 같이 당신의 용기를 만들고 운송하는 것입니다!
    docker-compose up -d --build
    
    PHP 용기가 구축됩니다. 이 기간 동안 사용자 ID와 그룹 ID로 laravel 그룹과 사용자를 만듭니다. 그리고 php 프로세스는 새로운 laravel 사용자를 사용하여 실행됩니다. 이것은 프로그램 파일 시스템에 대한 쓰기 권한을 부여해야 합니다. 권한의 정의가 사용자 속성과 일치하기 때문입니다.

    마무리


    Docker와 PHP의 권한은 상당히 복잡한 문제입니다.이 컴퓨터의 운영체제와 Docker 소프트웨어 사이에 가상화 층이 존재하기 때문에 MacOS는 이 영향을 받지 않는 것 같아서 이 점은 도움이 되지 않는다.WSL-2가 있는 것과 WSL-2가 없는 Windows와 Ubuntu 사이에도 문제가 있다.
    나는 이미 모든 주요 운영체제와 플랫폼에서 상술한 내용을 테스트했는데 현지 개발과 생산 환경을 포함하여 아직 어떠한 권한 문제도 발생하지 않았다.또한 이러한 변경 사항을 GitHub repo에 발표한 후 문제 부분은 조용해졌다.
    그러나 주의해야 할 것은 생산 환경이나 로컬 환경을 루트/루트 사용자로 사용하면 위의 절차에 문제가 발생할 수 있다는 것이다.우선, 모든 생산 시스템에서 비 루트 sudo 사용자를 사용하는 것을 권장하지만, 이 경로를 계속 사용하기로 결정하면, 제가 최초로 링크한 GitHub의 README에 단독 부분을 만들었습니다. 이 부분은 모든 문제를 해결하는 데 도움을 줄 수 있을 것입니다.
    만약에 본고의 어떤 내용에 대해 궁금한 점이 있거나 Docker와 Laravel과 PHP를 어떻게 결합해서 사용하는지에 대해 궁금한 점이 있으면 언제든지 연락 주세요!

    좋은 웹페이지 즐겨찾기