Fedora 33 - APM(Apache PHP Mysql) 설치 및 연동

Last Updated on 1월 10, 2021 by 태랑(정현호)



APM은 Apache + PHP + Mysql 의 약자



웹 서버를 구축하고 PHP 로 작성된 웹 어플리케이션을 구동하기 위해 이전부터 많이 사용해온 스택 입니다.

PHP 를 구동 하기 위한 서버 스택의 구성은 여러가지 방식으로 할 수 있습니다.
Apache + PHP(mod_php) + Mysql 나 MariaDB
Apache + PHP-FPM + Mysql 나 MariaDB
Nginx + PHP-FPM + Mysql 나 MariaDB

이번 글에서는 yum(rpm)으로 Apache + PHP-FPM + Mysql 기술 하도록 하겠습니다.


설치 환경
OS: Fedora Linux 33 (5.8.18-300)
APACHE2.4.46 + PHP 7.4.12 + Mysql 8.0.22


설치순서는 apache mysql php 순으로 설치 하겠습니다 작업은 root 로 진행하겠습니다

# root 로 변경
$ sudo su -
[root]#




1. Apache 설치


[root]# dnf -y install httpd mod_proxy_html

[root]# httpd -v
Server version: Apache/2.4.46 (Fedora)
Server built: Aug 25 2020 00:00:00



2. Mysql 설치


# Mysql Repository 설치

[root]# rpm -ivh https://dev.mysql.com/get/mysql80-community-release-fc33-1.noarch.rpm
[root]# dnf clean all


# 설치
[root]# dnf -y install mysql-community-server mysql-community-devel mysql-community-server-debug


# Mysql의 root 패스워드 변경
[root]# systemctl start mysqld

* mysql 를 처음 시작 하고 로그에서 임시 비밀번호를 확인 할 수 있습니다.
[root]# cat /var/log/mysqld.log | grep "temporary password"
[Note] A temporary password is generated for root@localhost: RTZwovJ#r8*:

[root]# mysql -uroot -p
Enter password: <==위에서의 비밀번호 입력, RTZwovJ#r8*:

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '변경할 패스워드';
<-- 패스워드는 복잡도를 고려 해야 합니다.
mysql> commit;
mysql> flush privileges;
mysql> exit;


기본적인 mysql 파라미터 추가
[root]# vi /etc/my.cnf


[mysqld] <-- 절에 아래 내용을 추가로 입력해 줍니다.

user=mysql
server-id=1
log_bin = binlog
expire_logs_days=10

innodb_buffer_pool_size = 384M
innodb_file_per_table=TRUE
bind-address=0.0.0.0
log_timestamps=SYSTEM
character-set-client-handshake=OFF
skip-character-set-client-handshake

max_allowed_packet=500M
init_connect=SET collation_connection = utf8mb4_general_ci

init_connect=SET NAMES utf8mb4
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci


Mysql 를 재시작 합니다.
[root]# systemctl restart mysqld



3. PHP 설치


[root]# dnf -y install php php-common \
php-fpm php-gd \
build php php-devel \
php-mysqlnd php-opcache \
php-mbstring php-pdo \
php-pecl-imagick-devel php-pecl-mcrypt \
php-pecl-zip php-bcmath \
curl curl-devel php-pecl-imagick \
libpng libpng-devel libwebp libwebp-devel \
libXpm libXpm-devel openssl openssl-devel \
autoconf zlib zlib-devel freetype freetype-devel \
gd gd-devel libmcrypt libmcrypt-devel \
libtool-ltdl-devel libxml2-devel \
libxml2 libcurl libcurl-devel


[root] php -v
PHP 7.4.12 (cli) (built: Oct 27 2020 15:01:52) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.12, Copyright (c), by Zend Technologies



[root]# vi /etc/php.ini

아래 5개는 주석 제거 및 내용 수정
date.timezone = Asia/Seoul
expose_php = Off
post_max_size = 500M
upload_max_filesize = 200M
memory_limit = 512M




4. PHP-FPM 으로 Apache 연동


Apache 와의 연동을 PHP-FPM으로 하도록 하겠습니다.

향후 Nginx 로의 변경시 변경이 자유롭고 Apache MPM방식을 event(thread) 방식을 사용할 수 있는 장점이 있습니다.

성능 또한 Apache + mod_php 방식에 비해 PHP-FPM을 사용하여 별도로 php 로직을 처리해주는것이 성능적으로도 더좋다고 확인 되고 있습니다.

그래서 이미 이전 부터 php-fpm 을 많이 사용하는 추세 입니다.



## 먼저 apache 설정을 변경

# /etc/httpd/conf/httpd.conf  파일 수정

[root]# vi /etc/httpd/conf/httpd.conf
ServerName www.example.com:80
-> 주석 해제

-> 아래 쪽에 2개 내용추가
ServerTokens Prod
ServerSignature Off



아래 Directory 사이의 내용을 변경 합니다.
<Directory "/var/www/html">
…. 사이의 내용…
</Directory>

#Options Indexes FollowSymLinks
-> 주석 처리 후 아래 내용으로 입력

Options MultiViews FollowSymLinks
-> 내용 추가


#AllowOverride None
-> 주석 처리 후 아래 내용으로 입력

AllowOverride All
-> 내용 추가


# 00-proxy.conf 파일 수정
[root]# vi /etc/httpd/conf.modules.d/00-proxy.conf

아래 4개 내용 추가

ProxyRequests Off
ProxyErrorOverride on
ProxyTimeout 600
ProxyPreserveHost On





# php-fpm.conf 파일 수정
[root]# vi /etc/php-fpm.conf

include=/etc/php-fpm.d/*.conf
--> 주석이 해제 되어 있는지 확인

daemonize = yes
-> 주석으로 되어 있다면 주석을 해제 합니다.


; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
;log_level = notice
-> PHP-FPM 데몬의 Log level Default 는 notice 입니다.
-> 문제에 대한 분석이나 초기 설정 후 확인 등이 필요하다면 debug 레벨로 변경하여 사용해도 됩니다.




## www.conf 파일 수정
[root]# cd /etc/php-fpm.d/
[root]# vi www.conf


; pool name ('www' here)
[www]
-> PHP Pool 이름을 지정하는 항목 입니다.
-> 프로그램명이나 사이트 명이나, 업무가 있다면 업무명 등을 입력 하여도 됩니다.
-> Pool 혹은 Container 의 식별, 이름 입니다 기본으로 www 지정되어 있습니디.
-> Pool은 conf 파일 별로 여러개의 Pool을 만들 수 있습니다. 이때는 Pool 별로 이름을 지정하여 겹치지 않게 해야 합니다


= 아래 내용과 같이 되어 있는지 확인 및 주석이 되어 있다면 주석을 해제 합니다.
user = apache
group = apache
listen.acl_users = apache,nginx


listen = /run/php-fpm/www.sock
=> 이부분은 접속을 받는 방식을 설정하는 부분으로 Socket(UDS) 방식으로 사용 하거나 IP 방식으로 사용하거나 둘 중 하나를 선택하여 설정해야 합니다.

=> IP 방식으로는 아래와 같이 지정 할 수 있습니다.
listen = 123.123.123.123.123:9000
listen = 127.0.0.1:9000
listen = 9000 <== 이와 같이 IP 없이 포트만 기재하면 모든 주소에서 접속이 가능한 상태 입니다
(listen on a TCP socket to all addresses)


소켓 방식은 아래와 같이 파일명을 지정해주면 됩니다.
listen = /run/php-fpm/www.sock

같은 서버에서 apache 와 php-fpm 사용 하는 설정으로 할 것임으로 socket 을 지정하여 설정하도록 하겠습니다
같은 서버내 라도 IP를 사용 할 수 있고 사용하여도 됩니다.


# 프로세스 수와 관련된 pm 으로 시작하는 파라미터 가 있습니다
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 40
pm.max_requests = 500

* 위의 설정값은 예시입니다.

pm.max_children 는 설정된 PHP Pool(여기서는 www) 내에서 가동할 수 있는 최대 자식 프로세스 수를 의미 합니다

pm.start_servers 는 php-fpm 을 실행할 때 초기에 생성하는 자식 프로세스의 개수입니다

pm.min_spare_servers 는 idle 상태의 자식 프로세스 개수가 이 개수보다 작으면 자식 프로세스를 생성합니다

pm.max_spare_servers 는 idle 상태의 자식 프로세스의 최대 개수를 의미 합니다.


pm.max_requests 는 각 프로세스가 최대 request를 처리하면 수 입니다.
500 으로 설정되어 있다면 500번 request 후 프로세스를 다시 생성 합니다
프로세스가 점진적인 메모리 증가에 대한부분을 방지 할 수 있습니다.
apache 에서 유사한 설정으로는 MaxRequestsPerChild 있습니다.




[참고]
PHP-FPM 메모리 사용현황 및 세션 계산


아래 명령어를 이용하면 현재 fork된 php-fpm 프로세스 당 메모리 사용량을 확인 할 수 있습니다.

[root]# ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'

시스템에 가용한 메모리나 사용 할 정도에서 프로세스당 사용메모리를 나누어서 최대 자식프로세스 개수를 산정 해도 되겠습니다

ex) PHP에 6GB 를 사용 하려고 함 , PHP-FPM이 현재 사용중인 메모리량이 대략 60MB 임
6000MB / 60MB = 자식 프로세스 개수 100개 로 설정

이와 같이 각 시스템 마다 메모리 상황을 고려하여 적절한 pm.max_children 값을 선정하여 설정하면 되겠습니다.



= 로그 관련된 파라미터의 주석 해제와 변경을 합니다.
access.log = /var/log/php-fpm/$pool.access.log
-> 주석 해제 및 경로 지정


access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
--> 주석제거


slowlog = /var/log/php-fpm/$pool.slow.log
--> 주석제거, 파일명 변경


request_slowlog_timeout = 5
--> 주석제거, 내용변경
--> 단위는 초로 5는 예시 입니다. 해당 시간은 선택해서 변경 하시면 됩니다.


catch_workers_output = yes
-> 주석 제거
-> main error log 파일에 worker 의 에러 로그가 같이 기록 되게 됩니다.


php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
-> 주석 제거



# PHP Opcache 파라미터

[참고] PHP 5.5 버전 부터 기본에 포함되었으며 이전에는 zend optimizer 를 별도로 설치 및 plugin 하여 사용 하였습니다.

사용 용도는 컴파일 / 실행 / 결과 의 순으로 처리되는 PHP에 대해서 Opcache(예전의 Zend Optimizer)를
이용하여 컴파일된 PHP 코드를 메모리에 Cache 해서 접속요청에 더 빠르게 응답을 줄수 있는 기능 입니다

php7.x 버전부터 Opcache 의 기본 메모리가 128M  입니다.
메모리를 변경하거나 다른 파라미터를 조정 하고자 한다면 10-opcache.ini 에서 설정할 수 있습니다.

[root]# cd /etc/php.d
[root]# vi 10-opcache.ini

10-opcache.ini 파일에는 opcache 의 활성화 내용부터 해서 기본적으로 사용 될수 있는 파라미터는
주석이 해제되어 활성화가 되어 있는 상태 입니다.

opcache의 파라미터의 간략한 설명은 아래와 같습니다.

opcache.enable=1 - Zend Opacache 활성화 여부 결정 , 1일때 활성화 됨
opcache.enable_cli=1 - PHP CLI 버전에서(명령행 버전에서도) Zend Opcache 활성화 여부 결정
opcache.memory_consumption - 캐쉬에 사용할 메모리 크기. 7.0부터 기본 크기는 128M
opcache.interned_strings_buffer=8 - 메모리에서 interned 문자열을 위해 사용할 메모리량
opcache.fast_shutdown=1 - 활성화 시 accelerated code 에 대해서 사용되어짐
opcache.interned_strings_buffer - Opcache 가 사용하는 내부 스트링( class name 이나 file등)을 저장하기 위한 메모리의 크기.

opcache.max_accelerated_files - Opcache 가 캐쉬할 최대 파일 갯수.

opcache.validate_timestamps - Default 1 / 0(off)이 아닐 경우 opcache.revalidate_freq 에 설정된
시간마다 코드와 캐쉬의 변경 여부를 체크한다.

validate_timestamps 가 꺼져 있을 경우 코드의 변경 여부를 체크하지 않으므로 PHP 소스가 수정되어도 반영되지 않는다.
그러므로 변경 사항을 반영하려면 httpd 를 재기동하거나 httpd 에 SIGUSR2 시그널을 전송해야 한다.


opcache.file_cache_only=1 - makes sure that the in-memory opcache is disabled and only files are used, which is what you want for CLI.
1 로 설정할 경우 in-memory opcache 사용이 안됨 = php-fpm 에서 사용할수 없음


그래서 메모리 관련하여 수정이 필요 할 경우 아래와 같이 용량을 늘려서 사용 할 수 있습니다.
opcache.memory_consumption=256
-> 입력의 예시 이며 단위는 MB 입니다
-> 이부분(메모리 변경) 은 필수는 아닙니다.



## php-fpm 재시작
[root]]# systemctl restart php-fpm
* PHP-FPM 설치 후 자동으로 기동되어 있음



# 프로세스 및 포트 오픈 확인
[root]]# ps -ef| grep php
root 62849 1 0 11:26 00:00:00 php-fpm: master process (/etc/php-fpm.conf)
apache 62850 62849 0 11:26 00:00:00 php-fpm: pool www
apache 62851 62849 0 11:26 00:00:00 php-fpm: pool www
apache 62852 62849 0 11:26 00:00:00 php-fpm: pool www
apache 62853 62849 0 11:26 00:00:00 php-fpm: pool www
apache 62854 62849 0 11:26 00:00:00 php-fpm: pool www


# listen을 Unix Socket 으로 사용 할 경우
[root]]# ls -al /run/php-fpm
srw-rw----+ 1 root root 0 11월 29 11:35 www.sock


# listen을 IP 으로 사용 할 경우
[root]]# netstat -antp | grep 9000
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 6389/php-fpm: master



## OS 방화벽 오픈 합니다.
# 80 포트 추가
[root]]# firewall-cmd --permanent --add-port=80/tcp

# 80 포트 삭제(참고)
[root]]# firewall-cmd --permanent --remove-port=80/tcp

# 정책 재반영 및 방화벽 정책 확인
[root]]# firewall-cmd --reload;firewall-cmd --list-all


/var/www/html 에 아래 내용으로 phpinfo.php 파일을  생성 합니다
[root]]# cd /var/www/html
[root]]# vi phpinfo.php

<?php
phpinfo();
?>



# apache 재시작
[root]# systemctl restart httpd



# 접속 테스트
http://ip주소/phpinfo.php





연관된 글



답글 남기기