NGINX + PHP-FPM + MariaDB 설치

악마의 소리를 들었던 것일까? 예를 들면 이런 소리.. “어서와.. NGINX는 처음이지?” ㅎㅎ 얼마전에 PHP-FPM 적용하고 사이트마다 고유의 아이디로 운영하고자 방법을 찾다보니까 어렵지는 않은데 Apache와 PHP-FPM 연동이 tcp를 이용한 방식인데 socket을 이용한 방법으로 하면 깔끔한 것 같아 tcp를 이용할 때는 127.0.0.1:9000 이런 식으로 포트를 지정해주는데 사이트가 여러개면 포트를 달리해서 운영하면 되는데 그것보다는 socket을 이용하는 게 좋겠다는 생각이 들어 방법을 찾다보니 그냥 nginx를 사용하는 게 훨씬 편하겠다라는 생각이 들어서 어제 테스트 서버에 먼저 사고를 쳐보고 잘 되는 것을 확인하고 어제 밤에 실제 서버에 적요을 했다. 금방 적용한 것은 아니고 문제가 많이 발생했다. 오늘 오전까지 수정 작업을 했으니 말이다. ㅎ

NPM-version

그럼 이제부터 어제의 삽질을 정리해볼까 싶다. 새벽까지 작업을 하고 아침에도 일찍 일어난 편이라 머리가 조금 멍하지만.. 지금 정리해두지 않으면 나중에 기억하는 건 힘들 것 같아서 무리해서라도 정리를 하는 게 좋을 것 같다는 생각이 든다.

 

0. 프로그램다운로드
https://downloads.mariadb.org/
http://php.net/downloads.php
http://nginx.org/en/download.html

1. MariaDB 5.5.32 설치

# useradd -Ms /bin/false mysql
# tar xvfz mariadb-5.5.32-linux-x86_64.tar.gz
# mv mariadb-5.5.32-linux-x86_64/ /usr/local/mysql
# cd /usr/local/mysql/scripts/
# ./mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
# cd ../support-files
# cp -a mysql.server /etc/init.d/mysqld
# chkconfig --add mysqld
# cp -a my-huge.cnf /etc/my.cnf
# service mysqld start
# /usr/local/mysql/bin/mysqladmin -u root -p password '1234'

MariaDB는 소프를 이용해 컴파일 설치를 하지 않고 컴파일된 바이너리 파일을 이용했다. 꼭 컴파일을 해서 사용하는 건 아니기도 하고 컴파일 하는 시간도 만만치 않기 때문이다. 이건 핑계이고 그냥 귀찮아서 바이너리 파일을 사용하는 것 같다.

2. PHP 5.5.2 FPM 설치

# tar xvfz php-5.5.2.tar.gz
# cd php-5.5.2
# ./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc \
--with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config \
--with-gd --with-curl --with-jpeg-dir=/usr --with-freetype-dir=/usr \
--with-png-dir=/usr --with-xpm-dir=/usr --with-zlib --with-zlib-dir=/usr \
--with-gdbm --with-gettext --with-iconv --with-openssl --enable-gd-native-ttf \
--enable-exif --enable-sockets --enable-soap --enable-mbstring=all --enable-bcmath \
--with-libxml-dir=/usr/lib --enable-ftp --with-mcrypt --enable-opcache --enable-fpm \
--enable-zip
# gmake -j4
# gmake install
# cp -a php.ini-production /usr/local/php/etc/php.ini
# cd sapi/fpm
# cp -a init.d.php-fpm /etc/init.d/php-fpm
# cp -a php-fpm.conf /usr/local/php/etc/php-fpm.conf
# chmod 755 /etc/init.d/php-fpm
# chkconfig --add php-fpm
# cd /usr/local/php/etc
# vi php-fpm.conf
# mkdir fpm.d
# cd fpm.d
# vi php-fpm.ncube.net.conf

php-fpm.conf 에서 사이트별 php-fpm 설정 파일을 저장하기 위해 아래 라인의 주석(;)을 제거한다.

include=etc/fpm.d/*.conf

그런 다음 fpm.d 라는 디렉토리르 생성하고 그 안에 사이트의 php-fpm 설정 파일을 생성한다. php-fpm.ncube.net.conf 라는 파일을  생성하고 아래 내용으로 설정했다.

[ncube]
user = ncube
group = ncube
listen = /var/run/php-fpm.ncube.net.sock
;listen.owner = ncube
;listen.group = ncube
;listen.mode = 0666
;listen.allowed_clients = 127.0.0.1
;process.priority = -19
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
;pm.process_idle_timeout = 10s;
;pm.max_requests = 500
;request_terminate_timeout = 0
;rlimit_files = 1024
;rlimit_core = 0
;security.limit_extensions = .php .php3 .php4 .php5

제일 첫 줄의 [ncube] 부분이 php-fpm pool 이름으로 사용되는 것이다. 그리고 더 자세한 설정항목은 php-fpm.conf 파일을 살펴보면 된다. php-fpm.conf 파일에 보면 www pool 설정이 있는데 이 부분은 사용하지 않을 것이기 때문에 모두 주석처리했다. 아래 명령어로 php-fpm 데몬을 실행한다. 위 설정에서 user = ncube group = ncube 부분이 php-fpm 데몬이 실행되는 user와 group 아이디이다. 이렇게 설정하면 흔히 웹사이트에서 파일 등의 업로드를 위해 디렉토리 퍼미션을 707 등으로 설정해야 하는데 계정 소유주의 아이디로 php-fpm 데몬이 실행되기 때문에 퍼미션을 따로 설정하지 않아도 된다. 그래서 보안에서 이점이 있다.

# service php-fpm start

실행 옵션은 start reload stop 등을 사용할 있다.

3. NGINX 1.4.2 설치

# tar xvfz nginx-1.4.2.tar.gz
# ./configure --prefix=/usr/local/nginx --user=daemon --group=daemon \
--with-http_ssl_module --with-http_gzip_static_module \
--without-mail_pop3_module --without-mail_imap_module \
--without-mail_smtp_module
# gmake
# gmake install
# cd /usr/local/nginx/conf
# mkdir vhosts
# vi nginx.conf

nginx configure 옵션은 더 자세히 알아보지 않아서 위의 옵션만을 사용했다. 추후에 옵션에 대해서는 알아봐야 할 것 같다. nginx.conf 파일에 사이트별 가상 호스트 설정파일 로드를 위해 vhosts 라는 디레토리를 생성했다. 아래 내용을 nginx.conf 파일의 http { } 블록 안에 추가해준다.

    # VirtualHost Configuration
    include /usr/local/nginx/conf/vhosts/*.conf;

사이트별 가상호스트 설정은 아래 내용을 참고하면 된다.

    server {
        listen       80;
        server_name  ncube.net www.ncube.net;

        #charset koi8-r;

        #access_log  logs/ncube.net.access.log  main;

        location / {
            root   /home/ncube/www;
            index  index.html index.php;
            try_files $uri $uri/ /index.php?$args;
        }

        #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   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$ {
            root           /home/ncube/www;
            fastcgi_pass   unix:/var/run/php-fpm.ncube.net.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;
        }

        # Add expire header for browser caching
        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            root           /home/ncube/www;
            expires        1y;
            log_not_found  off;
        }
    }

php-fpm과 연동을 socket 으로 처리하기 위해 fastcgi_pass   unix:/var/run/php-fpm.ncube.net.sock; 라고 설정했다. 그리고 fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name; 부분에서 $document_root 라고 변경하지 않아 nginx를 실행했을 때 File not Found. 화면만 나와서 엄청 당황했다. php 파일에서만 문제가 발생했는데 이걸 보지 못하고 넘어가서 1시간 가까이 검색 등의 무한 삽질을 했다. $document_root 대신 직접 절대 경로를 지정해줘도 된다. 위 설정의 마지막 부분에 추가되어있는 부분은 이미지 파일의 브라우저 캐싱을 위한 것이다.

        # Add expire header for browser caching
        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            root           /home/ncube/www;
            expires        1y;
            log_not_found  off;
        }

위 설정에서 root 를 설정하는 부분을 빼먹었더니 이미지 등이 표시되지 않는 문제가 생겨서 검색으로 root 설정 부분을 추가했더니 문제가 해결됐다. 그리고 위 설정 내용 중 try_files $uri $uri/ /index.php?$args; 부분이 있는데 이것은 WordPress에서 Permalinks 설정을 사용하기 위해 추가한 것이다. 추가로 압축 설정을 추가해주면 트래픽과 접속속도에 이점이 있다. 아래 설정을 nginx.conf 파일의 http { } 블록안에 추가해주면 된다.

    gzip  on;
    gzip_http_version 1.1;
    gzip_vary on;
    gzip_comp_level 6;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js;
    gzip_buffers 16 8k;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";

nginx는 init.d 설정 파일을 따로 제공해주지 않는다. 아래의 내용으로 파일을 생성해 준다.

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemin
#
# chkconfig:   - 85 15
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /usr/local/nginx/conf/nginx.conf
# pidfile:     /var/run/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"

lockfile=/var/lock/subsys/nginx

start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest || return $?
    stop
    start
}

reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}

force_reload() {
    restart
}

configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac
# vi /etc/init.d/nginx
# chmod 755 /etc/init.d/nginx
# chkconfig --add nginx

이렇게 nginx 관리용 스크립트를 사용하면 아래와 같이 nginx를 시작할 수 있다.

# service nginx start

start restart stop 등의 옵션을 사용할 수 있다. 이것으로 NGINX + PHP-FPM + MariaDB 연동 설치를 마쳤다. 설정을 마무리 하고 구글 페이지스피트를 이용해 측정했을 때 90점이라는 점수가 나왔다. Apache를 사용했을 때는 86점이었는데.. nginx를 사용하고 4포인트 올랐다. 좀 더 튜닝을 해보면 좀 더 나은 점수가 나오지 않을까 싶은 생각이 들지만 지금 당장은 좀 무리가 아닐까 싶다. 차차 공부해가면서 좀 더 튜닝을 해봐야겠다.

참고글
http://www.lowendguide.com/3/webservers/wordpress-permalinks-with-nginx/
http://blog.beany.co.kr/archives/2516
http://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and-optimizing-tips-and-tricks/
http://blog.beany.co.kr/archives/2422

편리

PHP와 MariaDB, jQuery 등을 사용해 게시판, 쇼핑몰 솔루션을 개발합니다. 그누보드5와 영카트5 개발에 참여 했습니다. Linux와 Nginx는 물론 WordPress, Git 등에도 관심이 많습니다. 자전거 타기 및 사진 촬영을 취미로 하고 있습니다.

카카오톡 플러스친구 채팅 : NCUBE.NET

7 thoughts to “NGINX + PHP-FPM + MariaDB 설치”

  1. ./mysql_install_db –user=mysql –basedir=/usr/local/mysql –datadir=/usr/local/mysql/data 이 부분이랑
    cp -a mysql.server /etc/init.d/mysqld 이 부분이 안되는데요

    .sh 파일을 붙여넣으면 되나요?

    1. root 권한으로 실행하신 것이라면 안될 이유가 없을 겁니다.
      그리고 오류 메세지등을 알려주시지 않으면 저로써도 원인을 알 수 없습니다.

      1. [root@Monster scripts]# ./mysql_install_db –user=mysql –basedir=/usr/local/mysql –datadir=/usr/local/mysql/data
        -bash: ./mysql_install_db: No such file or directory

        이런식으로 오류가 뜹니다

        1. sh ./mysql_install_db.sh –user=mysql –basedir=/usr/local/mysql –datadir=/usr/local/mysql/data

          이런식으로 해보니

          FATAL ERROR: Could not find my_print_defaults

          The following directories were searched:

          /usr/local/mysql/bin
          /usr/local/mysql/extra

          If you compiled from source, you need to run ‘make install’ to
          copy the software into the correct location ready for operation.

          If you are using a binary release, you must either be at the top
          level of the extracted archive, or pass the –basedir option
          pointing to that location.

          The latest information about mysql_install_db is available at
          http://kb.askmonty.org/v/installing-system-tables-mysql_install_db.

          이런 페이탈 에러가 나네요

        2. 다운로드 받으신 mariadb파일이 소스파일인지
          컴파일된 바이너라 파일인지 확인해 보시기 바랍니다.
          소스 파일을 다운로드 하셔서 설치하시려는 것 같은데요
          소스 파일은 컴파일을 해야하므로 위의 내용대로는 설치가
          되지 않습니다. 컴파일된 바이너리 파일을 받으셔서
          다시 테스트해보셔야 할 것 같습니다.

  2. 진짜 정말 많은 도움이 되었습니다 ㅠㅠ 감사합니다!
    새해복 많이받으세요!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.