SSD Nodes Learn
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-07-24

Ubuntu 24.04 LAMP 스택 구축 가이드 PHP-FPM 포함

Ubuntu 24.04에서 Apache, MariaDB, PHP 8.3 및 PHP-FPM을 설치합니다. unix_socket 인증 방식과 Certbot을 이용한 HTTPS 설정까지 포함하며, 메모리 부족이나 포트 차단 오류를 방지하는 팁을 제공합니다.

구축 목표

LAMP 스택은 하나의 Ubuntu 24.04 서버에서 작동하는 네 가지 구성 요소로 이루어집니다. 기반이 되는 Linux, HTTP 요청을 처리하는 Apache, 데이터를 저장하는 MariaDB, 그리고 코드를 실행하는 PHP 8.3입니다. 과정을 마치면 도메인 기반의 virtual host가 실제 애플리케이션 디렉토리를 서비스하고, 최소 권한을 가진 전용 사용자가 관리하는 데이터베이스가 준비됩니다. 또한 PHP-FPM을 통해 Apache와 연결된 PHP와 Let's Encrypt 무료 인증서까지 구성됩니다.

설치 과정은 네 개의 apt 명령어로 진행됩니다. 이 가이드의 대부분은 각 구성 요소를 연결하는 방법과, 설치 직후 발생할 수 있는 일반적인 오류를 다룹니다. 오류가 발생하면 빈 페이지가 표시되거나, 소스 코드가 브라우저에서 다운로드되거나, 데이터베이스 접속이 거부될 수 있습니다. 이러한 오류들은 고유한 특징이 있으며, 아래에 실제 화면에 나타나는 메시지와 함께 정리되어 있습니다.

Prerequisites and the honest gotchas

sudo 권한을 가진 user 또는 root 계정, 그리고 공인 IPv4 주소를 가진 신규 Ubuntu 24.04 KVM VPS를 가정합니다. 최소 스택은 1 GB RAM에서 실행됩니다. 실제 데이터베이스 기반 애플리케이션을 설치하기 전에 2 GB를 할당하십시오. MariaDB의 기본 버퍼와 소수의 PHP-FPM worker가 1 GB를 빠르게 점유하기 때문입니다.

마지막 단계의 Certbot이 정상 작동하려면 다음 두 가지 조건이 충족되어야 합니다. 먼저 준비하십시오. VPS의 공인 IP를 가리키는 A 레코드가 설정된 domain name이 필요합니다. Let'srypt는 해당 이름에 대해 HTTP를 통해 검증을 수행하며, IP 주소만으로는 인증서를 받을 수 없습니다. 또한 인터넷에서 80 및 443 포트에 접속할 수 있어야 합니다. 많은 서비스 제공업체의 경우, 서버 내부의 ufw 설정뿐만 아니라 제어판의 네트워크 방화벽에서도 해당 포트를 열어야 합니다. DNS 변경 사항은 전파되는 데 최대 1시간이 소요될 수 있습니다. 따라서 A 레코드를 먼저 설정하면 작업에 필요한 시점에는 적용이 완료될 것입니다.

Step 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에 위치하며, 기본 제공되는 default virtual host인 000-default.conf에 의해 제공됩니다. 이 두 설정은 나중에 비활성화할 예정입니다. 현재는 이 페이지가 보이는 것이 정상적인 상태입니다.

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

Step 2 - HTTP 및 HTTPS를 위한 firewall 개방

apache2 패키지는 3개의 ufw application profile을 등록합니다. 목록은 다음과 같습니다:

sudo ufw app list

Apache, Apache Full, Apache Secure이 표시됩니다. Apache은 80 포트 전용이며, Apache Secure은 443 포트 전용입니다. Apache Full은 두 포트 모두를 포함합니다. TLS를 추가할 예정이므로 Apache Full을 사용해야 합니다.

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

ufw enable을 실행하기 전에 OpenSSH을 허용하십시오. ufw의 기본 설정은 모든 incoming traffic을 차단하는 것입니다. SSH rule 없이 이를 활성화하면 활성화 즉시 연결이 끊깁니다. 현재 세션은 유지되지만 재접속이 불가능해집니다. sudo ufw status으로 확인하십시오. OpenSSH, Apache Full 및 해당 v6 항목이 모두 ALLOW 상태여야 합니다.

Step 3 - MariaDB 설치 및 보안 설정

sudo apt install -y mariadb-server
systemctl status mariadb

Ubuntu 24.04에는 LTS(Long-term-support) 버전인 MariaDB 10.11이 포함되어 있으므로 외부 repository를 추가할 필요가 없습니다. 서비스가 실행 중인 상태에서 보안 설정을 수행합니다:

sudo mysql_secure_installation

Enter 키를 무작정 누르기보다 프롬프트 내용을 읽어야 합니다. current root password를 묻는 경우, 아직 설정된 비밀번호가 없으므로 Enter를 누릅니다. "Switch to unix_socket authentication?" 질문은 이 패키지에서 이미 활성화되어 있으므로 결과가 변하지 않습니다. 따라서 n를 선택합니다. 다음 단락의 이유로 인해 "Change the root password?" 질문에는 n을 선택하고, 나머지 질문(anonymous users 제거, remote root login 금지, test database 삭제, privilege tables reload)에는 Y으로 응답합니다.

이 부분에서 많은 사용자가 혼란을 겪습니다. Ubuntu의 MariaDB에서 root 데이터베이스 계정은 비밀번호가 아닌 unix_socket 인증을 사용합니다. 이는 데이터베이스가 이미 인증된 operating-system 사용자를 신뢰함을 의미합니다. 따라서 root shell에서 다음 명령어가 작동합니다:

sudo mysql

...명령어를 실행하면 비밀번호 입력 없이 MariaDB [(none)]> 프롬프트로 진입합니다. 권한이 없는 사용자가 동일한 명령어를 실행하면 거부됩니다. 이것이 핵심입니다. 데이터베이스 root에 대한 액세스는 시스템의 sudo과 연결되어 있으며, 탈취, 피싱 또는 brute-force 공격을 당할 비밀번호 자체가 존재하지 않습니다. 이는 비밀번호 방식보다 더 안전하므로 설정을 변경하지 마십시오. 여기서 도출되는 규칙은 다음과 같습니다: 절대로 애플리케이션이 root 계정을 사용하도록 설정하지 마십시오. 애플리케이션마다 전용 사용자를 생성하십시오(Step 7). TCP를 통해 사용자 이름과 비밀번호로 연결되는 애플리케이션은 socket 인증을 사용할 수 없으며, 각 애플리케이션의 권한을 해당 데이터베이스로 제한해야 하기 때문입니다.

Step 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 요청만 전달할 수 있습니다. 프로세스 풀은 웹 서버와 독립적으로 튜닝할 수 있으며, 나중에 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 간의 소켓 또는 파일 경로 불일치로 인해 발생합니다.

Step 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 사용자로 실행됩니다. 따라서 웹 서버가 읽어야 하는 파일과 uploads 폴더처럼 앱이 쓰기 권한을 가져야 하는 디렉토리는 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를 설정하면 index 파일이 없을 때 Apache가 디렉토리 목록을 표시하는 것을 방지합니다. 설정하지 않으면 방문자가 소스 트리 구조를 탐색할 수 있습니다. AllowOverride All를 설정하면 대부분의 PHP 애플리케이션이 Pretty URL을 위해 요구하는 .htaccess 파일이 작동합니다. 앱에 이 기능이 필요 없다면 None에 배치하여 성능을 약간 향상시킬 수 있습니다. 이 사이트를 활성화하고, 기본 사이트를 비활성화한 뒤, 설정을 확인하고 다시 로드하십시오:

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

apache2ctl configtest를 실행하면 Syntax OK이 출력되어야 합니다. a2dissite 000-default 라인은 사용자들이 자주 누락하는 부분이며, 이로 인해 기본 페이지가 계속 표시되는 문제가 발생합니다. 자세한 내용은 failures 섹션을 참조하십시오.

Step 6 - PHP 실행을 확인한 후 테스트 파일 삭제

app root 디렉토리에 한 줄짜리 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가 연결되지 않은 상태입니다. 다른 작업을 수행하기 전에 failures 섹션으로 이동하십시오.

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

socket-authenticated 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-byte UTF-8입니다. 기존의 utf8 alias는 이모지 및 일부 CJK 문자를 조용히 잘라내므로 항상 utf8mb4를 사용해야 합니다. 권한 부여는 appdb.*에 대해 수행하며, *.*이 아닙니다. 이 사용자는 자신의 데이터베이스만 접근할 수 있습니다. 따라서 애플리케이션에서 SQL-injection 취약점이 발생하더라도 다른 사이트의 테이블을 읽을 수 없습니다. 또한 'appuser'@'localhost'는 계정이 로컬 호스트에서 발생하는 연결로만 제한되도록 합니다.

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

mysql -u appuser -p appdb

비밀번호를 입력하면 MariaDB [appdb]> 프롬프트가 나타납니다. -h 플래그가 없는 점에 유의하십시오. 이 플래그를 사용하지 않으면 클라이언트는 로컬 Unix socket을 통해 연결되며, MariaDB는 이를 localhost로 간주합니다. 주의할 점이 하나 있습니다. MySQL과 MariaDB에서 localhost은 Unix socket을 의미하며, 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) 오류와 함께 연결이 거부됩니다.

따라서 애플리케이션의 host는 localhost, user는 appuser, database는 appdb로 설정하십시오. root은 절대 사용하지 마십시오. PHP의 mysqli과 PDO는 host가 문자열 localhost일 때 방금 생성한 계정과 일치하는 Unix socket으로 전환됩니다. 만약 프레임워크가 숫자 형태의 TCP host를 요구한다면, 실제 연결 방식에 맞춰 사용자를 생성하십시오. 즉, 'appuser'@'127.0.0.1'를 사용하거나, 다른 머신에서 데이터베이스에 접속해야 하는 경우에만 (방화벽 규칙과 함께) @'%'을 사용하십시오.

Step 8 - Certbot을 사용하여 HTTPS 추가하기

HTTP를 통해 로그인 양식을 전송하면 비밀번호가 평문으로 전송됩니다. 모든 최신 브라우저는 해당 페이지를 "Not secure"로 표시합니다. Certbot을 사용하면 명령 한 줄로 이 문제를 해결할 수 있습니다. Apache 플러그인을 사용하여 설치하십시오:

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

Certbot은 여기서 두 개의 플러그인을 사용합니다. apache authenticator는 실행 중인 Apache를 통해 인증용 파일을 일시적으로 제공하여 도메인 소유권을 증명합니다. apache installer는 virtual host를 재작성하여 443 블록을 추가하고, 새 인증서를 지정하며, 모든 HTTP 트래픽을 기본적으로 HTTPS로 리다이렉트합니다. Certbot 2.0부터는 리다이렉트 여부를 묻지 않습니다. 평문 HTTP를 계속 사용해야 하는 경우 --no-redirect를 전달하십시오. Step 5에서 실제 ServerName를 설정했으므로 Certbot이 도메인을 자동으로 감지합니다. 인증서 유효 기간은 90일이며, 패키지는 인증서를 갱신하는 systemd timer를 설치합니다. timer는 Congratulations, all simulated renewals succeeded로 끝나는 sudo certbot renew --dry-run 명령어로 확인할 수 있습니다.

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

Backups, upgrades, and hardening

상태를 유지하는 두 가지 요소인 database와 web root를 백업하십시오. 매일 밤 수행하는 logical dump가 가장 간단하고 신뢰할 수 있는 방법입니다. sudo sh -c 'mysqldump --all-databases --single-transaction | gzip > /root/db-$(date +%F).sql.gz'를 실행한 후 서버 외부로 복사하십시오. 전체 파이프라인을 sudo sh -c으로 감싸는 것이 중요합니다. 이를 수행하지 않으면 shell이 > /root/... redirect를 현재 사용자 권한으로 실행하며, mysqldumpsudo을 상속받기 때문에 Permission denied 오류가 발생합니다. --single-transaction를 사용하면 InnoDB table을 잠그지 않고 일관된 snapshot을 생성할 수 있습니다. 이를 /var/www/etc/apache2/sites-availabletar과 함께 보관하면, 새 VPS에서 해당 파일들만으로 전체 stack을 재구축할 수 있습니다.

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

설치 첫날 수행해야 할 두 가지 hardening 단계가 있습니다. 첫째, 서버에 Fail2Ban SSH 모니터링을 설치하십시오. 공개 VPS는 몇 분 내에 자동화된 로그인 시도에 노출됩니다. 작은 jail을 설정하면 수천 번의 시도를 차단하기 전 몇 번의 시도로 제한할 수 있습니다. 둘째, 파일을 직접 편집하는 대신 브라우저를 통해 Apache virtual hosts, MariaDB databases, users를 관리하고 싶다면, Webmin 웹 기반 제어 패널을 사용하십시오. 이 패널은 현재 stack 위에서 작동하며 방금 작성한 것과 동일한 config 파일을 제어합니다. 두 도구 모두 구성 요소를 이해하는 과정을 대체하지는 않지만, 일상적인 관리의 번거로움을 줄여줍니다.

Failure modes, with the strings you will see

기본 페이지가 사라지지 않습니다. virtual host를 수정하고 reload를 수행했음에도 브라우저에 여전히 "Apache2 Ubuntu Default Page"와 "It works!" 배너가 표시됩니다. Apache는 요청과 일치하는 첫 번째 virtual host를 제공합니다. 일치하는 ServerName가 없으면 알파벳 순서가 빠른 설정이 우선 적용됩니다. 000-default.conftestapp.conf보다 먼저 정렬됩니다. 요청의 host name이 ServerName와 일치하지 않거나, sudo a2dissite 000-default을 실행하지 않았기 때문입니다. 기본 설정을 비활성화(sudo systemctl reload apache2)한 후, apache2ctl -S을 실행하여 vhost 맵을 확인하십시오. apache2ctl -S은 어떤 설정이 기본 설정을 점유하고 있는지 보여줍니다. 브라우저 캐시도 삭제하십시오. 이전 페이지의 200 응답이 캐시에 남아 있을 수 있습니다.

.php 파일이 실행되지 않고 다운로드됩니다. info.php를 열었을 때 브라우저가 파일을 실행하는 대신 <?php 소스 코드가 포함된 파일을 다운로드하거나 일반 텍스트로 표시합니다. PHP handler가 연결되지 않아 Apache가 해당 파일을 정적 자산으로 제공하고 있습니다. sudo a2enmod proxy_fcgi 또는 sudo a2enconf php8.3-fpm 단계를 누락했거나, 이후 Apache를 재시작하지 않았기 때문입니다. Step 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이나 비밀번호는 필요하지 않습니다. 이 메시지는 설치 오류가 아니라 socket 인증이 정상적으로 작동하고 있음을 나타내는 예상된 동작입니다.

올바른 비밀번호를 입력했음에도 애플리케이션에서 ERROR 1045 (28000): Access denied for user 'appuser'@'127.0.0.1' 발생. 계정은 'appuser'@'localhost'으로 존재하지만, 애플리케이션이 호스트 이름 해석이 비활성화된(skip-name-resolve) 서버의 127.0.0.1로 TCP 연결을 시도하고 있습니다. 이로 인해 MariaDB는 두 연결을 서로 다른 호스트로 인식합니다. localhost은 Unix socket이고 127.0.0.1은 TCP입니다. 애플리케이션이 socket을 사용하여 계정과 일치하도록 host 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 socket이 설치되지 않은 PHP 버전을 가리키는 경우(예: 8.3만 실행 중인데 업그레이드 후 php8.4 socket을 사용하는 경우)입니다. 둘째, DocumentRoot와 실제 디렉토리가 일치하지 않아 파일이 존재하지 않는 경우입니다. ls -l /run/php/으로 socket 존재 여부를 확인하고, DocumentRoot이 파일 위치와 일치하는지 확인한 후 php8.3-fpmapache2을 모두 재시작하십시오.

재시작할 때마다 AH00558: apache2: Could not reliably determine the server's fully qualified domain name 발생. 이는 오류가 아닌 무해한 경고입니다. Apache가 전역 ServerName이 설정되지 않았음을 알리는 것입니다. /etc/apache2/conf-available/servername.confServerName your.domain을 작성하고 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를 별도의 독립적인 튜닝 가능한 풀(pool)로 실행합니다. Apache는 소켓을 통해 PHP에 접속하며, 더 빠른 threaded event MPM과 함께 작동합니다. 또한 나중에 nginx로 전환할 때도 그대로 사용할 수 있습니다. PHP-FPM은 현대적인 기본 설정입니다. mod_php은 프로세스 내부 동작에 의존하는 레거시 앱에만 의미가 있습니다.

브라우저가 PHP 파일을 실행하는 대신 다운로드합니다.

PHP 핸들러가 연결되지 않았기 때문에 Apache가 .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 레코드를 서버로 지정한 뒤 sudo certbot --apache을 실행하십시오. Apache 인증 도구가 실행 중인 Apache를 통해 도메인 제어권을 증명하며, 설치 프로그램이 443 포트에 맞춰 virtual host를 재작성하고 자동 갱신을 설정합니다. Certbot 및 Apache 전체 가이드에서 인증 과정, 갱신 타이머, 일반적인 오류 유형을 확인할 수 있습니다.

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