NGINX + PHP-FPM + MariaDB 설치
악마의 소리를 들었던 것일까? 예를 들면 이런 소리.. “어서와.. NGINX는 처음이지?” ㅎㅎ 얼마전에 PHP-FPM 적용하고 사이트마다 고유의 아이디로 운영하고자 방법을 찾다보니까 어렵지는 않은데 Apache와 PHP-FPM 연동이 tcp를 이용한 방식인데 socket을 이용한 방법으로 하면 깔끔한 것 같아 tcp를 이용할 때는 127.0.0.1:9000 이런 식으로 포트를 지정해주는데 사이트가 여러개면 포트를 달리해서 운영하면 되는데 그것보다는 socket을 이용하는 게 좋겠다는 생각이 들어 방법을 찾다보니 그냥 nginx를 사용하는 게 훨씬 편하겠다라는 생각이 들어서 어제 테스트 서버에 먼저 사고를 쳐보고 잘 되는 것을 확인하고 어제 밤에 실제 서버에 적요을 했다. 금방 적용한 것은 아니고 문제가 많이 발생했다. 오늘 오전까지 수정 작업을 했으니 말이다. ㅎ
그럼 이제부터 어제의 삽질을 정리해볼까 싶다. 새벽까지 작업을 하고 아침에도 일찍 일어난 편이라 머리가 조금 멍하지만.. 지금 정리해두지 않으면 나중에 기억하는 건 힘들 것 같아서 무리해서라도 정리를 하는 게 좋을 것 같다는 생각이 든다.
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/chicpro.dev.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
./mysql_install_db –user=mysql –basedir=/usr/local/mysql –datadir=/usr/local/mysql/data 이 부분이랑
cp -a mysql.server /etc/init.d/mysqld 이 부분이 안되는데요
.sh 파일을 붙여넣으면 되나요?
root 권한으로 실행하신 것이라면 안될 이유가 없을 겁니다.
그리고 오류 메세지등을 알려주시지 않으면 저로써도 원인을 알 수 없습니다.
[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
이런식으로 오류가 뜹니다
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.
이런 페이탈 에러가 나네요
다운로드 받으신 mariadb파일이 소스파일인지
컴파일된 바이너라 파일인지 확인해 보시기 바랍니다.
소스 파일을 다운로드 하셔서 설치하시려는 것 같은데요
소스 파일은 컴파일을 해야하므로 위의 내용대로는 설치가
되지 않습니다. 컴파일된 바이너리 파일을 받으셔서
다시 테스트해보셔야 할 것 같습니다.
진짜 정말 많은 도움이 되었습니다 ㅠㅠ 감사합니다!
새해복 많이받으세요!