SSD Nodes Learn Hosting plans →
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-07

Ubuntu 24.04 LAMP 스택 설치 및 PHP-FPM 설정 가이드

Ubuntu 24.04에서 Apache, MariaDB, PHP 8.3을 연동하는 방법을 설명합니다. PHP-FPM 연결 오류와 Certbot 인증서 발급 시 발생하는 흔한 문제 해결법을 포함하여, 운영 환경에 최적화된 LAMP 스택 구축 과정을 단계별로 안내합니다.

구축할 시스템

LAMP 스택은 Ubuntu 24.04 서버 한 대에서 작동하는 네 가지 구성 요소입니다. 기반이 되는 Linux, HTTP 요청을 처리하는 Apache, 데이터를 저장하는 MariaDB, 코드를 실행하는 PHP 8.3으로 이루어집니다. 이 과정을 마치면 실제 애플리케이션 디렉터리를 서비스하는 이름 기반 가상 호스트, 최소 권한을 가진 전용 사용자가 관리하는 데이터베이스, PHP-FPM을 통해 Apache와 연결된 PHP, 그리고 Let's Encrypt에서 발급받은 무료 인증서가 적용된 환경을 갖추게 됩니다.

설치 과정은 apt 명령 네 개로 완료됩니다. 이 가이드의 대부분은 각 구성 요소를 연결하는 설정과, 새로 구축한 스택에서 빈 페이지가 출력되거나, 소스 코드가 브라우저로 다운로드되거나, 데이터베이스 접속이 거부되는 등의 흔한 오류를 해결하는 데 할애합니다. 이러한 문제들은 각각 고유한 징후가 있으며, 아래에 각 오류 상황에서 나타나는 정확한 메시지와 함께 설명되어 있습니다.

사전 요구 사항 및 주의 사항

Ubuntu 24.04 기반의 신규 KVM VPS와 sudo 권한을 가진 사용자 또는 root 계정, 그리고 공인 IPv4 주소가 준비되어 있다고 가정합니다. 최소 사양의 스택은 1 GB RAM으로도 실행 가능하지만, 실제 데이터베이스 기반 애플리케이션을 운영하려면 2 GB로 증설하십시오. MariaDB의 기본 버퍼와 몇 개의 PHP-FPM 워커만으로도 첫 1 GB는 금방 소진되기 때문입니다.

마지막 단계에서 Certbot이 정상적으로 작동하려면 두 가지 조건이 충족되어야 하므로 지금 미리 준비하십시오. 첫째, VPS의 공인 IP를 가리키는 A 레코드가 포함된 도메인 이름이 필요합니다. Let's Encrypt는 해당 도메인 이름으로 HTTP 검증을 수행하므로, IP 주소만으로는 인증서를 발급받을 수 없습니다. 둘째, 80번과 443번 포트가 외부 인터넷에서 접속 가능해야 합니다. 많은 클라우드 제공업체에서는 서버 내부의 ufw 설정뿐만 아니라 제어판의 네트워크 방화벽에서도 해당 포트를 개방해야 합니다. DNS 변경 사항이 전파되는 데 최대 1시간이 소요될 수 있으므로, A 레코드를 먼저 설정해 두면 인증서 발급 시점에는 정상적으로 반영될 것입니다.

1단계 - Apache 설치 및 기본 페이지 확인

sudo apt update
sudo apt install -y apache2

apt은 서비스를 시작하고 활성화합니다. 다음 명령으로 확인하십시오.

systemctl status apache2

active (running)라는 문구가 포함된 줄을 확인해야 합니다. 이제 브라우저에서 http://YOUR_SERVER_IP/을 엽니다. "It works!"라는 큰 배너가 있는 Apache2 Ubuntu Default Page가 나타나면 정상입니다. 이는 Apache가 오류 없이 서비스를 제공하고 있다는 증거입니다. 해당 페이지는 /var/www/html/index.html에 위치하며, 기본으로 제공되는 가상 호스트인 000-default.conf를 통해 서비스됩니다. 두 항목 모두 나중에 비활성화할 예정이지만, 지금은 이 페이지가 표시되는 것이 정상입니다.

페이지가 전혀 로드되지 않지만 systemctl에서 프로세스가 실행 중이라고 표시된다면, 방화벽이 차단하고 있는 것입니다. 다음 단계에서 이를 해결합니다.

2단계 - HTTP 및 HTTPS를 위한 방화벽 개방

apache2 패키지는 세 가지 ufw 애플리케이션 프로필을 등록합니다. 다음 명령으로 목록을 확인하십시오:

sudo ufw app list

Apache, Apache Full, Apache Secure이 표시될 것입니다. Apache는 80번 포트 전용이며, Apache Secure은 443번 포트 전용입니다. Apache Full는 두 포트를 모두 포함하므로, 마지막 단계에서 TLS를 추가할 때 이 프로필을 사용해야 합니다.

sudo ufw allow OpenSSH
sudo ufw allow "Apache Full"
sudo ufw enable

ufw enable을 실행하기 전에 OpenSSH를 허용하십시오. ufw은 기본적으로 모든 수신 트래픽을 거부합니다. SSH 규칙 없이 방화벽을 활성화하면 즉시 연결이 끊어집니다. 현재 세션은 유지되더라도 다시는 재접속할 수 없게 됩니다. sudo ufw status로 설정을 확인하십시오. OpenSSH, Apache Full 및 해당 v6 버전이 모두 ALLOW 상태로 표시되어야 합니다.

3단계 - MariaDB 설치 및 보안 설정

sudo apt install -y mariadb-server
systemctl status mariadb

Ubuntu 24.04는 장기 지원(LTS) 릴리스인 MariaDB 10.11을 기본 제공하므로 외부 저장소를 추가할 필요가 없습니다. 서비스가 실행 중인 상태에서 다음 명령으로 보안을 강화합니다.

sudo mysql_secure_installation

설정 과정에서 나타나는 질문들은 Enter 키를 연타하기보다 읽어보는 것이 좋습니다. current root password를 물으면 Enter를 누르십시오. 아직 설정된 비밀번호가 없습니다. "Switch to unix_socket authentication?" 질문은 이 패키지에서 이미 활성화되어 있으므로 어떤 선택을 하든 결과는 같습니다. 따라서 n를 입력하십시오. 다음 단락에서 설명할 이유로 "Change the root password?"에는 n이라고 답하십시오. 그 후 나머지 질문인 익명 사용자 제거, 원격 root 로그인 차단, 테스트 데이터베이스 삭제, 권한 테이블 새로고침에는 모두 Y를 선택하십시오.

많은 사용자가 혼란스러워하는 부분은 다음과 같습니다. Ubuntu의 MariaDB에서 root 데이터베이스 계정은 비밀번호가 아닌 unix_socket 인증을 사용합니다. 이는 데이터베이스가 이미 인증을 마친 운영체제 사용자를 신뢰한다는 의미입니다. 따라서 root 셸에서 다음 명령을 실행하면 정상적으로 작동합니다.

sudo mysql

...그러면 비밀번호를 묻지 않고 바로 MariaDB [(none)]> 프롬프트로 진입합니다. 권한이 없는 일반 사용자로 같은 명령을 실행하면 거부되는데, 이것이 바로 핵심입니다. 데이터베이스 root 접근 권한은 서버의 sudo 계정과 연동되어 있으며, 탈취하거나 피싱하거나 무차별 대입 공격을 할 비밀번호 자체가 존재하지 않습니다. 이는 비밀번호보다 훨씬 안전하므로 설정을 변경하지 마십시오. 여기서 도출되는 규칙은 다음과 같습니다. 애플리케이션을 root 계정에 연결하지 마십시오. 애플리케이션마다 전용 사용자를 생성하십시오(7단계). TCP를 통해 사용자 이름과 비밀번호로 접속하는 애플리케이션은 어차피 소켓 인증을 사용할 수 없으며, 각 애플리케이션은 자신의 데이터베이스에만 접근하도록 제한하는 것이 바람직하기 때문입니다.

단계 4 - PHP 8.3 및 PHP-FPM 설치

Ubuntu 24.04의 기본 PHP 버전은 8.3입니다. FPM 프로세스 관리자와 일반적인 애플리케이션에 필요한 확장 기능을 설치합니다.

sudo apt install -y php8.3-fpm php8.3-mysql php8.3-cli \
  php8.3-curl php8.3-xml php8.3-mbstring php8.3-zip

목록에 포함되지 않은 libapache2-mod-php에 유의하십시오. 해당 구형 패키지는 모든 Apache 프로세스 내부에 PHP 인터프리터를 포함합니다. 구성은 간단하지만, 스크립트를 처리하든 정적 이미지를 전송하든 모든 워커가 PHP 복사본을 유지해야 하며, 두 프로세스의 수명 주기가 결합되어 있습니다. 또한 이는 가장 효율성이 낮은 Apache의 prefork MPM에서만 작동합니다. 반면 PHP-FPM은 PHP를 별도의 프로세스 풀로 실행하며, Apache는 소켓을 통해 이와 통신합니다. 이를 통해 Apache는 정적 파일 처리에 스레드 기반의 event MPM을 사용하고 PHP 요청만 FPM으로 전달할 수 있습니다. 프로세스 풀은 웹 서버와 독립적으로 튜닝할 수 있으며, 나중에 nginx로 전환하더라도 동일한 FPM 설정을 그대로 사용할 수 있습니다. 이것이 현재 기본값으로 채택된 이유입니다.

Apache는 proxy_fcgi 모듈을 통해 FPM에 접근합니다. 해당 모듈을 활성화하고 FPM 패키지가 생성한 설정을 적용한 뒤 재시작합니다.

sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.3-fpm
sudo systemctl restart apache2

a2enconf php8.3-fpm은 PHP 파일을 FPM 소켓으로 라우팅하는 규칙이 포함된 /etc/apache2/conf-available/php8.3-fpm.conf를 활성화합니다. 이 설정의 핵심은 모든 .php 파일을 찾아 /run/php/php8.3-fpm.sock에 위치한 소켓으로 전달하는 것입니다.

<FilesMatch ".+\.ph(ar|p|tml)$">
    SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>

이 파일은 올바르게 제공되므로 직접 수정할 필요가 없습니다. 하지만 소켓 경로를 파악하고 있으면 나중에 발생할 수 있는 "PHP가 실행되지 않고 다운로드됨" 오류나 "Primary script unknown" 오류를 진단할 수 있습니다. 두 오류 모두 Apache와 FPM이 해당 소켓이나 그 뒤의 파일에 대해 서로 다르게 인식할 때 발생합니다.

5단계 - 애플리케이션을 위한 이름 기반 가상 호스트 설정

이름 기반 가상 호스팅을 사용하면 하나의 IP 주소로 여러 사이트를 서비스할 수 있습니다. Apache는 요청에 포함된 Host: 헤더를 확인하여 사이트를 구분합니다. 기본 경로인 /var/www/html에서 벗어난 곳에 애플리케이션을 위한 디렉터리를 생성하십시오.

sudo mkdir -p /var/www/testapp
sudo chown -R www-data:www-data /var/www/testapp
sudo chmod -R 755 /var/www/testapp

소유권 설정이 중요합니다. Ubuntu에서 Apache와 PHP-FPM은 모두 www-data 사용자로 실행됩니다. 따라서 웹 서버가 읽어야 하는 파일과 업로드 폴더처럼 애플리케이션이 쓰기 작업을 수행해야 하는 디렉터리는 www-data가 소유해야 합니다. 로그인한 사용자로 파일을 직접 수정해야 한다면, 파일을 본인 소유로 두고 사용자를 www-data 그룹에 추가하는 방식이 일반적입니다. 단순 배포 환경이라면 www-data:www-data로 설정하는 것이 가장 직관적입니다.

/etc/apache2/sites-available/testapp.conf 경로에 가상 호스트 파일을 생성하십시오.

<VirtualHost *:80>
    ServerName app.example.com
    DocumentRoot /var/www/testapp

    <Directory /var/www/testapp>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/testapp-error.log
    CustomLog ${APACHE_LOG_DIR}/testapp-access.log combined
</VirtualHost>

ServerName를 실제 도메인으로 설정하십시오. Options -Indexes는 인덱스 파일이 없을 때 Apache가 디렉터리 목록을 노출하지 않도록 방지합니다. 이 설정을 하지 않으면 방문자가 소스 트리 구조를 열람할 수 있습니다. AllowOverride All은 대부분의 PHP 애플리케이션이 깔끔한 URL을 위해 요구하는 .htaccess 파일의 동작을 허용합니다. 애플리케이션에서 해당 기능이 필요 없다면 성능 향상을 위해 None로 변경하십시오. 사이트를 활성화하고, 기본 사이트를 비활성화한 뒤, 설정을 검사하고 다시 불러오십시오.

sudo a2ensite testapp
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2

apache2ctl configtest 명령을 실행하면 Syntax OK이 출력되어야 합니다. a2dissite 000-default 줄은 사용자가 자주 누락하는 부분이며, 나중에 기본 페이지가 그대로 유지되는 것처럼 보이는 원인이 됩니다. 자세한 내용은 실패 해결 섹션을 참조하십시오.

6단계 - PHP 실행 확인 및 테스트 파일 삭제

애플리케이션 루트 디렉터리에 한 줄짜리 PHP 파일을 생성합니다.

echo "<?php phpinfo();" | sudo tee /var/www/testapp/info.php

http://app.example.com/info.php에 접속합니다. 정상적인 결과라면 로드된 모듈이 나열된 보라색과 회색의 긴 PHP Version 8.3.x 표가 나타나며, Server API 줄에 FPM/FastCGI라고 표시되어야 합니다. 이 마지막 줄은 요청이 mod_php가 아닌 PHP-FPM을 통해 처리되고 있음을 의미합니다.

이제 즉시 파일을 삭제합니다.

sudo rm /var/www/testapp/info.php

phpinfo()는 정확한 PHP 버전, 로드된 모든 확장 모듈, 파일 경로, 환경 설정 정보를 노출하므로, 서버의 취약점을 찾는 공격자에게는 좋은 정보원이 됩니다. 이는 기능이 아니라 테스트용 파일입니다. 페이지를 확인한 즉시 삭제하십시오. 만약 브라우저에서 표가 나타나지 않고 info.php 파일을 다운로드하겠냐고 묻는다면, PHP가 Apache와 올바르게 연결되지 않은 것입니다. 다른 작업을 수행하기 전에 먼저 실패 해결 섹션으로 이동하십시오.

7단계 - 애플리케이션 데이터베이스 및 최소 권한 사용자 생성

소켓 인증을 사용하는 root 계정으로 데이터베이스에 접속합니다.

sudo mysql

그런 다음 데이터베이스 하나와 해당 데이터베이스에만 권한이 제한된 사용자 하나를 생성합니다.

CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

여기에는 세 가지 의도적인 선택이 포함되어 있습니다. utf8mb4은 실제 4바이트 UTF-8을 지원합니다. 구형 utf8 별칭은 이모지나 일부 CJK 문자를 자동으로 잘라내므로 항상 utf8mb4를 사용해야 합니다. 권한 부여는 *.*이 아닌 appdb.*에 수행합니다. 이렇게 하면 해당 사용자는 자신의 데이터베이스만 접근할 수 있으므로, 애플리케이션에서 SQL 인젝션 취약점이 발생해도 다른 사이트의 테이블을 읽을 수 없습니다. 또한 'appuser'@'localhost'는 해당 계정의 접속을 서버 내부에서 발생하는 연결로만 제한합니다.

해당 사용자로 접속을 테스트합니다.

mysql -u appuser -p appdb

비밀번호를 입력하면 MariaDB [appdb]> 프롬프트가 나타납니다. -h 플래그가 없다는 점에 유의하십시오. 이 플래그를 생략하면 클라이언트는 로컬 Unix 소켓을 통해 연결하며, MariaDB는 이를 정확히 localhost로 간주합니다. 알아두어야 할 주의 사항이 있습니다. MySQL과 MariaDB에서 localhost은 Unix 소켓을 의미하고 127.0.0.1은 TCP 연결을 의미합니다. 기본 Ubuntu 24.04 MariaDB 환경에서는 서버가 127.0.0.1에서 오는 TCP 연결을 localhost로 해석하므로 두 경우 모두 계정이 일치합니다. 하지만 skip-name-resolve이 활성화된 서버(일반적인 성능 최적화 설정이며 많은 컨테이너 이미지의 기본값)에서는 두 연결이 서로 다른 호스트로 간주됩니다. 따라서 127.0.0.1로 접속하는 애플리케이션은 비밀번호가 정확하더라도 ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' (using password: YES) 오류로 인해 거부됩니다.

따라서 애플리케이션의 호스트 설정은 root이 아닌 localhost, 사용자 appuser, 데이터베이스 appdb로 지정하십시오. PHP의 mysqli 및 PDO는 호스트가 문자열 localhost일 때 자동으로 Unix 소켓을 사용하며, 이는 방금 생성한 계정과 일치합니다. 만약 프레임워크가 반드시 숫자 형태의 TCP 호스트를 요구한다면, 실제 연결 방식에 맞춰 'appuser'@'127.0.0.1'로 사용자를 생성하십시오. 다른 머신에서 데이터베이스에 접근해야 하는 경우에만 방화벽 규칙과 함께 @'%'을 사용하십시오.

8단계 - Certbot으로 HTTPS 추가하기

일반 HTTP로 로그인 폼을 제공하면 비밀번호가 평문으로 전송되며, 모든 최신 브라우저는 해당 페이지를 "주의 요함"으로 표시합니다. Certbot은 단 하나의 명령어로 이 문제를 해결합니다. Apache 플러그인과 함께 설치하십시오:

sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache

Certbot은 여기서 두 가지 플러그인을 사용합니다. apache authenticator는 실행 중인 Apache를 통해 챌린지 파일을 잠시 제공함으로써 사용자가 해당 도메인을 제어하고 있음을 증명하며, apache installer는 가상 호스트를 다시 작성하여 443 블록을 추가하고 새 인증서를 지정합니다. Certbot 2.0부터는 리다이렉트 여부를 묻지 않으며 기본적으로 모든 HTTP 트래픽을 HTTPS로 리다이렉트합니다. 일반 HTTP 서비스를 계속 유지해야 한다면 --no-redirect 플래그를 전달하십시오. 5단계에서 실제 ServerName을 설정했으므로 Certbot이 도메인을 자동으로 감지합니다. 인증서 유효 기간은 90일이며, 패키지는 인증서를 갱신하는 systemd 타이머를 설치합니다. sudo certbot renew --dry-run로 타이머를 확인하십시오. 결과는 Congratulations, all simulated renewals succeeded로 끝나야 합니다.

챌린지 과정, 갱신 타이머, DNS 및 방화벽 요구 사항에 대한 전체 안내는 Apache에서 Certbot을 사용하여 무료 Let's Encrypt TLS 인증서 발급하기 가이드를 참조하십시오.

백업, 업그레이드 및 보안 강화

상태 정보를 담고 있는 데이터베이스와 웹 루트, 이 두 가지를 백업해야 합니다. 매일 밤 수행하는 논리적 덤프가 가장 간단하고 신뢰할 수 있는 방법이며, sudo sh -c 'mysqldump --all-databases --single-transaction | gzip > /root/db-$(date +%F).sql.gz'을 사용한 뒤 서버 외부로 복사합니다. 전체 파이프라인을 sudo sh -c로 감싸는 것이 중요합니다. 그렇지 않으면 셸이 > /root/... 리다이렉트를 현재 사용자의 권한으로 실행하여 Permission denied 오류가 발생합니다. mysqldump만이 sudo를 상속받기 때문입니다. --single-transaction를 사용하면 InnoDB 테이블을 잠그지 않고도 일관된 스냅샷을 얻을 수 있습니다. 이를 /var/www/etc/apache2/sites-availabletar과 함께 구성하면, 해당 파일들로 새로운 VPS에서 전체 스택을 재구축할 수 있습니다.

업그레이드는 일반적인 sudo apt update && sudo apt upgrade 과정입니다. 주의해야 할 점은 PHP 버전 업데이트입니다. 향후 Ubuntu 버전에서 기본값이 PHP 8.4로 변경되면, apt이 8.3과 함께 php8.4-fpm을 설치할 수 있습니다. 이때 소켓은 /run/php/php8.4-fpm.sock가 되지만 Apache 설정은 여전히 8.3 소켓을 가리키고 있을 수 있습니다. 새로운 설정을 활성화(sudo a2enconf php8.4-fpm)하고 이전 설정을 비활성화하십시오. 그렇지 않으면 일상적인 업그레이드 후 사이트에서 Primary script unknown 오류가 발생합니다. PHP 릴리스 주기가 LTS 배포판보다 빠르므로, 패치 버전을 고정하기보다는 현재 PHP 릴리스 노트를 확인하십시오.

운영 첫날 수행할 가치가 있는 두 가지 보안 강화 단계가 있습니다. 첫째, 서버에 SSH를 감시하는 Fail2Ban을 설치하십시오. 공개 VPS는 수 분 내에 자동화된 로그인 시도를 받게 되며, 작은 감옥(jail) 설정을 통해 수천 번의 시도를 차단하기 전 몇 번의 시도로 줄일 수 있습니다. 둘째, Apache 가상 호스트, MariaDB 데이터베이스 및 사용자를 파일을 직접 수정하는 대신 브라우저를 통해 관리하고 싶다면, 웹 기반 제어 패널인 Webmin을 사용하십시오. 이 도구는 방금 작성한 것과 동일한 스택 위에서 작동하며 동일한 설정 파일을 제어합니다. 두 도구 모두 각 구성 요소에 대한 이해를 대신할 수는 없지만, 일상적인 운영의 번거로움을 줄여줍니다.

실패 유형 및 확인되는 메시지

기본 페이지가 사라지지 않습니다. 가상 호스트를 수정하고 리로드했음에도 브라우저에 여전히 "Apache2 Ubuntu Default Page"와 "It works!" 배너가 표시됩니다. Apache는 요청과 일치하는 첫 번째 가상 호스트를 제공합니다. 요청과 일치하는 ServerName가 없으면 알파벳순으로 가장 앞선 설정이 우선하는데, 000-default.conftestapp.conf보다 먼저 정렬됩니다. 요청의 호스트 이름이 ServerName와 일치하지 않거나 sudo a2dissite 000-default을 실행하지 않은 경우입니다. sudo systemctl reload apache2을 사용하여 기본 설정을 비활성화하고, apache2ctl -S을 실행하여 가상 호스트 맵을 확인하십시오. 어떤 설정이 기본값을 점유하고 있는지 알 수 있습니다. 브라우저 캐시도 삭제하십시오. 이전 페이지의 200 응답이 캐시에 남아 계속 표시될 수 있습니다.

.php 파일이 실행되지 않고 다운로드됩니다. info.php를 열었을 때 브라우저가 <?php 소스 코드가 포함된 파일을 다운로드하거나 일반 텍스트로 표시합니다. PHP 핸들러가 연결되지 않았거나, sudo a2enmod proxy_fcgi 또는 sudo a2enconf php8.3-fpm 단계를 건너뛰었거나, 이후 Apache를 재시작하지 않아 Apache가 해당 파일을 정적 자산으로 처리하는 것입니다. 세 명령을 모두 실행(4단계)하고 리로드하십시오. apache2ctl -M | grep fcgi을 실행하여 proxy_fcgi_module가 목록에 있는지 확인하여 모듈이 로드되었는지 확인하십시오. 이는 단순한 외관상의 문제가 아니라 소스 코드 유출이므로 실제 데이터를 서버에 올리기 전에 반드시 해결해야 합니다.

ERROR 1698 (28000): Access denied for user 'root'@'localhost'. sudo 없이 mysql -u root 또는 mariadb -u root을 실행했습니다. root 계정은 unix_socket 인증을 사용하므로, OS 사용자가 실제로 root인 경우에만 접속을 허용합니다. 해결 방법은 sudo mysql을 사용하는 것이며, -u root이나 비밀번호는 필요하지 않습니다. 이 메시지는 소켓 인증이 정상적으로 작동하고 있음을 나타내는 기대된 동작이며, 설치가 잘못된 것이 아닙니다.

애플리케이션에서 발생하는 ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' (올바른 비밀번호 사용 시). 계정은 'appuser'@'localhost'으로 존재하지만, 애플리케이션이 호스트 이름 해석이 비활성화된(skip-name-resolve) 서버에서 127.0.0.1로 TCP 연결을 시도하고 있습니다. MariaDB는 두 접속을 서로 다른 호스트로 인식합니다. localhost은 유닉스 소켓이고 127.0.0.1은 TCP이기 때문입니다. 애플리케이션이 소켓을 사용하여 계정과 일치하도록 호스트를 localhost로 지정하거나, 프레임워크가 TCP만 지원한다면 'appuser'@'127.0.0.1' 계정을 별도로 생성하십시오.

/var/log/apache2/testapp-error.log 내의 AH01071: Got error 'Primary script unknown', 브라우저에는 File not found. 표시. Apache가 요청을 PHP-FPM으로 전달했으나, FPM이 Apache로부터 전달받은 경로에서 스크립트를 찾지 못했습니다. 두 가지 주요 원인이 있습니다. 설정의 FPM 소켓이 설치되지 않은 PHP 버전을 가리키고 있거나(업그레이드 후 8.3만 실행 중인데 php8.4 소켓을 참조하는 경우), DocumentRoot와 실제 디렉터리 경로가 일치하지 않아 파일이 실제로 존재하지 않는 경우입니다. ls -l /run/php/로 소켓 존재 여부를 확인하고, DocumentRoot이 실제 파일 위치와 일치하는지 확인한 뒤 php8.3-fpmapache2을 모두 재시작하십시오.

재시작 시마다 발생하는 AH00558: apache2: Could not reliably determine the server's fully qualified domain name. 이는 오류가 아닌 무해한 경고입니다. Apache가 전역 ServerName이 설정되지 않았음을 알리는 것입니다. ServerName your.domain/etc/apache2/conf-available/servername.conf에 작성하고 sudo a2enconf servername을 실행하여 이 메시지를 숨길 수 있습니다.

Apache 시작 시 (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80. 다른 웹 서버가 이미 80번 포트를 점유하고 있습니다. 이전 실험에서 실행된 nginx가 남아있는 경우가 많습니다. sudo ss -ltnp | grep :80로 해당 프로세스를 찾은 뒤, Apache를 시작하기 전에 다른 서비스를 중지하고 비활성화하십시오.

FAQ

mod_php와 PHP-FPM 중 무엇을 사용해야 합니까?

PHP-FPM을 사용하십시오. mod_php은 모든 Apache 프로세스에 인터프리터를 내장하며 느린 prefork MPM 사용을 강제하므로, 정적 이미지를 서비스할 때도 Apache가 PHP 오버헤드를 짊어지게 됩니다. PHP-FPM은 PHP를 별도의 독립적으로 튜닝된 풀로 실행하며, Apache는 소켓을 통해 이 풀에 접근합니다. 이는 더 빠른 스레드 기반 event MPM과 함께 작동하며, 나중에 nginx로 전환할 때도 그대로 사용할 수 있습니다. 이것이 현대적인 기본 설정입니다. mod_php는 프로세스 내부 동작에 의존하는 레거시 애플리케이션을 운영할 때만 의미가 있습니다.

브라우저에서 PHP 파일을 실행하지 않고 다운로드하는 이유는 무엇입니까?

Apache가 .php 파일을 PHP 핸들러가 연결되지 않은 정적 다운로드 파일로 처리하고 있기 때문입니다. FPM을 사용하는 Ubuntu 24.04 환경에서 이런 현상이 발생한다면 sudo a2enmod proxy_fcgi, sudo a2enconf php8.3-fpm 중 하나를 누락했거나 Apache 재시작을 수행하지 않은 것입니다. 세 가지 명령을 모두 실행하고 리로드한 뒤, apache2ctl -M | grep fcgi 명령으로 proxy_fcgi_module가 목록에 있는지 확인하십시오. 이 문제를 해결하기 전까지 서버는 소스 코드를 그대로 노출하므로 긴급하게 처리해야 합니다.

올바른 비밀번호를 입력해도 MariaDB에서 root 접근이 거부되는 이유는 무엇입니까?

Ubuntu의 MariaDB는 비밀번호가 설정되어 있지 않을 경우 root 계정을 unix_socket으로 인증하며, 이를 운영체제의 root 사용자와 연결하기 때문입니다. 일반 셸에서 mysql -u root을 실행하면 설계상 ERROR 1698 (28000): Access denied for user 'root'@'localhost'이 반환됩니다. 대신 sudo mysql로 접속하고, root 계정을 재사용하는 대신 애플리케이션용으로 별도의 비밀번호 인증 사용자를 생성하십시오.

LAMP 사이트에 HTTPS를 추가하려면 어떻게 해야 합니까?

certbotpython3-certbot-apache을 설치하고, 도메인의 A 레코드를 서버 IP로 지정한 뒤 sudo certbot --apache을 실행하십시오. Apache 인증기는 실행 중인 Apache를 통해 도메인 소유권을 증명하며, 설치 프로그램이 포트 443에 대한 가상 호스트를 재작성하고 자동 갱신을 설정합니다. Certbot과 Apache 전체 가이드에서 챌린지 과정, 갱신 타이머, 일반적인 실패 사례를 확인할 수 있습니다.

#lamp#apache#mariadb#php-fpm#ubuntu