우분투 LEMP 워드프레스 설치 – Ubuntu 24.04
우분투(Ubuntu 24.04)에서 LEMP 스택(Linux, Nginx, MariaDB, PHP)은 웹 애플리케이션을 구동하기 위한 강력한 도구입니다. 이 가이드는 Ubuntu 24.04에서 LEMP 스택을 설치하고, 워드프레스를 설정하는 방법을 단계별로 설명합니다.
우분투(Ubuntu 24.04) 업데이트 및 기본 설정
우선, 모든 패키지를 최신 상태로 업데이트합니다. 이 단계는 보안을 강화하고 호환성을 보장하는 데 필수적입니다.
sudo apt-get update && sudo apt-get upgrade -y
1. root 권한 활성화 및 설정
root 계정 비밀번호가 설정되어 있지 않은 경우 다음과 같이 설정합니다.
sudo passwd root
이후 단계를 편의상 root 권한으로 수행하였습니다. 필요하지 않은 경우 sudo 명령어를 이용하여 진행해도 무방합니다.
su -
저는 dev 사용자을 이용하여 다음 프로세스를 진행하였으니 참조하여 사용자(dev)를 변경하여 진행하시면 됩니다.
sudo 사용 시 비밀번호를 묻지 않도록 다음과 같이 설정 가능합니다.
USERID="dev"
chmod 700 /etc/sudoers && \
echo "${USERID} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
chmod 440 /etc/sudoers
2. 시간대 설정
서버의 시간을 한국 시간으로 설정합니다.
sudo timedatectl set-timezone Asia/Seoul
Nginx 설치 및 설정
1. Nginx 설치
최신 버전의 Nginx를 설치하기 위해 저장소를 추가하고, 설치 후 Nginx를 시작합니다.
sudo add-apt-repository ppa:ondrej/nginx-mainline
sudo apt-get install nginx -y
sudo service nginx start
2. Nginx 버전 확인
설치된 Nginx의 버전을 확인합니다:
nginx -v

웹 브라우저에서 서버의 IP를 입력하고 Nginx 환영 페이지가 뜨는지 확인합니다.

해당 문구의 텍스트 페이지가 나타난다면 Nginx는 문제없이 잘 설치된 상태입니다.
만약 정적인(static) 페이지의 웹 사이트를 운영할 생각이라면 이 상태로 바로 서버를 운영해도 전혀 문제가 없는 상태입니다.
저장경로(/var/www/html)에서 웹사이트를 업로드하고 바로 이용을 하실 수 있습니다.
PHP-FPM 8.3 설치
1. PHP-FPM 설치
최신 PHP 버전을 사용하기 위해 PHP 저장소를 추가하고 PHP-FPM과 필요한 모듈을 설치합니다.
sudo add-apt-repository ppa:ondrej/php
sudo apt-get install php8.3-fpm php8.3-mysql php8.3-xml php8.3-mbstring php8.3-zip php8.3-curl -y
sudo service php8.3-fpm start
2. PHP-FPM 시작
PHP-FPM 서비스를 시작하고 상태를 확인합니다:
sudo service php8.3-fpm start
php -v

3. Composer 설치
Composer는 PHP용 의존성 관리 도구로, 프로젝트에서 필요한 외부 라이브러리나 패키지를 쉽게 관리하고 설치할 수 있도록 도와줍니다.
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
php composer-setup.php --filename=composer --install-dir=/usr/local/bin && \
php -r "unlink('composer-setup.php');"
MariaDB 10.11 설치
1. MariaDB 설치
MariaDB는 데이터베이스 서버로, 다음 명령어를 통해 설치합니다.
DBROOTPASS="DB root 패스워드"
PHPVERSION="8.3"
MARIADBVERSION="10.11"
debconf-set-selections <<< "mariadb-server-${MARIADBVERSION} mysql-server/root_password password ${DBROOTPASS}"
debconf-set-selections <<< "mariadb-server-${MARIADBVERSION} mysql-server/root_password_again password ${DBROOTPASS}"
apt-get -y install mariadb-server mariadb-client && \
apt-get -y install php$PHPVERSION-mysql && \
service mariadb start
정상적으로 설치가 되었는지 확인합니다.
service mariadb status

2. MariaDB 언어셋 및 기본 설정
최근엔 모바일에서 사용하는 이모지(emoji)등에 대응하기 위해 utf8이 아닌 utf8mb4 언어셋으로 지정하여 mariadb.cnf 파일을 생성합니다.
echo "[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
skip-name-resolve
skip-external-locking
## MariaDB 스케줄러
event-scheduler = OFF
sysdate-is-now
back_log = 100
max_connections = 300
max_connect_errors = 999999
# max_connections에 비례해서 사용
thread_cache_size = 50
table_open_cache = 400
wait_timeout = 6000
max_allowed_packet = 32M
max_heap_table_size = 32M
tmp_table_size = 512K
sort_buffer_size = 128K
join_buffer_size = 128K
read_buffer_size = 128K
read_rnd_buffer_size = 128K
query_cache_type = 1
query_cache_size = 32M
query_cache_limit = 2M
group_concat_max_len = 1024
## 마스터 MariaDB 서버에서 레코드 기반 복제를 사용할 때는 READ-COMMITTED 사용 가능
## 복제에 참여하지 않는 MariaDB 서버에서는 READ-COMMITTED 사용 가능
## 그 외에는 반드시 REPEATABLE-READ 로 사용
transaction-isolation = REPEATABLE-READ
## InnoDB 기본 옵션
## InnoDB를 사용하지 않는다면 innodb_buffer_pool_size를 최소화하거나
## InnoDB 스토리지 엔젠을 기동하지 않도록 설정
innodb_buffer_pool_size = 1G
## MyISAM 옵션
## InnoDB를 사용하지 않고 MyISAM만 사용한다면 key_buffer_size를 4GB까지 설정
key_buffer_size = 32M
## 로깅 옵션
slow-query-log = 1
long_query_time = 1
## 복제 옵션
binlog_cache_size = 128K
max_binlog_size = 512M
expire_logs_days = 14
log-bin-trust-function-creators = 1
sync_binlog = 1
lower_case_table_names = 1
query_cache_min_res_unit = 2k
sql_mode = NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
[mysqldump]
default-character-set=utf8mb4
max_allowed_packet = 32M
" > /etc/mysql/conf.d/mariadb.cnf
설정된 내용 적용을 위해 MariaDB 서비스를 재시작 합니다.
service mariadb restart
Redis 캐시서버 설치
PHP에서 세션을 처리할 때, 기본적으로 하드디스크 파일을 사용하지만, 성능 향상을 위해 메모리 기반 캐시를 활용하는 것이 더욱 효율적입니다.
이를 위해 대표적으로 사용되는 기술이 Redis로, 빠른 데이터 접근이 필요한 세션 저장소로 적합하며 캐시 서버로서도 뛰어난 성능을 발휘합니다.
1. Redis 서버 및 PHP-Redis 연동 설치
PHPVERSION="8.3"
apt-get -y install redis-server && \
apt-get -y install php$PHPVERSION-redis && \
service redis-server start
핑퐁 테스트를 실행해서 redis에 정상적으로 접속이 되는지 확인합니다.

이후 PHP 설정에서 세션 핸들러를 파일이 아닌 Redis 서버로 설정할 것입니다.
Nginx와 PHP 연동
1. Nginx 설정 파일 수정
Nginx는 PHP를 자체적으로 처리하지 않으므로 PHP-FPM과 연동해야 합니다. Nginx 설정 파일을 수정하여 PHP 파일을 처리하도록 구성합니다.
USERID="dev"
BASE="/home/${USERID}"
CONF_NGINX="${BASE}/conf/nginx"
EXPIRES="7d"
mkdir -p $CONF_NGINX/conf.d
nginx.conf 파일은 Nginx 서버의 사용자, 프로세스, 이벤트, HTTP 설정 등을 정의하여 웹 서버의 전반적인 동작과 성능을 제어하는 기본 설정 파일입니다.
echo "user ${USERID};
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;
events {
multi_accept on;
worker_connections 65535;
}
http {
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
log_not_found off;
types_hash_max_size 2048;
client_max_body_size 32M;
# MIME
include mime.types;
default_type application/octet-stream;
# logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
# load configs
include ${CONF_NGINX}/conf.d/*.conf;
}
" > /etc/nginx/nginx.conf
security.conf 파일은 Nginx 서버에 보안 헤더를 추가하여 웹 애플리케이션을 클릭재킹, XSS, MIME 타입 스니핑, 정보 누출 등 다양한 보안 위협으로부터 보호하기 위한 설정을 담고 있습니다.
echo "# security headers
add_header X-Frame-Options \"SAMEORIGIN\" always;
add_header X-XSS-Protection \"1; mode=block\" always;
add_header X-Content-Type-Options \"nosniff\" always;
add_header Referrer-Policy \"no-referrer-when-downgrade\" always;
add_header Content-Security-Policy \"default-src 'self' http: https: data: blob: 'unsafe-inline' 'unsafe-eval'\" always;
" > $CONF_NGINX/security.conf
general.conf 파일은 Nginx 서버에서 정적 파일 캐싱, 로그 설정, gzip 압축 등을 관리하여 웹사이트의 성능 최적화와 리소스 처리 방식을 정의하는 설정 파일입니다.
echo "# favicon.ico
location = /favicon.ico {
log_not_found off;
access_log off;
}
# robots.txt
location = /robots.txt {
log_not_found off;
access_log off;
}
# assets, media
location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
expires ${EXPIRES};
access_log off;
}
# svg, fonts
location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
add_header Access-Control-Allow-Origin \"*\";
expires ${EXPIRES};
access_log off;
}
# gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
" > $CONF_NGINX/general.conf
php_fastcgi.conf 파일은 Nginx 서버에서 PHP FastCGI 프로세스와의 연결을 설정하고, PHP 요청 처리 시 버퍼, 경로, 보안 설정 등을 정의하는 구성 파일입니다.
echo "# 404
try_files \$fastcgi_script_name =404;
# default fastcgi_params
include fastcgi_params;
# fastcgi settings
fastcgi_pass unix:/var/run/php/${USERID}.sock;
fastcgi_index index.php;
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
# fastcgi params
fastcgi_param DOCUMENT_ROOT \$realpath_root;
fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name;
fastcgi_param PHP_ADMIN_VALUE \"open_basedir=\$base/:/usr/lib/php/:/tmp/\";
" > $CONF_NGINX/php_fastcgi.conf
proxy.conf 파일은 Nginx 서버에서 프록시 요청 처리를 위한 헤더 설정과 HTTP 버전, 업그레이드 연결 등을 정의하여 클라이언트와 백엔드 서버 간의 원활한 통신을 관리하는 구성 파일입니다.
echo "proxy_http_version 1.1;
proxy_cache_bypass \$http_upgrade;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection \"upgrade\";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Forwarded-Host \$host;
proxy_set_header X-Forwarded-Port \$server_port;
" > $CONF_NGINX/proxy.conf
wordpress.conf 파일은 Nginx 서버에서 워드프레스 사이트를 구동하기 위한 기본 설정을 정의하며, 포트 리스닝, 루트 디렉터리, 보안 및 로깅 설정, PHP 처리, 그리고 정적 파일 처리 규칙 등을 포함한 서버 구성을 담당하는 파일입니다.
echo "server {
listen 80;
listen [::]:80;
server_name _;
set \$base ${BASE};
root \$base/wordpress;
# security
include ${CONF_NGINX}/security.conf;
# logging
access_log /var/log/nginx/wordpress.access.log;
error_log /var/log/nginx/wordpress.error.log warn;
# index.php
index index.php;
# index.php fallback
location / {
try_files \$uri \$uri/ /index.php?\$query_string;
}
# handle .php
location ~ \.php$ {
include ${CONF_NGINX}/php_fastcgi.conf;
}
include ${CONF_NGINX}/general.conf;
}
" > $CONF_NGINX/conf.d/wordpress.conf
설치 과정 이후 사용자별로 서비스를 운영 예정이므로 Nginx 설정 파일들의 권한을 해당 사용자로 변경합니다.
chown -R $USERID:$USERID /home/$USERID/conf
변경 사항을 적용하려면 Nginx를 재시작합니다:
sudo service nginx restart
사용자별 계정 추가 및 설정
도메인에 따른 여러 사이트를 운영하기 위해 다음과 같이 설정을 진행합니다.
1. 사용자 PHP 설정
이제 공통의 php.ini 설정이 아닌 사용자별 PHP를 설정해줍니다.
USERID="dev"
TIMEZONE="Asia/Seoul"
PHPVERSION="8.3"
echo "[${USERID}]
user = ${USERID}
group = ${USERID}
listen = /run/php/${USERID}.sock
listen.owner = ${USERID}
listen.group = www-data
pm = dynamic
pm.max_children = 9
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200
php_admin_value[date.timezone] = ${TIMEZONE}
php_admin_value[realpath_cache_size] = 64k
php_admin_value[expose_php] = Off
php_admin_value[opcache.revalidate_freq] = 1 ;0:개발, 1:라이브수정, 2:최적성능
php_admin_value[opcache.validate_timestamps] = 1
php_admin_value[opcache.interned_strings_buffer] = 16
php_admin_value[max_execution_time] = 60
php_admin_value[max_input_time] = 60
php_admin_value[post_max_size] = 30M
php_admin_value[upload_max_filesize] = 20M
php_admin_value[session.save_handler] = 'redis'
php_admin_value[session.save_path] = 'tcp://127.0.0.1:6379'
" > /etc/php/$PHPVERSION/fpm/pool.d/$USERID.conf
PHP 서비스 재시작합니다.
service php$PHPVERSION-fpm restart
2. 사용자 데이터베이스 생성
DB root 패스워드, User ID, User 패스워드, DBName을 입력하고 다음과 같이 설정합니다.
DBROOTPASS="DB root 패스워드"
USERID="User ID"
USERPW="User 패스워드"
DBNAME="DBName"
mysql -uroot -p$DBROOTPASS -e "CREATE DATABASE ${DBNAME}
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;"
mysql -uroot -p$DBROOTPASS -e "CREATE USER '${USERID}'@'%' IDENTIFIED BY '${USERPW}'"
mysql -uroot -p$DBROOTPASS -e "GRANT USAGE ON *.* TO '${USERID}'@'%' REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0"
mysql -uroot -p$DBROOTPASS -e "GRANT ALL PRIVILEGES ON ${DBNAME}.* TO '${USERID}'@'%'"
3. 데이터베이스 원격접속 허용
개발 시 DB Tool을 통해 접속하기 위해서 원격접속 설정이 필요합니다.
DBROOTPASS="DB root 패스워드"
mysql -uroot -p$DBROOTPASS -e "CREATE USER 'root'@'%' IDENTIFIED BY '${DBROOTPASS}'"
mysql -uroot -p$DBROOTPASS -e "GRANT ALL PRIVILEGES ON *.* to 'root'@'%'"
mysql -uroot -p$DBROOTPASS -e "FLUSH PRIVILEGES"
sed -i 's/bind-address = 127.0.0.1/#bind-address = 127.0.0.1/' /etc/mysql/mariadb.conf.d/50-server.cnf
설정을 적용하기 위해 DB 서비스 재시작 합니다.
service mariadb restart
4. iptables 활성화 및 포트 허용
iptables 설치되어 있지 않는 경우 다음과 같이 설치합니다.
apt-get install iptables-persistent
MariaDB 기본 포트인 3306 포트를 허용하며, 재부팅 시 추가한 내역 사라지지 않도록 설정합니다.
# 3306 포트 인바운드 아웃바운드 허용
iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
# 재부팅 시 저장
netfilter-persistent save
netfilter-persistent reload
워드프레스 다운로드 및 설치
1. 워드프레스 다운로드
아래 링크를 통해 최신 워드프레스 버전을 다운로드 합니다.
워드프레스를 이용할 계정으로 전환합니다.
su - dev
2. 설치파일 업로드 및 압축 해제
저는 wordpress-6.6.2.zip 파일을 다운 받았으며 해당 파일을 사용자 홈 디렉토리에 업로드 합니다. (/home/dev)
unzip이 설치되지 않은 경우는 다음과 같이 설치합니다.
sudo apt-get -y install unzip
사용자 홈 디렉토리에 업로드한 파일을 압축해제 합니다.
unzip wordpress-6.6.2.zip
3. 브라우저에서 WordPress 설정
브라우저를 열고 서버의 IP 주소나 도메인으로 접속하여 WordPress 설치 마법사를 완료합니다. (예. http://192.168.0.2/wp-admin/install.php)

마무리
Ubuntu 24.04에서 LEMP 스택을 설치하고 워드프레스를 설정하는 과정에 대해 알아보았습니다. LEMP 스택은 웹 애플리케이션을 구동하기 위한 효율적이고 강력한 환경을 제공하며, 특히 Nginx와 PHP-FPM을 통해 높은 성능을 유지할 수 있습니다.
이 글을 통해 LEMP 스택 및 워드프레스 설치하고 관리하는 데 도움이 되기를 바랍니다.