NGINX

NGINX-PHP-MySQL 설치

CGI

CGI는 Common Gateway Interface의 약자로 웹서버와 외부 프로그램을 연결해주는 표준화된 프로토콜이다. 웹이 처음 등장했을 때는 HTML과 이미지를 전달해주는 웹서버 밖에 없었다. 하지만 웹에 대한 수요가 증가함에 따라서 정적인 HTML만을 가지고 정보를 제공하는 것에 한계가 생겼고, 이를 극복하기 위해서 등장한 기술이 CGI다. 웹서버로 요청이 들어왔을 때 그것이 웹서버가 처리 할 수 없는 정보일 때 그 정보를 처리 할 수 있는 외부 프로그램을 호출해서 외부 프로그램이 처리한 결과를 웹서버가 받아서 브라우저로 전송하는 것이다. 외부 프로그램은 C, C++, 펄, PHP, Python등 어떤 언어로든 작성될 수 있는데, 이것이 가능한 것은 웹서버와 외부 프로그램 사이에 통용되는 공통의 규칙이 정의되어 있기 때문이다. (위키피디아 참고)

CGI와 FastCGI가 무엇인지 이해하지 못해도 NGINX와 PHP를 연동하는 것에는 아무런 문제가 없다.

FastCGI

CGI 는 하나의 요청(Request)에 하나의 프로세스를 생성한다. 이것은 프로세스를 생성하고 삭제하는 과정에서 많은 부하가 발생한다. 당연히 느리다. 이를 개선하기 위해서 등장한 것이 FastCGI이다. FastCGI는 요청이 있을 때마다 프로세스가 만들어지는 것이 아니라 만들어진 프로세스가 계속해서 새로운 요청들을 처리한다. 덕분에 프로세스를 생성하고 제거하는데 들어가는 부하가 줄어든다. (위키피디아 참고)

PHP-FPM

PHP-FPM는 PHP FastCGI Process Manager의 약자로 PHP를 FastCGI 모드로 동작하도록 해준다. PHP5.4 RC부터는 PHP에 기본 내장 되었다. PHP-FPM을 사용하면 아래와 같은 이점이 생긴다. 

  • Adaptive process spawning 
  • Basic statistics (ala Apache's mod_status) 
  • Advanced process management with graceful stop/start
  • Ability to start workers with different uid/gid/chroot/environment and different php.ini (replaces safe_mode)
  • Stdout & stderr logging
  • Emergency restart in case of accidental opcode cache destruction
  • 업로드를 빠르게 처리해준다.
  • "slowlog"를 통해서 느리게 동작하는 부분을 추적할 수 있게 한다.
  • Enhancements to FastCGI, such as fastcgi_finish_request() - 요청을 일단 끝내고 후처리가 요구되는 작업을 백그라운드로 처리할 수 있도록 해준다. (예제)

PHP-FPM 설치 - Ubuntu

MySQL 설치

MySQL을 사용한다면 우선 MySQL을 설치한다. 

sudo apt-get install mysql-client mysql-server;

PHP-FPM 설치

이 과정에서 php도 설치된다. 

sudo apt-get install php5-fpm;

MySQL과 PHP-FPM의 연결

sudo apt-get install php5-mysql

NGINX 설정

Nginx의 설정 파일을 수정한다.

설정파일은 아래의 위치 중의 하나에 있다.

  • /etc/nginx/conf.d/default.conf
  • /etc/nginx/sites-available/default

다음은 필자의 설정파일이다.

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    root   /usr/share/nginx/html;
    location / {
        index  index.html index.htm index.php;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        fastcgi_pass   unix:/var/run/php5-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

위의 내용을 그대로 사용하면 PHP 보안 문제가 있다. 아래 링크를 따라가면 몇가지 보안 이슈를 해결 할 수 있는 정보가 있다. 참고하자. http://phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=77007&page=#c_77013

위의 설정 파일에서 주목해야 할 부분을 설명하겠다.

location ~ \.php$ {..}

location

location은 .php 확장자로 끝나는 요청을 처리하기 위한 부분이다.

fastcgi_param

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

fastcgi_param 은 FastCGI의 규칙에 따라서 에플리케이션(php-fpm)에게 전달할 데이터를 지정한다. SCRIPT_FILENAME은 CGI 의 규격 중 SCRIPT_NAME에 해당하는 값인데, 이 값으로 전달된 $document_root는 루트 디렉토리 즉 /usr/share/nginx/html 을 의미한다. $fastcgi_script_name은 파일의 이름을 의미한다. 이 두개의 값이 조합된 결과가 PHP-FPM으로 전달되는 것이다. PHP-FPM은 전달된 값에 해당되는 파일을 읽어서 실행하게 된다. 

fastcgi_pass

socket

fastcgi_pass는 php-fpm과 NGINX를 연결하기 위한 인터페이스를 지정하는 것이다. 이 값은 php-fpm의 listen 설정값과 일치해야 한다. 필자의 php-fpm 버전에서는 이 설정값을 /etc/php5/fpm/pool.d/www.conf에서 찾을 수 있었다. 위의 예제에서 지정된 unix:/var/run/php5-fpm.sock는 유닉스 소켓으로 NGINX와 PHP-FPM이 같은 (컴퓨터를 의미하는) 호스트에 설치된 경우 사용한다. 이것을 그림으로 나타내면 아래와 같다.

 

TCP Connection

만약 NGINX와 PHP-FPM이 서로 다른 머신에 설치되었다면 TCP Connection의 값을 지정해야 한다. 만약 PHP-FPM이 192.168.125.142에 설치되어 있다면  NGINX 측의 설정은 아래와 같아야 한다.

fastcgi_pass   192.168.125.142:9000;

이에 대응해서 PHP-FPM 측의 listen 값은 아래와 같아야 한다.

listen = 192.168.125.142:9000

이것을 그림으로 나타내면 아래와 같다.

 

 

Upstream Module

Upstream Module는 NGINX를 일종의 부하분배장치(Load Balancer)로 이용할 수 있게 해주는 NGINX의 모듈이다. 자세한 내용은 Upstream Module를 참고한다. Upstream Module 바로가기

Trouble Shooting

TCP Connection을 통해서 접속이 되지 않을 때 문제 해결 방법

증상 : File not found.라고 출력된다. 

원인 : NGINX가 fastCGI 인터페이스를 통해서 PHP-FPM이 실행할 파일을 지정할 때 사용하는 변수가 SCRIPT_FILENAME 인데 이 값이 잘못 전달되서 PHP-FPM이 실행 할 파일을 찾지 못하고 있다. 

원인 분석 : PHP-FPM이 설치된 머신에서 tcpdump로 9000 포트로 들어오는 패킷을 감청해서 CGI 환경변수가 잘 전달되고 있는지 확인한다. 

tcpdump port 9000 -A | strings
 
TCP Connection에서 주로 문제가 발생하는 지점은 SCRIPT_FILENAME 이기 때문에 이 값을 파악해보는 것이 중요하다. 아래와 같은 내용을 찾아보자. 
 

필자는 /usr/local/nginx/html에 test.php 파일을 위치시켰는데 NGINX는 /usr/share/nginx/html 에서 파일을 호출하고 있었다. 

문제해결 : php-fpm 쪽의 디렉토리를 변경한다. 

소켓 파일에 엑세스 할 수 있는 권한이 없다고 오류가 발생하는 경우

error.log에 아래와 같은 에러가 발생하는 경우는 소켓파일에 접근하는 nginx의 소유자 퍼미션이 맞지 않기 때문이다. 

2014/12/29 21:59:12 [crit] 8116#0: *1 connect() to unix:/var/run/php5-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.222.1, server: o2.org, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "o2.org"

이 문제에 대한 자세한 설명은 아래 링크를 참고하자. 

http://jesin.tk/fix-connect-to-php5-fpm-sock-failed-13-permission-denied-while-connecting-to-upstream-nginx-error/

댓글

댓글 본문
  1. 드림보이
    2021.09.12. 시작
  2. loopback
    최신 php 7.0 기준
    sudo apt install mysql-client mysql-server
    sudo apt install php7.0-fpm
    sudo apt install php7.0-mysql
  3. DEAN
    저는 AWS EC2 환경에서 nginx php-fpm 설치 및 연동해보는 과정에서,
    test.php 추가하고 브라우저로 url로 접속하면 보이지 않길래... 확인해보니,
    $ sudo vim /etc/nginx/nginx.conf 입력하여 설정파일 내용 수정할 때,
    fastcgi_pass 항목 관련 php-fpm.sock 파일의 디렉토리 경로값을 정확하게 입력해줘야 했습니다.
    저는 아래처럼 "fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;" 라고 수정한 후,
    php-fpm 서비스하고 nginx 서비스 재시작하니까
    브라우저에서 test.php의 내용을 보는 데에 성공했습니다.

    -----------------------------------------------------------------------------
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
    fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    }
    대화보기
    • lemon
      연동은 했는데 http 설정은 어떻게 하는지 궁금합니다.
    • smchae
      nginx를 사용하던 중 etc/nginx 아래에 'on'이라는 이름을 가진 파일을 발견하게되었는데 해당 파일은 nginx log를 기록하고 있었습니다. nginx.conf 에서 /var/log/nginx/ 으로 저장하라고 명시하였는데 'on' 파일은 어떤 파일인가요?
    • wppark
      항상 감사하게 읽고 있습니다! 해외 포털도 이렇게 정리가 잘되기 쉽지 않은데! 감사합니다!
    • kjone
      저도 별모모님처럼 연결이 되지 않는 것 같네요.. nginx가 최신 동향에 맞는 것 같아서 쓰고 싶은데
      잘 안되네요
    • 지나가다
      개념 잡기에 좋네 좋은글 감사
    • 별모모
      [ Nginx와 PHP가 연결되지 않는 것 같습니다. 2번 동영상에서 info.php하면 phpinfo가 나와야하는데 안 나옵니다. /var/log/nginx/error.log는 아래와 같습니다.

      2014/02/23 18:47:26 [crit] 5544#0: *14 connect() to unix:/var/run/php5-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: 172.30.1.2, server: localhost, request: "GET /info.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "172.30.1.4"

      TCP/IP 문제가 의심되어 nginx.conf(fastcgi_pass 127.0.0.1:7777;), /etc/php5/fpm/pool.d/www.conf(localhost 127.0.0.1:7777;) 로 변경하여도 마찬가지 입니다.

      [ phpinfo.php, 다운로드 ] Nginx를 컴파일하여 설치하는데 성공하고 예제처럼 phpinfo.php를 만들어 놓고, 주소창에 입력하면 무엇이 잘못되었는지 "다운로드"가 됩니다. 구글님도 stackoverflow 등에도 증상은 있지만 해결책을 찾지 못했습니다. 예전에, apache서버에서도 php소스파일이 다운로드 되어서 해결을 못했는데 Nginx-php_fpm에서도 그러네요.

      도움을 청합니다.

      (삽질 4일 후,)
      ==>[ 동영상 내용 수정 필요: PHP-fpm (2/3)] php-fpm을 설치해도, PHP는 설치되지 않는 것 같습니다. PHP5를 별도로 설치해야 합니다.

      phpinfo.php 가 왜 안 뜨는지 모르겠습니다. ㅠㅠ; (L)APM이 정말 편리했구나....
    • 술않먹는하마
      넘 도움이 많이대서 머라 말을 못하겟내요 ~

      저의 경우 bbb(비글본블랙 인베이드 리눅스오픈 하드웨어 라즈베리파이같은것)하나 질러서

      써버 하나 꾸미고 건물 모니터링 생활환경(온도 정보 수집/제어) 해보려구요

      한육계월 해야 대지 않을까햇는대 여기서 시간 많이 time++ 대서 감니다 (아니군 아꼇으니 time-- 조)

      감사합니다.
    • 감사합니다
      감사합니다.
    • 진짜궁금
      http://www.conf 서 listen = 값이랑 fastcgi_pass 값이 같으면 되는거죠?
      이상하게 127.0.0.1:9000 으로하면 죽어도 안되다가 /var/run/php5-fpm.sock 로 하니까 잘되네요.
      127.0.0.1:9000 은 다른설정이 필요한건가요?
    • php에서 처리 합니다.
      대화보기
      • 서경빈
        내용 너무너무 좋네요

        덕분에 아마존 EC2 에 무사히 nginx+php-fpm을 세팅했습니다.

        ㅎㅎ 근데 한가지 궁금한 사항이 있어서요(제가 php도 막 공부하기 시작한 초짜입니다.)

        제가 이해한대로라면 지금 현재 nginx세팅이 php파일은 fast-cgi을 통해서 처리를 하는 것이고

        그외 단순 html파일은 nginx가 처리를 하는 것으로 알고 있습니다.

        그렇다면 html 파일 내에서 php함수를 호출할 경우에 처리는 어디서 하게 되는것인지요?

        예를 들자면

        <HTML>
        <HEAD>
        <TITLE>HTML 안에 PHP</TITLE>
        </HEAD>
        <BODY>
        지금 시간은 <b> <? echo date("Y-m-d H:i:s") ?> </b> 입니다.
        </BODY>
        </HTML>

        이렇게 직접적으로 php문법이 들어가는 경우나

        <HTML>
        <HEAD>
        <TITLE>템플릿의 활용</TITLE>
        </HEAD>
        <BODY>
        <? include "TimeTemplate.php"; ?>
        </BODY>
        </HTML>

        이런식의 php을 템플화해서 호출하는 경우에는 어디서 처리가 되는것인지 매우 궁금합니다.
      • kore
        너무너무 잘 봤습니다. 감사합니다!
      • 살라리꽃
        nginx 설치 및 연동은 구현했는데,
        제로보드(XE)를 설치(연동)시키려면 어떻게 해야하나요...?
        도움 좀 부탁드리겠습니다.
        대화보기
        • 정원석
          nginx 설치로 이리저리 구글링 했었는데,
          한방에 깨달아버렸네요^^
          감사합니다~
        • egoing
          컴파일시 옵션을 주지 않으면 /usr/local/nginx/conf에 설정 파일이 생기는 것이 맞습니다 ^^
          2013년 5월 9일 목요일에 Disqus님이 작성:
          대화보기
          • dlengmlek
            설정파일 경로 때문에 헷갈렸는데 다른건 제가 동영상 한번더 보니까 해결 되네요 ^^ 좋습니다.~~~~~~~~~~~~~
          • Guest
            이고잉님 질문요
            "NGINX 설정
            Nginx의 설정 파일을 수정한다.
            설정파일은 아래의 위치 중의 하나에 있다.
            /etc/nginx/conf.d/default.conf
            /etc/nginx/sites-available/default"
            이부분이 두가지경우라는건 위에있는건 컴파일 했을때 경로이고
            밑에 있는건 패키지설치시 경로인거 같은데
            전 컴파일설치시 경로가 다르게 나옵니다.
            컴파일 동강봤을땐 제경로가 맞는거 같은데 ... 헷갈려서요userver@userver:/usr/local/nginx/conf$ ls -al
            합계 68
            drwxr-xr-x 2 root root 4096 5월 8 16:50 .
            drwxr-xr-x 11 root root 4096 5월 8 16:50 ..
            -rw-r--r-- 1 root root 1034 5월 8 16:50 fastcgi.conf
            -rw-r--r-- 1 root root 1034 5월 8 18:00 fastcgi.conf.default
            -rw-r--r-- 1 root root 964 5월 8 16:50 fastcgi_params
            -rw-r--r-- 1 root root 964 5월 8 18:00 fastcgi_params.default
            -rw-r--r-- 1 root root 2837 5월 8 18:00 koi-utf
            -rw-r--r-- 1 root root 2223 5월 8 18:00 koi-win
            -rw-r--r-- 1 root root 3463 5월 8 16:50 mime.types
            -rw-r--r-- 1 root root 3463 5월 8 18:00 mime.types.default
            -rw-r--r-- 1 root root 2685 5월 8 16:50 nginx.conf
            -rw-r--r-- 1 root root 2822 5월 8 23:12 nginx.conf.default
            -rw-r--r-- 1 root root 596 5월 8 16:50 scgi_params
            -rw-r--r-- 1 root root 596 5월 8 18:00 scgi_params.default
            -rw-r--r-- 1 root root 623 5월 8 16:50 uwsgi_params
            -rw-r--r-- 1 root root 623 5월 8 18:00 uwsgi_params.default
            -rw-r--r-- 1 root root 3610 5월 8 18:00 win-ut
            위에 경로가 /usr/local/nginx/conf/ 이렇게 되어집니다. 테스트서버로 사용할려고 노트북에 설치하고 이상해서 맥에서 가상으로 우분투설치후 업데이트만 하고 아무것도 설치 안하고 nginx 컴파일설치 했는데 또 같은 경로로 설정파일 존재합니다. 그리고 두군데다 보드설치할려면 403 퍼미션에러나고요. 퍼미션은 루트경로부터 777로 줬습니다. ㅜㅜ
            그리고 html/ info.php 파일이 없습니다. 가상우분투하고 테스트서버둘다요.ㅠㅠ
            우분투는 12.04 LTS 입니다.계속 막히네요. 전에 nginx 1.1.9 버전에서는 403에러 간단히 권한복구로 해결했는데 ... 왜이런걸까요?
          • ㅎㅎ
            네 상관없어요~
            대화보기
            • 궁금인
              unix:/var/run/php5-fpm.sock; 이 127.0.0.1:9000; 으로 되있는 사람은 그냥 두면되는거죠?
            • egoing
              php-fpm에는 nginx를 설치하지 않아도 됩니다.
              대화보기
              • 아트인
                동영상에 php는 5.4 버전인데 nginx 처럼 최신 버전 쉽게 설치하는 방법 알려주세요~!
              • 아트인
                php-fpm 머신에도 nginx를 설치해야 하나요?
                대화보기
                • 아트인
                  php-fpm(3/3) 동영상에서php-fpm 머신에 /usr/share/nginx/html 경로를 어떻게 설정하셨나요?
                • 아트인
                  apache 2.4.x mpm-event와 nginx에서 고민 중이였는데,이번 수업이 많은 도움이 될 것 같습니다.감사합니다 ^^
                  대화보기
                  • egoing
                    예 맞습니다 :)하지만 mysql-client는 설치하시는게 아무래도 편리하겠죠.
                    2013/4/26 Disqus <notifications@disqus.net></notifications@disqus.net>
                    대화보기
                    • 아트인
                      NginX, PHP, MySQL을 모두 분리할 때, 각 서버에
                      서버1: nginx 설치서버2: php5-fpm, php5-mysql 설치서버3: mysql-client mysql-server 설치
                      이 때, 서버2에 mysql 설치 하지 않아도 되겠죠?
                    • egoing
                      너무 좋은 정보입니다. 저도 몰랐던 것들입니다! 감사해요 :)
                      대화보기
                      • Darwin Park
                        html 파일 안에 PHP코드 실행하고 싶으신 분은 /etc/php5/fpm/pool.d/www.conf 파일 내에 security.limit_extensions 옵션 주석해제하셔야 됩니다~
                      • Darwin Park
                        기본으로 TCP소켓인분들은 그냥 /etc/php5/fpm/pool.d/www.conf 에서 경로 설정을 해주시면 해당 파일이 생성되고 유닉스 소켓을 이용할 수 있어요~
                      • Seongwoo Noh
                        잘 읽었습니다. ^^.
                      버전 관리
                      egoing@gmail.com
                      현재 버전
                      선택 버전
                      graphittie 자세히 보기