본 문서는 RockyLinux 10 웹서버 구축 시리즈의 두 번째 글입니다. 1편에서 서버 초기 설정, SELinux, Firewall, 필수 패키지 설치를 정리했다면, 이번 글에서는 RockyLinux 10 환경에서 PHP 8.5를 설치하고 PHP-FPM을 운영 가능한 상태로 구성하는 과정을 정리합니다.
PHP 기반 웹사이트를 운영할 때 PHP 설치만으로는 충분하지 않습니다. 실제 운영 서버에서는 nginx 와 PHP 를 직접 연결하지 않고, PHP-FPM을 통해 PHP 요청을 처리하는 구조를 사용합니다. nginx 는 정적 파일과 HTTP 요청을 처리하고, PHP-FPM 은 PHP 스크립트 실행을 담당하는 방식입니다.
이 글에서는 Remi Repository 를 이용해 PHP 8.5 를 설치하고, 자주 사용하는 PHP 확장 모듈을 함께 설치한 뒤, php.ini와 php-fpm 기본 설정까지 진행합니다.
1. PHP 8.5 설치 방식
RockyLinux 기본 저장소에서 제공되는 PHP 버전은 보통 최신 PHP 버전보다 낮습니다. 운영 서버에서 최신 PHP 버전이 필요한 경우에는 Remi Repository 를 사용하는 것이 일반적입니다.
Remi Repository 는 RHEL 계열 배포판에서 PHP 최신 버전과 다양한 PHP 확장 패키지를 제공하는 저장소입니다. RockyLinux, AlmaLinux, RHEL 계열 서버에서 PHP 8.x 버전을 설치할 때 자주 사용됩니다.
여기서는 RockyLinux 10 기준으로 Remi Repository 를 설치한 뒤 PHP 8.5 모듈을 활성화합니다.
2. Remi Repository 설치
먼저 Remi Repository RPM 패키지를 설치합니다.
dnf install https://rpms.remirepo.net/enterprise/remi-release-10.rpm설치 후에는 PHP 모듈 목록을 확인할 수 있습니다.
dnf module list php이 명령을 실행하면 RockyLinux 기본 PHP 스트림과 Remi 에서 제공하는 PHP 스트림 목록이 표시됩니다. 여기서 php:remi-8.5 스트림을 활성화합니다.
3. PHP 8.5 활성화
PHP 8.5 스트림을 활성화합니다.
dnf module enable php:remi-8.5 -y이미 다른 PHP 모듈 스트림이 활성화되어 있다면 충돌이 발생할 수 있습니다. 이 경우에는 기존 PHP 모듈을 reset 한 뒤 다시 활성화합니다.
dnf module reset php -y
dnf module enable php:remi-8.5 -y신규 서버라면 보통 reset 과정 없이 바로 활성화해도 됩니다.
4. PHP 및 주요 확장 모듈 설치
PHP-FPM 과 개발에 자주 사용하는 PHP 확장 모듈을 함께 설치합니다.
dnf install -y php-fpm php-devel php-json php-mbstring php-opcache php-pdo php-pecl-geoip php-pecl-imagick php-tidy php-xml php-gd php-mysql php-pecl-zip php-curl php-bcmath위 명령은 PHP 실행 환경과 함께 일반적인 웹 개발에 필요한 모듈을 설치합니다. CMS, 게시판, 관리자 시스템, 파일 업로드, 이미지 처리, API 연동 등을 운영하려면 대부분의 경우 위 모듈들이 필요합니다.
주요 패키지 설명
php-fpm: nginx 와 연동하여 PHP 스크립트를 실행하는 FastCGI Process Manager 입니다.
php-devel: PHP 확장 모듈을 컴파일하거나 PECL 패키지를 설치할 때 필요한 개발 헤더를 제공합니다.
php-json: JSON 인코딩과 디코딩 기능을 제공합니다. API 연동이 많은 웹서비스에서는 필수에 가깝습니다.
php-mbstring: 한글과 같은 멀티바이트 문자열 처리를 위해 필요합니다.
php-opcache: PHP 바이트코드를 메모리에 캐시하여 PHP 실행 성능을 향상시킵니다.
php-pdo: PDO 기반 데이터베이스 연결을 위한 공통 모듈입니다.
php-mysql: MariaDB 또는 MySQL 연결을 위해 사용합니다. mysqli, pdo_mysql 등을 포함합니다.
php-gd: 썸네일 생성, 이미지 리사이즈 등 기본 이미지 처리를 위해 사용합니다.
php-pecl-imagick: ImageMagick 기반 이미지 처리를 PHP 에서 사용할 수 있게 해줍니다.
php-curl: 외부 API 호출, HTTP 요청, 결제 연동, 문자 발송 API 연동 등에 필요합니다.
php-bcmath: 정밀한 수치 계산이 필요한 경우 사용합니다. 결제, 정산, 금액 계산 로직이 있는 서비스에서는 설치해두는 것이 좋습니다.
5. PHP 설치 확인
설치가 완료되면 PHP 버전을 확인합니다.
php -vPHP 8.5 버전이 표시되면 정상입니다.
PHP 8.5.x (cli) (built: ...)
Copyright (c) The PHP Group
Zend Engine v4.x.x, Copyright (c) Zend Technologies
with Zend OPcache설치된 PHP 모듈 목록은 아래 명령으로 확인할 수 있습니다.
php -m특정 모듈만 확인하고 싶다면 grep 을 사용할 수 있습니다.
php -m | grep -E 'mbstring|curl|pdo_mysql|imagick|gd|Zend OPcache'6. PHP 설정 파일 구성
PHP 설정은 기본적으로 /etc/php.ini에서 관리할 수 있습니다. 다만 운영 서버에서는 기본 파일을 직접 수정하기보다, 별도 ini 파일을 추가하여 필요한 설정만 덮어쓰는 방식이 관리하기 좋습니다.
여기서는 /etc/php.d/z-php.ini 파일을 생성합니다. 파일명이 z-로 시작하면 비교적 뒤쪽 순서에 로드되므로 기존 설정을 덮어쓰기 쉽습니다.
vi /etc/php.d/z-php.ini아래 내용을 입력합니다.
expose_php = Off
upload_max_filesize = 200M
max_file_uploads = 100
post_max_size = 800M
date.timezone = Asia/Seoul설정 항목 설명
expose_php = Off: HTTP 응답 헤더에서 PHP 버전 노출을 막습니다. 보안상 PHP 버전 정보를 노출하지 않는 것이 좋습니다.
upload_max_filesize = 200M: 단일 업로드 파일의 최대 크기를 200MB로 설정합니다.
max_file_uploads = 100: 한 번의 요청에서 업로드 가능한 파일 개수를 100개로 설정합니다.
post_max_size = 800M: POST 요청 전체 크기의 최대값입니다. 파일 여러 개를 업로드하는 경우
upload_max_filesize보다 충분히 크게 설정해야 합니다.date.timezone = Asia/Seoul: PHP 의 기본 시간대를 한국 시간으로 설정합니다.
파일 업로드 기능이 있는 관리자 시스템이나 CMS 에서는 upload_max_filesize와 post_max_size 설정이 중요합니다. 다만 너무 크게 설정하면 비정상적인 대용량 요청에 서버 자원이 낭비될 수 있으므로 서비스 성격에 맞게 조정해야 합니다.
7. PHP-FPM 기본 구조
PHP-FPM 은 PHP FastCGI Process Manager 의 약자입니다. nginx 는 PHP 파일을 직접 실행하지 못하므로 PHP 요청을 PHP-FPM 으로 전달합니다. PHP-FPM 은 전달받은 PHP 스크립트를 실행하고 결과를 nginx 에게 반환합니다.
일반적인 구조는 다음과 같습니다.
사용자 브라우저
↓
nginx
↓
PHP-FPM
↓
PHP 애플리케이션 실행
↓
MariaDB / Redis / 외부 API따라서 PHP 기반 웹서버에서는 nginx 설정과 PHP-FPM 설정이 함께 맞아야 정상적으로 동작합니다.
8. PHP-FPM 서비스 등록
서버 재부팅 후에도 PHP-FPM 이 자동으로 실행되도록 서비스를 등록합니다.
systemctl enable php-fpm바로 실행하려면 아래 명령을 사용합니다.
systemctl start php-fpm상태 확인은 다음과 같이 합니다.
systemctl status php-fpm9. PHP-FPM Pool 설정
PHP-FPM 의 기본 pool 설정 파일은 보통 /etc/php-fpm.d/www.conf입니다. 이 파일에서 PHP 프로세스를 어떤 사용자 권한으로 실행할지, 어떤 방식으로 nginx 와 통신할지, 프로세스 수를 어떻게 관리할지 설정할 수 있습니다.
vi /etc/php-fpm.d/www.conf기본적으로 아래 항목을 확인하거나 수정합니다.
user = 사용자계정
group = 사용자계정여기서 사용자계정은 실제 웹 소스 파일을 소유하고 있는 계정으로 변경하면 됩니다. 예를 들어 웹 소스가 /home/honam/src에 있고 파일 소유자가 honam이라면 다음처럼 설정할 수 있습니다.
user = honam
group = honamPHP-FPM 실행 계정과 웹 소스 파일 소유자가 맞지 않으면 파일 업로드, 캐시 생성, 로그 작성, 세션 파일 생성 등에서 권한 문제가 발생할 수 있습니다.
다만 여러 사이트를 하나의 서버에서 운영한다면 사이트별로 PHP-FPM pool 을 분리하는 것이 더 안전합니다. 각 사이트마다 별도 사용자 계정을 두고, pool 도 개별로 나누면 한 사이트의 권한 문제가 다른 사이트로 확산되는 위험을 줄일 수 있습니다.
10. PHP-FPM Listen 설정 확인
www.conf에서 nginx 와 PHP-FPM 이 통신하는 방식도 확인해야 합니다. 일반적으로 TCP 방식 또는 Unix Socket 방식을 사용합니다.
TCP 방식 예시
listen = 127.0.0.1:9000Unix Socket 방식 예시
listen = /run/php-fpm/www.sockTCP 방식은 설정이 단순하고 확인이 쉽습니다. Unix Socket 방식은 같은 서버 내부 통신에서 약간 더 효율적일 수 있지만, 소켓 파일 권한 설정을 추가로 신경 써야 합니다.
nginx 설정에서 fastcgi_pass 값은 PHP-FPM 의 listen 값과 일치해야 합니다.
nginx 에서 TCP 방식으로 연결하는 경우
fastcgi_pass 127.0.0.1:9000;nginx 에서 upstream 이름으로 연결하는 경우
upstream php-fpm {
server 127.0.0.1:9000;
}fastcgi_pass php-fpm;이후 nginx 편에서 fastcgi_pass php-fpm; 구조를 사용할 예정이라면 nginx 설정 안에 upstream 정의가 필요합니다.
11. PHP-FPM 프로세스 설정
운영 서버에서는 PHP-FPM 프로세스 수 설정도 중요합니다. 너무 적으면 동시 요청 처리량이 부족하고, 너무 많으면 메모리를 과도하게 사용합니다.
기본적으로 www.conf 안에는 다음과 같은 설정이 있습니다.
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35주요 항목 설명
pm: 프로세스 관리 방식을 설정합니다. 일반적으로
dynamic또는ondemand를 사용합니다.pm.max_children: 동시에 실행 가능한 PHP-FPM 자식 프로세스의 최대 개수입니다.
pm.start_servers: PHP-FPM 시작 시 미리 띄워둘 프로세스 개수입니다.
pm.min_spare_servers: 유휴 상태로 유지할 최소 프로세스 개수입니다.
pm.max_spare_servers: 유휴 상태로 유지할 최대 프로세스 개수입니다.
서버 메모리가 충분하지 않은데 pm.max_children 값을 너무 크게 잡으면 메모리 부족으로 서버가 불안정해질 수 있습니다. 반대로 너무 작게 설정하면 트래픽이 조금만 늘어도 요청 대기가 발생할 수 있습니다.
실무에서는 PHP-FPM 프로세스 하나가 사용하는 평균 메모리를 확인한 뒤, 사용 가능한 메모리를 기준으로 pm.max_children 값을 계산하는 것이 좋습니다.
ps -ylC php-fpm --sort:rss또는 다음 명령으로 PHP-FPM 프로세스의 메모리 사용량을 대략 확인할 수 있습니다.
ps aux | grep php-fpm12. PHP-FPM 재시작
설정을 변경한 뒤에는 PHP-FPM 을 재시작합니다.
systemctl restart php-fpm재시작 후 상태를 확인합니다.
systemctl status php-fpm설정 파일에 오류가 있으면 서비스가 시작되지 않습니다. 이 경우 journalctl 로 로그를 확인합니다.
journalctl -u php-fpm -xe13. PHP 설정 적용 여부 확인
CLI 기준 PHP 설정은 아래 명령으로 확인할 수 있습니다.
php -i | grep "Loaded Configuration File"
php -i | grep "Scan this dir"
php -i | grep "upload_max_filesize"
php -i | grep "post_max_size"
php -i | grep "date.timezone"다만 PHP CLI 와 PHP-FPM 은 실행 환경이 다를 수 있습니다. 웹에서 실제 적용 여부를 확인하려면 임시로 phpinfo() 파일을 만들어 확인할 수 있습니다.
<?php
phpinfo();확인이 끝나면 phpinfo() 파일은 반드시 삭제해야 합니다. PHP 버전, 모듈, 서버 경로, 환경 정보가 노출될 수 있기 때문입니다.
14. OPcache 기본 확인
PHP 운영 서버에서는 OPcache 사용 여부가 성능에 큰 영향을 줍니다. OPcache 는 PHP 스크립트를 매 요청마다 다시 파싱하고 컴파일하지 않도록 바이트코드를 메모리에 캐시합니다.
OPcache 로드 여부는 다음 명령으로 확인할 수 있습니다.
php -v출력에 Zend OPcache가 표시되면 OPcache 가 로드된 것입니다.
OPcache 설정 파일은 보통 다음 경로에 있습니다.
/etc/php.d/10-opcache.ini기본 설정으로도 운영은 가능하지만, 트래픽이 많은 사이트라면 메모리 크기, 캐시 파일 수, validate_timestamps 설정 등을 별도로 튜닝할 수 있습니다. 이 부분은 실제 애플리케이션 규모와 배포 방식에 따라 달라지므로 별도 성능 튜닝 단계에서 조정하는 것이 좋습니다.
15. 운영 서버에서 권장하는 PHP-FPM 관리 방식
사이트별 사용자 분리: 여러 사이트를 운영한다면 각 사이트마다 리눅스 사용자와 PHP-FPM pool 을 분리하는 것이 좋습니다.
소스 소유권 정리: PHP-FPM 실행 계정이 파일 업로드 디렉터리, 캐시 디렉터리, 로그 디렉터리에 접근할 수 있어야 합니다.
phpinfo 삭제: 점검 후 phpinfo 파일은 반드시 삭제해야 합니다.
불필요한 확장 최소화: 사용하지 않는 PHP 확장은 보안과 관리 측면에서 줄이는 것이 좋습니다.
타임아웃 관리: 외부 API 호출, 대용량 업로드, PDF 생성처럼 오래 걸리는 작업이 있다면 PHP 실행 시간과 nginx timeout 을 함께 검토해야 합니다.
16. 자주 발생하는 문제
1) nginx 에서 502 Bad Gateway 발생
nginx 가 PHP-FPM 에 연결하지 못할 때 발생합니다. PHP-FPM 서비스가 실행 중인지 확인합니다.
systemctl status php-fpmnginx 의 fastcgi_pass 값과 PHP-FPM 의 listen 값이 일치하는지도 확인해야 합니다.
2) 파일 업로드가 되지 않음
upload_max_filesize, post_max_size, nginx 의 client_max_body_size 값을 함께 확인해야 합니다. PHP 설정만 크게 잡아도 nginx 설정이 작으면 업로드 요청이 nginx 단계에서 차단됩니다.
3) 업로드 파일 저장 실패
PHP-FPM 실행 계정이 업로드 디렉터리에 쓰기 권한을 가지고 있는지 확인해야 합니다.
ls -al /home/USER/src
ls -al /home/USER/src/uploads필요하다면 소유권을 정리합니다.
chown -R USER:USER /home/USER/src4) PHP 설정을 바꿨는데 적용되지 않음
PHP-FPM 을 재시작했는지 확인해야 합니다.
systemctl restart php-fpm또한 설정 파일이 실제로 로드되는 디렉터리에 있는지도 확인합니다.
php --ini17. 최종 명령어 요약
전체 과정을 명령어만 정리하면 다음과 같습니다.
# Remi Repository 설치
dnf install https://rpms.remirepo.net/enterprise/remi-release-10.rpm
# PHP 8.5 활성화
dnf module enable php:remi-8.5 -y
# PHP 및 주요 모듈 설치
dnf install -y php-fpm php-devel php-json php-mbstring php-opcache php-pdo php-pecl-geoip php-pecl-imagick php-tidy php-xml php-gd php-mysql php-pecl-zip php-curl php-bcmath
# PHP 설정 파일 생성
vi /etc/php.d/z-php.ini
# PHP-FPM 설정
vi /etc/php-fpm.d/www.conf
# PHP-FPM 서비스 등록 및 시작
systemctl enable php-fpm
systemctl start php-fpm
systemctl status php-fpm마무리
이번 글에서는 RockyLinux 10 환경에서 Remi Repository 를 이용해 PHP 8.5 를 설치하고, PHP-FPM 을 운영 가능한 상태로 구성하는 방법을 정리했습니다.
PHP 웹서비스 운영에서 중요한 것은 단순히 PHP 를 설치하는 것이 아니라, nginx 와 PHP-FPM 이 안정적으로 연동될 수 있도록 실행 계정, 설정 파일, 업로드 제한, 타임존, 확장 모듈, 서비스 등록 상태를 함께 정리하는 것입니다.
다음 글에서는 PHP 세션 저장소로 사용할 Valkey(Redis)를 설치하고, PHP 세션을 파일 방식이 아닌 Redis 방식으로 전환하는 방법을 정리합니다.