리눅스 APM(Apache + PHP + MySQL) 설치 및 연동 - Rocky Linux 8

Share

Last Updated on 9월 29, 2022 by Jade(정현호)

안녕하세요 
이번 포스팅에서는 Rocky Linux 8 에서  APM(Apache + PHP + MySQL) 설치 및 연동 내용에 대해서 확인 해보려고 합니다.  

APM

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

PHP 를 구동 하기 위한 서버 스택의 구성은 여러가지 방식으로 할 수 있습니다.

Apache + PHP(mod_php) + MySQL 나 MariaDB
Apache + PHP-FPM + MySQL 나 MariaDB
Nginx + PHP-FPM + MySQL 나 MariaDB


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

• 설치 환경

OS: Rocky Linux 8.6
Apache 2.4.37 + PHP-FPM 8.2.0 + MySQL 8.0.26
설치순서는 Apache MariaDB PHP-FPM 순으로 설치 진행 합니다.


• CentOS 7 에서 APM 구성은 아래 글을 참조 하시면 됩니다.


• 우분투 환경에서의 APM 은 아래 글을 참조 하시면 됩니다.

                     

사전 환경 구성

외부 Repository 구성

• dnf 구성

sudo dnf install epel-release
sudo dnf install epel-next-release
sudo dnf update

sudo dnf -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm


• remi repo 활성화

user$ sudo dnf --disablerepo="*" --enablerepo="remi" list available
Importing GPG key 0x5F11735A:
 Userid     : "Remi's RPM repository <remi@remirepo.net>"
 Fingerprint: 6B38 FEA7 231F 87F5 2B9C A9D8 5550 9759 5F11 735A
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-remi.el8
Is this ok [y/N]: y

user$ sudo dnf --disablerepo="*" --enablerepo="remi-safe" list available
Importing GPG key 0x5F11735A:
 Userid     : "Remi's RPM repository <remi@remirepo.net>"
 Fingerprint: 6B38 FEA7 231F 87F5 2B9C A9D8 5550 9759 5F11 735A
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-remi.el8
Is this ok [y/N]: y

user$ sudo dnf --disablerepo="*" --enablerepo="remi-modular" list available
Importing GPG key 0x5F11735A:
 Userid     : "Remi's RPM repository <remi@remirepo.net>"
 Fingerprint: 6B38 FEA7 231F 87F5 2B9C A9D8 5550 9759 5F11 735A
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-remi.el8
Is this ok [y/N]: y


사전 필요 패키지 설치

• 패키지 설치

sudo dnf -y install gcc gcc-c++ \
pcre-devel make git openssl wget vim \
unzip GeoIP-devel git tree cmake \
expat-devel libxml2-devel \
openssl openssl-devel python3 \
curl gnupg2 libxslt-devel gd-devel \
perl-ExtUtils-Embed rsyslog

                         

Apache

• 패키지 설치

sudo dnf -y install httpd httpd-devel \
apr apr-util apr-devel apr-util-devel \
apr-util-openssl mod_proxy_html apr-util \
libnghttp2 mod_http2 mod_ssl httpd-tools


버전 확인

user$ httpd -V
Server version: Apache/2.4.37 (rocky)
Server built:   Jun 22 2022 14:17:54
Server's Module Magic Number: 20120211:83
Server loaded:  APR 1.6.3, APR-UTIL 1.6.1
Compiled using: APR 1.6.3, APR-UTIL 1.6.1
Architecture:   64-bit
Server MPM:     event
  threaded:     yes (fixed thread count)
    forked:     yes (variable process count)

 

MySQL

• 패키지 설치

sudo dnf -y install mysql mysql-common \
mysql-devel mysql-libs mysql-selinux mysql-server



기본 파라미터 추가

• 설정 파일 수정

sudo vi /etc/my.cnf.d/mysql-server.cnf


[mysqld] <-- 절에 아래 내용을 추가로 입력해 줍니다.
user=mysql
server-id=1
log_bin = binlog
binlog_expire_logs_seconds=432000
innodb_buffer_pool_size = 384M
innodb_file_per_table=TRUE
# bind-address=0.0.0.0
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 시작

sudo systemctl start mysqld


• 버전 확인

user$ sudo mysql 

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.26 Source distribution

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select @@version;
+-----------+
| @@version |
+-----------+
| 8.0.26    |
+-----------+

                  

PHP

• REMI PHP 8.2 설치

sudo dnf -y install php82 php82-php-common \
php82-php-fpm php82-php-gd php82-php-xml \
php82 php82-php-devel php82-libzip \
php82-php-mysqlnd php82-php-opcache \
php82-php-mbstring php82-php-pdo \
php82-php-pecl-imagick-devel php82-php-pecl-selinux \
php82-php-pecl-zip php82-php-bcmath \
curl curl-devel php82-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 php82-php-soap \
php82-php-pecl-xattr php82-php-pecl-imagick-im7 


• 버전 확인

user$ php82 -v 
PHP 8.2.0beta3 (cli) (built: Aug 16 2022 15:45:22) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.2.0-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.0beta3, Copyright (c), by Zend Technologies


포스팅에서는 8.2 버전으로 설치를 하였지만, 다른 버전을 설치 해도 경로만 다르고 설정은 동일 합니다.
8.1 또는 7.4 버전으로 설치를 원하시는 분은 위의 명령에서 버전만 변경 하시면 됩니다.
             

php.ini 파일 수정

• php.ini 파일 수정

cd /etc/opt/remi/php82/
sudo vi php.ini


## 아래 5개는 주석 제거(; 제거) 및 내용 수정

date.timezone = Asia/Seoul
expose_php = Off
post_max_size = 500M
upload_max_filesize = 200M
memory_limit = 512M

파일을 수정 하였다면 저장 후 종료 합니다.
       

PHP-FPM 설정

포스팅에서는 Apache 와 PHP 의 연동을 PHP-FPM 으로 사용 하였습니다. 그렇기 때문에 PHP-FPM 에 대한 설정이 필요 합니다.

Apache 는 mod_php 를 통해서 Apache 와 PHP 와의 연동 설정이 기존 부터 사용하던 보통의 방식이지만 최근에는 PHP-FPM 이 성능상 더 좋기 이점이 있어서 PHP-FPM 을 많이 사용하는 추세 입니다.
             

php-fpm.conf

• php-fpm.conf 파일 수정

cd /etc/opt/remi/php82/
sudo vi php-fpm.conf


include=/etc/opt/remi/php82/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

pool 에 해당 하는 설정으로 파일 별로 pool 을 생성 할 수 있으며 pool 별로 포트와 이름 등을 달리하여 시작 할 수 있습니다.
포스팅에서는 기본 생성되어 있는 www pool 을 수정하여 사용 하였습니다.

• www.conf 파일 수정

cd /etc/opt/remi/php82/php-fpm.d
sudo cp www.conf www.conf.ori

sudo vi www.conf


www.conf 파일을 아래와 같이 내용을 수정 합니다.

• 설정1

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


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


listen = /var/opt/remi/php82/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 = listen = /var/opt/remi/php82/run/php-fpm/www.sock


• 설정2 - PHP-FPM 프로세스 관련

# 같은 서버에서 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 있습니다.


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

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

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 값을 선정하여 설정 합니다.


• 설정3 - 로그 설정
로그 관련된 내용의 주석 해제와 변경을 합니다

access.log = /var/opt/remi/php82/log/php-fpm/$pool.access.log
-> 주석 해제 및 경로 지정


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


slowlog = /var/opt/remi/php82/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/opt/remi/php82/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 에서 설정할 수 있습니다.

• 파일 수정

cd /etc/opt/remi/php82/php.d
sudo 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=256
- 캐쉬에 사용할 메모리 크기. PHP 7.0 부터 기본 크기는 128M
-> 입력의 예시 이며 단위는 MB 입니다
-> 이부분(메모리 변경) 은 필수는 아닙니다.
-> 사용시 앞에 주석(;) 을 제거 합니다.

opcache.interned_strings_buffer=8
- 메모리에서 interned 문자열을 위해 사용할 메모리량
- Opcache 가 사용하는 내부 스트링( class name 이나 file등 )을 저장하기 위한 메모리의 크기

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

opcache.validate_timestamps
- Default 1 / 0(off)이 아닐 경우 opcache.revalidate_freq 에 설정된
- 시간마다 코드와 캐쉬의 변경 여부를 체크 합니다.
- validate_timestamps 가 비활성화 되어 있을 경우 
- 코드의 변경 여부를 체크하지 않으므로 PHP 소스가 수정되어도 반영되지 않습니다.
- 그러므로 변경 사항을 반영하려면 httpd 를 재기동 합니다.



PHP-FPM 재시작

설정이 완료 되었다면 PHP-FPM 을 재시작 합니다.

sudo systemctl restart php82-php-fpm

* PHP-FPM 설치 후 자동으로 기동되어 있을수 있음


프로세스 및 포트 오픈 확인

• 프로세스

user$ ps -ef| grep php
root 62849 1 0 11:26 00:00:00 php-fpm: master process (/etc/opt/remi/php82/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 으로 사용 할 경우

user$ ls -al /var/opt/remi/php82/run/php-fpm/
srw-rw----+ 1 root root  0 Aug 27 01:43 www.sock


- listen 을 IP 으로 사용 할 경우

user$ netstat -antp | grep 9000
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 6389/php-fpm: master

            

Apache 설정

• 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 파일 수정

cd /etc/httpd/conf.modules.d/
sudo vi 00-proxy.conf


## 아래 4개 내용 추가

ProxyRequests Off
ProxyErrorOverride on
ProxyTimeout 600
ProxyPreserveHost On


[참고] PHP-FPM 과 연결되는 Proxy_Pass 설정은 아래 파일내에 대부분이 설정되어 있습니다.
/etc/httpd/conf.d/php82-php.conf
              

방화벽 설정 및 Apache 재시작

• OS 방화벽 오픈

# 80 포트 추가
user$ sudo firewall-cmd --permanent --add-port=80/tcp

# 80 포트 삭제(참고)
user$ sudo firewall-cmd --permanent --remove-port=80/tcp

# 정책 재반영 및 방화벽 정책 확인
user$ sudo firewall-cmd --reload;firewall-cmd --list-all


[참고] 클라우드 사용시 클라우드 네트워크의 보안 정책이나 클라우드의 방화벽도 오픈을 해줘야 합니다.


• phpinfo.php 파일 생성
PHP 정상 작동 여부 확인을 위해 phpinfo.php 파일을 생성 합니다.

cd /var/www/html
sudo vi phpinfo.php


## 아래 내용으로 파일 내용 입력

<?php
phpinfo();
?>


• Apache 재시작

sudo systemctl restart httpd


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



연관된 다른 글 

 

 

 

             

0
글에 대한 당신의 생각을 기다립니다. 댓글 의견 주세요!x