안녕하세요. 비전 IDC 기술팀입니다.
APM은 웹 서버 Apache, 데이터베이스 MySQL, 서버 측 스크립트 언어 PHP를 함께 구성한 웹 서비스 환경을 말합니다. 워드프레스, 그누보드, 라라벨 기반 서비스 등 많은 PHP 웹 애플리케이션이 이 조합에서 동작합니다.
이 문서에서는 Ubuntu 22.04 / 24.04 서버에서 공식 저장소 패키지만으로 Apache2, MySQL, PHP를 설치하고, MySQL 기본 보안 설정과 애플리케이션용 데이터베이스 계정 생성, PHP 동작 확인, 기본적인 문제 해결 방법까지 순서대로 설명합니다. Ubuntu 20.04와 다른 부분은 해당 위치에 함께 표시했습니다.
적용 환경
- 운영체제: Ubuntu 22.04 LTS / 24.04 LTS (20.04 LTS 차이점 별도 표기)
- 웹 서버: Apache 2.4 (
apache2), 서비스명apache2 - 데이터베이스: MySQL 8.0 (
mysql-server), 서비스명mysql - PHP: 배포판 기본 버전 (20.04: 7.4, 22.04: 8.1, 24.04: 8.3), Apache 모듈 방식(
libapache2-mod-php) - 방화벽: UFW (활성화된 경우에만 설정)
1. 패키지 목록 갱신 및 시스템 업데이트
설치 전에 패키지 목록을 최신 상태로 갱신하고 설치된 패키지를 업데이트합니다.
sudo apt update
sudo apt upgrade -y
커널이나 주요 라이브러리가 업데이트되었다면 로그인 시 재부팅이 필요하다는 안내가 표시될 수 있습니다. 운영 중인 서비스가 없는 신규 서버라면 이 시점에 재부팅해 두는 것이 좋습니다.
[ -f /var/run/reboot-required ] && echo "재부팅 필요" || echo "재부팅 불필요"
운영체제 버전도 확인해 둡니다.
lsb_release -a
2. Apache2 설치
sudo apt install -y apache2
Ubuntu에서는 설치가 끝나면 Apache가 자동으로 시작됩니다. 서비스 상태를 확인하고 부팅 시 자동 실행되도록 설정합니다.
sudo systemctl enable --now apache2
systemctl status apache2
active (running)으로 표시되면 정상입니다. 서버 내부에서 응답을 확인합니다.
curl -I http://localhost
HTTP/1.1 200 OK가 표시되면 Apache가 동작 중입니다. 브라우저에서 http://서버IP로 접속하면 Apache2 Default Page(Ubuntu 기본 안내 페이지)가 표시됩니다.
| 구분 | 경로 |
|---|---|
| 기본 웹 문서 루트 | /var/www/html |
| 주 설정 파일 | /etc/apache2/apache2.conf |
| 가상 호스트 설정 | /etc/apache2/sites-available/ (활성화: a2ensite) |
| 모듈 설정 | /etc/apache2/mods-available/ (활성화: a2enmod) |
| 로그 | /var/log/apache2/access.log, /var/log/apache2/error.log |
3. UFW 방화벽 설정 (활성화된 경우)
먼저 UFW가 활성화되어 있는지 확인합니다.
sudo ufw status
Status: inactive로 표시된다면 UFW가 동작하지 않는 상태이므로 이 장은 건너뛰어도 됩니다. Status: active라면 Apache가 등록한 애플리케이션 프로필을 확인합니다.
sudo ufw app list
Apache: 80/tcp (HTTP)Apache Secure: 443/tcp (HTTPS)Apache Full: 80/tcp와 443/tcp
HTTP만 사용한다면 Apache를, 이후 SSL 인증서를 적용할 계획이라면 Apache Full을 허용합니다.
sudo ufw allow 'Apache'
sudo ufw status
4. MySQL 설치
sudo apt install -y mysql-server
설치가 끝나면 MySQL 서비스가 자동으로 시작됩니다. 상태와 버전을 확인합니다.
sudo systemctl enable --now mysql
systemctl status mysql
mysql --version
Ubuntu의 MySQL 패키지는 root 계정에 auth_socket 인증 방식을 사용합니다. 운영체제의 root 권한으로 실행하면 MySQL 비밀번호 없이 관리자로 접속되며, 일반 사용자가 mysql -u root -p로 비밀번호를 입력하는 방식으로는 root 로그인이 되지 않습니다.
sudo mysql
접속되면 mysql> 프롬프트가 표시됩니다. 현재 계정의 인증 방식을 확인한 뒤 종료합니다.
SELECT user, host, plugin FROM mysql.user;
EXIT;
5. mysql_secure_installation으로 기본 보안 설정
MySQL 설치 직후에는 보안 스크립트를 실행해 불필요한 기본 계정과 데이터베이스를 정리합니다.
sudo mysql_secure_installation
스크립트는 다음 순서로 질문합니다. 각 질문에는 y 또는 다른 키(n)로 응답합니다.
1) VALIDATE PASSWORD 컴포넌트 사용 여부
비밀번호 강도 검사 기능을 켤지 묻습니다. y를 선택하면 정책 수준을 숫자로 고릅니다.
| 수준 | 요구 조건 |
|---|---|
| 0 = LOW | 8자 이상 |
| 1 = MEDIUM | 8자 이상, 숫자·대소문자·특수문자 포함 |
| 2 = STRONG | MEDIUM 조건에 더해 사전 파일에 있는 단어 사용 제한 |
이 기능을 켜면 이후 CREATE USER로 계정을 만들 때도 선택한 정책이 적용됩니다. 운영 서버라면 MEDIUM(1) 이상을 권장합니다.
2) root 비밀번호 설정
Ubuntu 기본 구성처럼 root가 auth_socket 인증을 사용하는 경우, 스크립트가 root 비밀번호 설정을 건너뛰었다는 안내를 표시하고 다음 단계로 넘어갈 수 있습니다. 이는 정상 동작이며, root는 계속 sudo mysql로 접속합니다.
3) 익명 사용자 삭제 (Remove anonymous users?)
계정 이름 없이 접속할 수 있는 익명 계정을 삭제할지 묻습니다. y를 선택합니다.
4) root 원격 로그인 차단 (Disallow root login remotely?)
root 계정이 localhost 외의 위치에서 접속하지 못하도록 할지 묻습니다. y를 선택합니다. 원격 관리가 필요하다면 root 대신 권한을 제한한 별도 계정을 사용하십시오.
5) test 데이터베이스 삭제 (Remove test database and access to it?)
누구나 접근할 수 있도록 만들어진 테스트용 데이터베이스와 권한을 삭제할지 묻습니다. y를 선택합니다.
6) 권한 테이블 다시 불러오기 (Reload privilege tables now?)
지금까지의 변경 사항을 즉시 적용할지 묻습니다. y를 선택하면 All done! 메시지와 함께 스크립트가 종료됩니다.
6. 애플리케이션용 데이터베이스와 계정 생성
웹 애플리케이션에서는 MySQL root를 사용하지 말고, 해당 서비스의 데이터베이스에만 권한을 가진 전용 계정을 만듭니다. 아래 appdb, appuser, 비밀번호는 예시이므로 실제 값으로 바꿔 사용합니다.
sudo mysql
CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'Str0ng!Passw0rd-Example';
GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost';
SHOW GRANTS FOR 'appuser'@'localhost';
EXIT;
utf8mb4: 한글과 이모지를 포함한 모든 유니코드 문자를 저장할 수 있는 문자 집합입니다.'appuser'@'localhost': 같은 서버 내부에서만 접속할 수 있는 계정입니다.appdb.*: 권한 범위를appdb데이터베이스로 제한합니다.*.*처럼 전체 권한을 주지 않도록 주의합니다.
VALIDATE PASSWORD 정책을 켠 상태에서 약한 비밀번호를 사용하면 Your password does not satisfy the current policy requirements 오류가 발생합니다. 정책을 만족하는 길고 복잡한 비밀번호를 사용하십시오.
생성한 계정으로 접속되는지 확인합니다.
mysql -u appuser -p appdb
비밀번호 입력 후 mysql> 프롬프트가 표시되면 정상이며, EXIT;로 종료합니다.
7. PHP 설치
PHP 본체와 Apache 연동 모듈, MySQL 연결 확장을 설치합니다.
sudo apt install -y php libapache2-mod-php php-mysql
대부분의 PHP 애플리케이션에서 필요로 하는 확장 모듈도 함께 설치합니다.
sudo apt install -y php-cli php-curl php-mbstring php-xml php-zip
| 패키지 | 역할 |
|---|---|
php |
배포판 기본 버전의 PHP 메타 패키지 |
libapache2-mod-php |
Apache가 PHP 파일을 직접 처리하도록 하는 모듈 |
php-mysql |
mysqli, PDO MySQL 확장 (MySQL 연결) |
php-cli |
터미널에서 php 명령 실행 (크론 작업, Composer 등) |
php-curl |
외부 API 호출 등 HTTP 요청 |
php-mbstring |
한글 등 멀티바이트 문자열 처리 |
php-xml |
XML 처리 (DOM, SimpleXML 등) |
php-zip |
ZIP 압축 파일 처리 |
설치된 버전과 확장 모듈을 확인합니다.
php -v
php -m | grep -Ei 'mysqli|pdo_mysql|curl|mbstring|xml|zip'
Apache에 PHP 모듈이 적용되도록 재시작합니다.
sudo systemctl restart apache2
apache2ctl -M 2>/dev/null | grep -i php
php_module이 표시되면 Apache에서 PHP를 처리할 준비가 된 것입니다.
8. phpinfo 테스트 페이지로 동작 확인
웹 문서 루트에 PHP 정보 출력 파일을 만듭니다.
echo '<?php phpinfo();' | sudo tee /var/www/html/info.php > /dev/null
브라우저에서 http://서버IP/info.php로 접속하면 PHP 버전과 설정 정보가 표 형태로 표시됩니다. 다음 항목을 확인합니다.
- Server API:
Apache 2.0 Handler로 표시되면 Apache 모듈 방식으로 동작 중입니다. - Loaded Configuration File: 실제 적용 중인
php.ini경로 - mysqli, pdo_mysql 섹션: MySQL 연결 확장이 로드되었는지 여부
서버 내부에서 확인하려면 다음 명령을 사용할 수도 있습니다.
curl -s http://localhost/info.php | grep -o 'PHP Version [0-9.]*' | head -n 1
sudo rm -f /var/www/html/info.php
PHP와 MySQL 연결까지 한 번에 확인하고 싶다면 앞에서 만든 계정으로 접속을 시험할 수 있습니다. 확인 후에는 이 파일도 삭제합니다.
sudo tee /var/www/html/dbtest.php > /dev/null <<'EOF'
<?php
$conn = new mysqli('localhost', 'appuser', 'Str0ng!Passw0rd-Example', 'appdb');
if ($conn->connect_error) {
die('DB connection failed: ' . $conn->connect_error);
}
echo 'DB connection OK (MySQL ' . $conn->server_info . ')';
EOF
curl -s http://localhost/dbtest.php; echo
sudo rm -f /var/www/html/dbtest.php
9. 서비스 관리 명령 정리
| 작업 | Apache2 | MySQL |
|---|---|---|
| 상태 확인 | systemctl status apache2 |
systemctl status mysql |
| 시작 | sudo systemctl start apache2 |
sudo systemctl start mysql |
| 중지 | sudo systemctl stop apache2 |
sudo systemctl stop mysql |
| 재시작 | sudo systemctl restart apache2 |
sudo systemctl restart mysql |
| 설정 다시 읽기 | sudo systemctl reload apache2 |
설정 변경 시 재시작 |
| 부팅 시 자동 시작 | sudo systemctl enable apache2 |
sudo systemctl enable mysql |
Apache 설정을 변경했다면 재시작 전에 반드시 문법 검사를 먼저 실행합니다. 문법 오류가 있는 상태로 재시작하면 Apache가 시작되지 않아 웹사이트 전체가 중단됩니다.
sudo apache2ctl configtest && sudo systemctl reload apache2
10. 자주 발생하는 문제와 확인 방법
| 증상 | 가능한 원인 | 확인 및 해결 방향 |
|---|---|---|
| Apache가 시작되지 않음 | 설정 문법 오류 | sudo apache2ctl configtest로 오류 위치를 확인하고 sudo journalctl -u apache2 -n 50으로 로그를 확인합니다. |
로그에 Address already in use 또는 could not bind to address ... :80 |
Nginx 등 다른 프로그램이 80 포트 사용 중 | sudo ss -tlnp | grep ':80 '로 점유 프로세스를 확인하고, 사용하지 않는 서비스라면 중지 후 Apache를 시작합니다. |
AH00558: Could not reliably determine the server's fully qualified domain name |
전역 ServerName 미설정 |
경고이므로 동작에는 영향이 없습니다. 없애려면 apache2.conf 또는 가상 호스트에 ServerName을 지정합니다. |
| 브라우저에 PHP 코드가 그대로 표시되거나 파일이 다운로드됨 | Apache PHP 모듈 미적용 | apache2ctl -M | grep php로 확인하고, 없다면 libapache2-mod-php 설치 후 sudo a2enmod php8.3(설치된 버전에 맞게) 실행 뒤 Apache를 재시작합니다. |
| PHP 모듈 활성화 시 MPM 충돌 메시지 | mpm_event와 PHP 모듈 충돌 |
sudo a2dismod mpm_event, sudo a2enmod mpm_prefork 실행 후 PHP 모듈을 활성화하고 재시작합니다. |
mysql -u root -p로 Access denied |
root가 auth_socket 인증 사용 | sudo mysql로 접속합니다. |
| PHP에서 DB 연결 실패 | 계정·비밀번호·호스트 불일치 또는 MySQL 중지 | mysql -u appuser -p appdb로 직접 접속을 확인하고 systemctl status mysql을 점검합니다. |
외부에서 웹 접속 불가, 서버 내부 curl은 정상 |
UFW 또는 외부 방화벽 차단 | sudo ufw status에서 80/443 허용 여부와 서버 외부 방화벽 정책을 확인합니다. |
오류 원인을 확인할 때 주로 사용하는 로그는 다음과 같습니다.
sudo tail -n 50 /var/log/apache2/error.log
sudo journalctl -u apache2 -n 50 --no-pager
sudo tail -n 50 /var/log/mysql/error.log
해결되지 않으면 비전 IDC 1:1 문의(https://visionidc.com/submitticket.php) 또는 텔레그램 VISIONIDC24로 문의해 주시기 바랍니다.
11. 관련 기술자료와 공식 참고자료
관련 비전 IDC 기술자료
- Ubuntu 무차별 대입 공격에 대한 보안 설정 — 웹 서버 공개 후 SSH 보안 강화
- Ubuntu SSH 접속 포트 변경하는 방법
- 리눅스 서버 SSH 키 인증 로그인 설정 방법
- Ubuntu 22.04에서 메모리 사용량이 높은 프로세스를 확인하는 방법
공식 참고자료
12. 자주 묻는 질문
MySQL 대신 MariaDB를 사용해도 되나요?
가능합니다. Ubuntu 저장소의 mariadb-server 패키지를 설치하면 되며, php-mysql 확장으로 동일하게 연결할 수 있습니다. 다만 두 패키지는 함께 설치하지 말고 하나만 선택하십시오.
최신 PHP 버전을 사용하고 싶습니다.
이 문서는 Ubuntu 공식 저장소의 기본 PHP 버전을 기준으로 합니다. 배포판 기본 버전은 해당 Ubuntu 버전의 보안 업데이트를 함께 받을 수 있다는 장점이 있습니다. 다른 버전이 꼭 필요하다면 애플리케이션 요구 사항과 유지보수 방법을 먼저 검토하시기 바랍니다.
웹사이트 파일은 어디에 올리면 되나요?
기본 문서 루트는 /var/www/html입니다. 여러 도메인을 운영한다면 /var/www/도메인명처럼 디렉터리를 나누고 /etc/apache2/sites-available/에 가상 호스트 설정을 만든 뒤 a2ensite로 활성화하는 방식이 관리하기 좋습니다.
Ubuntu 20.04에서도 같은 방법으로 설치할 수 있나요?
명령은 동일하게 사용할 수 있으며, PHP 버전이 7.4로 설치되는 점이 주요 차이입니다. 모듈 이름(php7.4)과 설정 파일 경로(/etc/php/7.4/)를 버전에 맞게 바꿔 적용하십시오. 또한 Ubuntu 20.04는 표준 지원 기간이 종료되었으므로 신규 구축에는 22.04 또는 24.04 사용을 권장합니다.
마무리
이번 문서에서는 Ubuntu 22.04 / 24.04에서 Apache2, MySQL, PHP를 설치하고 mysql_secure_installation으로 기본 보안 설정을 적용한 뒤, 애플리케이션 전용 DB 계정 생성과 phpinfo 테스트로 동작을 확인하는 과정을 살펴봤습니다.
설치를 마친 뒤에는 테스트 파일 삭제, MySQL 외부 접속 차단 유지, 불필요한 포트 비공개, 정기적인 apt upgrade를 통해 기본 보안 상태를 유지하시기 바랍니다. 실제 서비스 도메인을 연결할 때는 가상 호스트와 HTTPS 설정도 함께 적용하는 것을 권장합니다.
