Moodle을 CentOS 7, Nginx, PHP-FPM 7.0, MariaDB로 설치하는 단계별 가이드

Important: 예시 비밀번호(hakaselabs123)는 반드시 실제 운영 시 더 안전한 값으로 변경하세요.
이 문서는 Moodle(모듈형 객체 지향 동적 학습 환경)을 CentOS 7에 설치하여 Nginx, PHP-FPM 7.0, MariaDB와 함께 안전하게 운영하는 절차를 자세히 다룹니다. 원본은 Moodle 3.2 기반 예시이지만, 개념과 절차는 다른 안정판에도 적용할 수 있습니다.
목표: Moodle을 HTTPS로 제공하고, SELinux/Firewalld 권한을 적절히 설정하며, PHP-FPM을 UNIX 소켓으로 구성하여 성능과 보안을 고려한 운영 환경을 만드는 것입니다.
핵심 용어 1줄 정의:
- Moodle: 교육용 오픈소스 LMS(학습 관리 시스템).
- PHP-FPM: PHP FastCGI Process Manager, PHP를 프로세스로 관리해 웹서버와 통신.
- MariaDB: MySQL 호환 관계형 데이터베이스.
주요 체크포인트
- OS: CentOS 7
- 웹서버: Nginx
- PHP: PHP-FPM 7.0
- DB: MariaDB
- Moodle 버전: MOODLE_32_STABLE(예시)
사전 준비
- CentOS 7이 설치된 서버(물리 또는 가상머신)
- 루트 권한 또는 sudo 권한 계정
- 공인 도메인(운영 환경) 또는 테스트용 로컬 호스트
- 방화벽/SELinux 기본 이해
중요: 아래 예시 명령은 루트 권한으로 실행하거나 sudo를 사용해야 합니다.
수행할 작업 요약
- Nginx 설치
- PHP-FPM 7.0 설치 및 구성
- MariaDB 설치 및 Moodle DB 준비
- Moodle 다운로드 및 파일 권한 설정
- SSL 인증서 생성 및 Nginx 가상 호스트 구성
- SELinux와 Firewalld 설정
- 웹 설치(브라우저를 통한 설정)
- 테스트 및 운영 점검
1단계 Nginx 설치
CentOS 기본 리포지터리에는 Nginx가 포함되지 않으므로 EPEL 저장소를 추가합니다.
yum -y install epel-release
EPEL 추가 후 Nginx 설치:
yum -y install nginx
설치 후 Nginx 시작 및 부팅 시 자동 시작 등록:
systemctl start nginx
systemctl enable nginx
Nginx가 포트 80에서 동작하는지 확인하려면 netstat로 포트 상태를 확인합니다.
netstat -plntu
참고: netstat이 없다면 net-tools를 설치하세요.
yum -y install net-tools
설치/서비스 상태 확인 팁:
- systemctl status nginx
- ss -ltnp | grep nginx
2단계 PHP-FPM 설치 및 구성
Moodle 3.2는 PHP 7을 지원하므로 PHP 7.0을 사용합니다. CentOS 기본 저장소에는 PHP 7.0이 없기 때문에 webtatic 같은 서드파티 리포지터리를 추가합니다.
webtatic 리포지터리 추가:
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
필요한 PHP 및 확장들 설치(예제):
yum install -y graphviz aspell php70w-fpm php70w-cli php70w-pspell php70w-curl php70w-gd php70w-intl php70w-mysql php70w-xml php70w-xmlrpc php70w-ldap php70w-zip php70w-json php70w-opcache php70w-readline php70w-mbstring php70w-soap
php.ini 설정(경로: /etc/php.ini): cgi.fix_pathinfo 주석 해제 및 0으로 변경
vim /etc/php.ini
# 변경
cgi.fix_pathinfo=0
PHP-FPM 풀 설정(예: /etc/php-fpm.d/www.conf):
- user와 group을 nginx로 설정
- listen을 UNIX 소켓으로 설정
- 소켓 권한/소유자 설정
- PHP가 처리할 확장 제한
- 필요한 환경변수 활성화
핵심 예시 변경사항:
# /etc/php-fpm.d/www.conf
user = nginx
group = nginx
listen = /run/php-fpm/php-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
security.limit_extensions = .php
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
세션 디렉터리 생성 및 권한 적용:
mkdir -p /var/lib/php/session/
chown -R nginx:nginx /var/lib/php/session/
chown -R nginx:nginx /run/php-fpm/
PHP-FPM 시작 및 부팅 등록:
systemctl start php-fpm
systemctl enable php-fpm
소켓이 제대로 생성되었는지 확인:
netstat -lx | grep php-fpm.sock
운영 팁:
- PHP-FPM 풀 설정에는 메모리 제한, pm.max_children, pm.start_servers 등 성능 관련 설정을 향후 튜닝해야 합니다.
- PHP 확장 설치 여부는 Moodle의 시스템 요구사항 페이지와 설치 화면의 체크리스트를 기준으로 확인합니다.
3단계 MariaDB 설치 및 Moodle용 데이터베이스 준비
MariaDB 설치:
yum -y install mariadb-server mariadb
my.cnf에 InnoDB 관련 권장 설정 추가(파일 끝의 [mysqld] 섹션):
default_storage_engine = innodb
innodb_file_per_table = 1
innodb_file_format = Barracuda
MariaDB 시작 및 자동 시작 등록:
systemctl start mariadb
systemctl enable mariadb
보안 설정(루트 비밀번호 설정 등):
mysql_secure_installation
설치 마법사를 통해 익명 사용자 제거, 루트 원격 로그인 금지, 테스트 데이터베이스 제거 등을 진행하세요.
Moodle용 DB 및 사용자 생성 예시(운영에서는 강력한 암호 사용):
mysql -u root -p
# MySQL 프롬프트에서
CREATE DATABASE moodledb DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
CREATE USER 'moodleuser'@'localhost' IDENTIFIED BY 'hakaselabs123';
GRANT ALL PRIVILEGES ON moodledb.* TO 'moodleuser'@'localhost' IDENTIFIED BY 'hakaselabs123';
FLUSH PRIVILEGES;
보안 권고:
- 운영 환경에서는 DB 접속 계정을 최소 권한 원칙으로 설정하세요.
- 데이터베이스 비밀번호는 충분히 복잡하고 주기적으로 교체합니다.
4단계 Moodle 다운로드 및 파일 권한 설정
git 설치:
yum -y install git
웹 루트 디렉터리 생성 및 Moodle 클론:
mkdir -p /var/www/
cd /var/www/
git clone https://github.com/moodle/moodle.git
Moodle 저장소에서 안정 브랜치 선택(예시: MOODLE_32_STABLE):
cd moodle/
git branch -a
# 최신 안정 브랜치 확인 후
git branch --track MOODLE_32_STABLE origin/MOODLE_32_STABLE
git checkout MOODLE_32_STABLE
git status
moodledata 디렉터리 생성 및 권한 설정(웹에서 쓰기 가능하도록 설정):
mkdir -p /var/moodledata
chown -R nginx:nginx /var/moodledata
chmod 0777 /var/moodledata
웹 루트의 소유자 변경:
chown -R nginx:nginx /var/www/moodle
chmod 0755 /var/www/moodle
보안 메모:
- /var/moodledata는 웹루트(/var/www/moodle) 밖에 위치하여 웹서버를 통해 직접 접근되지 않도록 해야 합니다.
- 운영 환경에서는 moodledata 권한을 0777로 두기보다 필요한 최소 권한(예: 0750 + nginx 소유)을 고려하세요.
5단계 SSL 및 Nginx 가상 호스트 설정
운영 서버라면 Let’s Encrypt 같은 CA에서 발급받은 인증서를 사용하세요. 로컬 테스트용으로는 자체 서명(자체 CA) 인증서를 생성할 수 있습니다.
mkdir -p /etc/nginx/ssl/
openssl req -new -x509 -days 365 -nodes -out /etc/nginx/ssl/moodle.crt -keyout /etc/nginx/ssl/moodle.key
chmod 600 /etc/nginx/ssl/moodle.key
Nginx 설정 파일 예시(/etc/nginx/conf.d/moodle.conf):
# PHP Upstream Handler
upstream php-handler {
server unix:/run/php-fpm/php-fpm.sock;
}
# Nginx redirect HTTP to HTTPS - moodle.hakase-labs.com
server {
listen 80;
server_name moodle.hakase-labs.com;
# enforce https
return 301 https://$server_name$request_uri;
}
# HTTPS Configuration
server {
server_name moodle.hakase-labs.com;
listen *:443 ssl http2;
listen [::]:443 ssl http2;
# SSL Configuration
ssl on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-SHA128:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_session_tickets off;
resolver_timeout 5s;
ssl_certificate /etc/nginx/ssl/moodle.crt;
ssl_certificate_key /etc/nginx/ssl/moodle.key;
# Root Moodle Data Directory
root /var/www/moodle;
rewrite ^/(.*\.php)(/)(.*)$ /$1?file=/$3 last;
location ^~ / {
try_files $uri $uri/ /index.php?q=$request_uri;
index index.php index.html index.htm;
location ~ \.php$ {
include fastcgi.conf;
fastcgi_pass php-handler;
}
}
}
구성 테스트 및 Nginx 재시작:
nginx -t
systemctl restart nginx
운영 권장 사항:
- SSL 프로토콜 및 암호화 설정은 시기별로 검토하고 최신 가이드(OWASP, Mozilla SSL 설정)를 따르세요.
- HTTP → HTTPS 리다이렉트 외에도 HSTS, X-Frame-Options, Content-Security-Policy를 필요에 맞게 적용하세요.
6단계 SELinux와 Firewalld 구성
SELinux 상태 확인:
sestatus
SELinux가 활성(Enforcing)이라면 웹 루트와 moodledata에 적절한 컨텍스트를 설정해야 합니다.
policycoreutils-python 설치:
yum -y install policycoreutils-python
파일 컨텍스트 설정 및 복원:
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/moodle(/.*)?'
restorecon -Rv '/var/www/moodle/'
semanage fcontext -a -t httpd_sys_rw_content_t '/var/moodledata(/.*)?'
restorecon -Rv '/var/moodledata/'
Firewalld 설치 및 포트 허용:
yum -y install firewalld
systemctl start firewalld
systemctl enable firewalld
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-service=ssh
firewall-cmd --reload
firewall-cmd --list-all
참고: 데이터베이스가 원격에 있고 포트를 열어야 하는 경우 DB 포트(예: 3306)는 엄격하게 접근 제어를 적용하세요.
7단계 웹 브라우저를 통한 Moodle 설치
이 시점에서 브라우저에서 https://moodle.hakase-labs.com 으로 접속하면 설치 마법사가 시작됩니다.
설치 단계 요약:
- 언어 선택
- Moodle 웹 주소와 웹루트, moodledata 경로 입력
- 데이터베이스 유형(MySQL/MariaDB) 선택 및 연결 정보 입력
- 라이선스 동의
- 시스템 요구사항 검사: PHP 확장 등 확인
- 설치 완료 후 관리자 계정 생성 및 사이트 기본 설정
설치 시 화면 예시(원본 이미지 참조):
데이터베이스 정보 예시 입력값:
- 호스트: localhost
- DB 이름: moodledb
- DB 사용자: moodleuser
- DB 비밀번호: hakaselabs123
- 테이블 접두사: moodle_
- 포트: 3306
- 유닉스 소켓: /var/lib/mysql/mysql.sock
설치 완료 후 관리자 계정 및 사이트 기본 설정을 완료하면 대시보드로 리디렉션됩니다.
8단계 테스트 및 검증
기본 확인 목록:
- 사이트 접속: https://moodle.hakase-labs.com
- 로그인 페이지: https://moodle.hakase-labs.com/login/
- 관리자 대시보드에서 플러그인/확장상태 확인
스크린샷 예시:
운영 검증 권장 항목:
- Moodle 설치 후 시스템 관리자 > 알림에서 추가 요구사항 확인
- cron 작업 설정: Moodle의 예약 작업이 정확히 실행되도록 시스템 cron(또는 웹 cron)을 설정하세요.
- 백업 테스트: 코스 백업 및 복원 절차를 확인하세요.
문제 해결 체크리스트
502 Bad Gateway 오류
- PHP-FPM 프로세스가 실행 중인지 확인: systemctl status php-fpm
- php-fpm 소켓 권한 및 소유자 확인: ls -l /run/php-fpm/php-fpm.sock
- Nginx fastcgi_pass가 php-fpm과 같은 소켓/포트를 참조하는지 확인
데이터베이스 연결 오류
- MySQL 명령줄에서 DB 접속 테스트: mysql -u moodleuser -p -D moodledb
- 사용자 권한과 호스트(‘localhost’) 설정 확인
파일 업로드/이미지 표시 문제
- moodledata 디렉터리 권한 및 SELinux 컨텍스트(httpd_sys_rw_content_t) 확인
PHP 확장 미설치 문제
- 설치 화면의 요구사항 목록에 부족한 확장이 표시됩니다. yum으로 해당 확장 설치 후 php-fpm 재시작
느린 응답
- Nginx/Gzip, PHP-FPM 오프셋, DB 인덱스, 캐시(opcache) 설정 확인
보안 강화 권장 사항
- 인증서: 운영 환경에서는 Let’s Encrypt 또는 상용 CA에서 발급받은 인증서 사용
- SSL/TLS: TLS 1.2 이상만 허용하도록 조정(예시 설정은 필요에 따라 최신화)
- HSTS: HSTS 헤더 적용 시 서브도메인 및 preload 고려
- 권한 최소화: 웹 파일 소유자와 권한 최소화로 공격 표면 축소
- 관리자 접근 제한: 관리자 페이지 접근을 IP 제한 또는 2단계 인증 적용
- 패치 관리: OS, Nginx, PHP, Moodle, 플러그인 패치 정책 수립
보안 점검 우선순위:
- 인증서와 TLS 설정
- DB 계정 최소 권한 적용
- 파일 권한 및 SELinux 정책 적용
- 관리자 계정 보안(강력한 비밀번호, 2FA)
운영 체크리스트(역할별)
시스템 관리자
- 서비스 상태 확인(Nginx, php-fpm, mariadb)
- 자동 백업 및 로그 로테이션 구성
- 보안 패치 적용
Moodle 관리자
- 플러그인 업데이트 및 호환성 확인
- 정기적인 코스 백업
- 역할 및 권한 설정 검토
강사
- 코스 생성 및 리소스 업로드
- 학생 접근 권한 검토
학생
- 계정 로그인 확인
- 수강 신청 및 콘텐츠 접근 테스트
백업 및 장애 조치(간단 SOP)
- 데이터베이스 백업
mysqldump -u root -p moodledb > /root/backup/moodledb-$(date +%F).sql
- Moodle 코드 및 moodledata 백업
rsync -a /var/www/moodle /root/backup/www-moodle-$(date +%F)
rsync -a /var/moodledata /root/backup/moodledata-$(date +%F)
- 장애 발생 시 롤백 순서
- 서비스 중지: systemctl stop nginx php-fpm
- 데이터베이스 복원
- 파일 복원
- SELinux 컨텍스트 확인
- 서비스 재시작 및 로그 확인
마이그레이션 및 버전 업그레이드 팁
- Moodle 버전 업데이트 시 반드시 플러그인 호환성을 먼저 확인하세요.
- 백업 없이 메이저 업그레이드를 수행하지 마세요.
- 테스트 환경에서 업그레이드 시나리오를 사전 검증(스냅샷/스테이징)
호환성 체크리스트:
- PHP 최소 버전 확인
- MariaDB/MySQL 버전 호환성 확인
- 사용 중인 플러그인 버전 확인
요약
이 가이드는 CentOS 7 환경에 Nginx, PHP-FPM 7.0, MariaDB를 조합해 Moodle 3.2 안정판을 설치하고 HTTPS 및 SELinux/Firewalld를 설정하는 전체 워크플로우를 제공합니다. 각 단계에서는 권한 설정, 소켓 기반 통신, SSL 구성, SELinux 컨텍스트 및 방화벽 규칙 적용 등 운영 환경에서 놓치기 쉬운 부분을 다루었습니다.
주요 권장 사항:
- 비밀번호 및 인증서 등 민감 정보는 운영 환경에서 반드시 교체
- SELinux를 사용한다면 파일 컨텍스트를 적절히 설정
- 정기적인 백업과 테스트 환경에서의 업그레이드 시나리오 검증
문제 해결 예시와 추가 자료
- 502 오류: php-fpm 로그(/var/log/php-fpm/error.log)와 Nginx 에러 로그(/var/log/nginx/error.log) 확인
- DB 연결 실패: /var/lib/mysql/mysql.sock 권한 확인, MySQL 사용자 호스트 값(‘localhost’ vs ‘%’) 확인
참고 문서:
자주 묻는 질문
Q1: Moodle을 다른 웹서버(Apache) 대신 Nginx를 쓰는 이유는 무엇인가요?
A1: Nginx는 정적 파일 처리와 리버스 프록시에서 높은 효율성을 보이며 낮은 메모리 소비로 다수의 동시 연결을 처리하는 데 유리합니다. Apache 대신 채택하는 경우가 많습니다.
Q2: moodledata를 웹루트 밖에 두어야 하나요?
A2: 예, 보안을 위해 moodledata는 웹서버가 직접 노출되는 루트 밖에 두는 것이 권장됩니다.
Q3: PHP-FPM을 TCP 포트 대신 UNIX 소켓으로 구성해도 되나요?
A3: 예, 동일 서버에서 PHP-FPM과 Nginx가 동작할 경우 UNIX 소켓이 더 빠르고 보안상 유리할 수 있습니다.
참고 이미지 출처는 설치 과정의 스크린샷이며, 경로는 문서에 포함된 대로 유지합니다.