홈 서버 만들기 09. 웹사이트: php + MariaDB + WordPress

May 10, 2018

워드프레스는 전 세계에서 가장 널리 쓰이는 웹사이트 저작 툴이다. 앞선 글에서 Nginx 웹 서버를 설치하고 https 보안 연결을 설정했으니 워드프레스로 웹사이트를 만들고 싶다면 php와 데이터베이스 프로그램을 설치한 다음에 워드프레스를 설치하면 된다. 워드프레스는 php로 제작되었고, 데이터베이스로 MySQL 또는 MariaDB를 사용하는데 이 중에서 MariaDB를 선택했다.

아래의 설명은 앞선 두 글 07. SSL/TLS 인증서08. 웹 서버를 바탕으로 자신의 도메인에 SSL/TLS 인증서를 발급받았고 Nginx 웹 서버가 설치된 상태임을 전제로 한다. 필요한 내용들은 아래에도 다시 간략히 중복 설명하겠지만 자세한 내용은 앞선 두 글을 참고한다.

php 설치

sudo apt-get update
sudo apt-get install php-fpm
sudo apt-get install php php-curl php-gd php-mbstring php-mysql php-xml php-xmlrpc

패키지 저장소 정보를 업데이트하고, php 및 워드프레스 운영에 필요한 php 확장 모듈을 설치한다. 우분투 서버 18.04 LTS 버전에서는 php 7.2버전이 기본으로 설치되는데, php 설치 명령을 먼저 실행하면 Apache 웹 서버가 함께 설치된다. Nginx 웹 서버를 사용하기 때문에 Apache 웹 서버를 설치하고 싶지 않다면, php-fpm을 단독으로 먼저 설치한 다음에 php를 설치하면 Apache 웹 서버가 설치되지 않는다.

sudo nano /etc/php/7.2/fpm/php.ini

php 설정 파일을 nano 편집기로 열고 아래를 참고해서 적절히 편집한다. 참고로 nano 편집기에서 항목을 찾을 때는 ctrl키와 w키를 동시에 누르면 찾을 내용을 입력하는 메뉴가 나타난다.

memory_limit = 256M
post_max_size = 160M
upload_max_filesize = 128M
max_file_uploads = 20
max_execution_time = 60
max_input_time = 120
date.timezone = Asia/Seoul
mbstring.language = UTF-8
mbstring.internal_encoding = UTF-8
mbstring.http_input = UTF-8
mbstring.http_output = UTF-8

memory_limit은 php가 사용할 최대 메모리 용량으로, 기본값은 128M 이다. 웹사이트 운영 중에 “Fatal Error: Allowed Memory Size of XXXXX Bytes Exhausted” 오류가 나타나면 이 값을 적절히 늘려야 한다.
post_max_size는 php로 생성되는 게시물 하나의 최대 용량으로, 게시물 자체의 용량 및 이 게시물에 포함된 첨부파일의 용량을 포함한다. 따라서 첨부파일 용량에 해당하는 아래의 max_file_uploads 보다 큰 값을 지정해야 한다. 기본값은 8M이다.
upload_max_filesize는 php를 통해 업로드 되는 파일의 최대 용량으로, 기본값은 2M이다. 워드프레스 내부의 버튼을 클릭해서 업로드하는 테마, 플러그인, 미디어 파일 등의 모든 파일이 이 용량에 제한받으므로 필요한 만큼 적절히 늘려준다.
max_file_uploads는 한 번에 업로드 할 수 있는 파일의 개수이다. 기본값은 20이다.
max_execution_time은 php 스크립트가 실행되는 최대 시간으로, 기본값은 30초이다. 여기서 지정한 시간 이내에 php 스크립트 작동이 완료되지 않으면 강제로 종료된다. post_max_sizeupload_max_filesize의 값을 늘렸다면 늘린 크기의 파일을 업로드하는데 소요되는 충분한 시간으로 설정한다.
max_input_time은 스크립트가 입력받은 데이터를 처리하는 최대 시간으로, 기본값은 60초이다. post_max_sizeupload_max_filesize의 값을 늘렸다면 늘린 크기의 파일을 업로드하는데 소요되는 충분한 시간으로 설정한다.
date.timezone은 시간대를 설정하는 옵션으로 옵션 앞에 주석 ;을 제거하고 Asia/Seoul로 지정한다.
mbstring으로 시작하는 4개의 옵션 앞에 주석 ;을 제거하고 UTF-8로 지정한다.

설정이 끝났으면 Ctrl키와 x키를 동시에 눌러서 nano 편집기를 빠져나오면서 저장한다.

sudo systemctl restart php7.2-fpm

설정한 내용을 반영하기 위해 php7.2-fpm을 재시작한다.

MariaDB 설치

sudo apt-get update
sudo apt-get install mariadb-server

패키지 저장소 정보를 업데이트하고, MariaDB를 설치한다.

sudo mysql_secure_installation

MariaDB를 처음 설치했으면 MariaDB의 기본 보안 설정을 진행한다. 몇 가지 사항을 질문해오는데 다음 설명을 참고해서 입력한다.
Enter current password for root:   MariaDB를 처음 설치한 경우 아직 패스워드를 설정하지 않았으므로 그냥 엔터키를 입력한다.
Set root password?   y를 입력해서 MariaDB의 루트 패스워드를 설정한다.
New password:   패스워드를 결정해서 입력한다.
Re-enter new password:   패스워드를 한 번 더 입력해서 확인한다.
Remove anonymous users?   y를 입력한다.
Disallow root login remotely?   y를 입력한다.
Remove test database and access to it?   y를 입력한다.
Reload privilege tables now?   y를 입력한다.

데이터베이스 생성

워드프레스가 사용할 데이터베이스를 생성한다.

sudo mysql -u root -p

위 명령을 실행한 후 MariaDB의 루트 패스워드를 입력해서 MariaDB에 접속한다.

CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

wordpress라는 이름의 데이터베이스를 utf8mb4 문자셋으로 생성한다. 데이터베이스 이름은 원하는 이름으로 생성하면 된다.

CREATE USER 'wpuser'@'localhost' IDENTIFIED BY '비밀번호';

wpuser라는 이름의 사용자와 이 사용자의 비밀번호를 생성한다. 역시 원하는 이름으로 생성하면 되고, 자신만의 비밀번호를 결정해서 입력한다.

GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';

wpuser 사용자에게 wordpress라는 이름의 데이터베이스의 모든 권한을 부여한다.

FLUSH PRIVILEGES;

설정 사항을 반영한다.

exit;

MariaDB 접속을 종료한다.

SSL/TLS 인증서 발급

https 보안 연결을 구성하기 위해서 도메인에 SSL/TLS 인증서를 발급받는다. 자세한 내용은 07. SSL/TLS 인증서를 참고한다.

Nginx 설치

워드프레스를 운영할 웹 서버로 앞서 설치한 Nginx를 사용할 것이다. Nginx 설치 및 작동에 관한 기본적인 개념은 앞선 글 08. 웹 서버를 참고한다.

DH Param 키 생성

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

앞선 글을 통해서 DH Param 키를 생성했다면 그 키 하나로 모든 웹사이트에 사용할 수 있으므로 이 단계는 건너뛴다. 만일 생성하지 않았다면 위 명령으로 DH Param 키를 생성한다. DH Param 키는 일부 암호화 방식의 성능을 높이기 위해 사용하는 난수인데, 위 명령어는 4096 비트 (512 바이트) 로 생성하므로 시간이 오래 걸린다. 서버 컴퓨터의 성능에 따라 다르지만 길게는 수십분 가량 소요되기도 한다. 2048 비트 (256 바이트) 로 생성하려면 위의 명령에서 끝에 4096을 2048로 바꿔서 입력한다. 키가 생성되는 위치는 /etc/ssl/certs/dhparam.pem 으로 지정했다.

워드프레스 설치 공간 생성

sudo mkdir -p /var/www/example.com/html

example.com 도메인을 사용한다고 가정하고, 워드프레스가 설치될 root 디렉토리를 생성한다. /var/www/ 하위의 디렉토리 이름은 원하는 대로 생성하면 되는데 여기서는 구분하기 쉽도록 example.com 도메인 이름을 그대로 사용했다.

Nginx 서버 블록 준비

sudo nano /etc/nginx/sites-available/example.com

example.com 웹사이트의 설정을 담을 Nginx 서버 블록 파일을 nano 편집기로 생성하고, 아래의 내용을 작성한다. 구분하기 쉽도록 서버 블록 파일의 이름을 example.com 도메인 이름 그대로 사용했다.

server {
	listen 80;

	server_name example.com www.example.com;

	return 301 https://$server_name$request_uri;
}

server {
	listen 443 ssl http2;

	server_name example.com www.example.com;

	root /var/www/example.com/html;

	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
	ssl_dhparam /etc/ssl/certs/dhparam.pem;

	ssl_protocols TLSv1.2;
	ssl_prefer_server_ciphers on;
	ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256;
	ssl_ecdh_curve secp384r1;
	ssl_session_timeout 10m;
	ssl_session_cache shared:SSL:10m;
	ssl_session_tickets off;
	ssl_stapling on;
	ssl_stapling_verify on;
	resolver 8.8.8.8 8.8.4.4 valid=300s;
	resolver_timeout 5s;

	add_header Strict-Transport-Security max-age=31536000;
	add_header X-Frame-Options SAMEORIGIN;
	add_header X-Content-Type-Options nosniff;
	add_header X-XSS-Protection "1; mode=block";

	index index.php index.html index.htm;

	location / {
		try_files $uri $uri/ /index.php$is_args$args;
	}

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        }

	client_max_body_size 0;
}

7군데의 example.com을 자신의 것으로 바꾸는 것에 주의하면서, 위의 내용으로 서버 블록 파일을 작성한다. 위의 내용에 대한 전반적인 설명은 앞선 글 08. 웹 서버를 참고하는데, 파란색 부분은 변경되거나 새로 추가된 부분이다.

파란색 부분을 살펴보면, indexindex.php를 앞에 추가해서 워드프레스의 php 파일이 서비스 되도록 하고, try_files에 php를 처리하도록 해서 워드프레스의 URI 구조가 작동하도록 한다. location ~ \.php$ 부분은 이 웹사이트에 php 프로그램을 연결하는 설정이다. client_max_body_size 0;은 Nginx 측의 게시물 용량 제한을 없애는 설정인데, php로 업로드 되는 용량은 여전히 php.ini에서 제어되지만 Nginx 측에서 중복으로 제한하는 것을 없애는 설정이다.

편집을 끝냈으면 Ctrl키와 x키를 동시에 눌러서 nano 편집기를 빠져나오면서 저장한다.

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

작성한 서버 블록을 작동시키기 위해 /etc/nginx/sites-enabled/ 경로에 심볼릭 링크를 만들어준다.

만일 이런 서버 블록을 여러 개 생성해서 다수의 웹사이트를 운영한다면 도메인 처리를 원활하게 하기 위해서 Nginx 설정 파일 nginx.conf에 아래의 설정을 추가한다.

sudo nano /etc/nginx/nginx.conf

Nginx 설정 파일인 nginx.conf 파일을 nano 편집기로 연다.

server_names_hash_bucket_size 64;

server_names_hash_bucket_size 64;를 찾아서 앞에 주석 #을 제거하고, Ctrl키와 x키를 동시에 눌러서 nano 편집기를 빠져나오면서 저장한다. 이미 처리되어 있다면 그대로 nano 편집기를 빠져나온다.

이상으로 서버 블록 설정이 끝났으면, 설정한 서버 블록이 Nginx에 반영되도록 아래와 같이 Nginx를 재시작한다.

sudo nginx -t

Nginx 설정에 기본적인 문법 오류가 없는지 점검한다. 오류가 없다면
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
이런 메시지가 출력된다. 만일 다른 메시지가 나온다면 메시지를 참고해서 설정 사항을 점검한다.

sudo systemctl restart nginx

오류가 없으면 Nginx를 재시작한다.

워드프레스 설치 파일 준비

이제 워드프레스 설치 파일을 내려받고 필요한 디렉토리와 설정 파일을 준비한다.

cd /tmp

작업하기 편하도록 /tmp 디렉토리로 이동한다.

curl -O https://wordpress.org/latest.tar.gz

최신 버전의 워드프레스 설치 파일을 내려받는다.

tar -xzvf latest.tar.gz

내려받은 파일의 압축을 해제한다.

cp /tmp/wordpress/wp-config-sample.php /tmp/wordpress/wp-config.php

워드프레스 설정 파일 wp-config.php을 생성한다.

mkdir /tmp/wordpress/wp-content/upgrade

워드프레스가 업그레이드할 때 사용하는 디렉토리를 생성한다.

sudo cp -a /tmp/wordpress/. /var/www/example.com/html/

이렇게 구성한 워드프레스를 example.com의 root 디렉토리에 복사한다.

sudo chown -R varins:www-data /var/www/example.com/html

example.com의 root 디렉토리 및 그 하위 디렉토리(-R)의 소유자를 varins, 소유그룹을 www-data로 설정한다. varins는 자신의 사용자 이름으로 바꾸고 www-data는 그대로 입력한다. www-data는 우분투 서버의 웹서버 프로세스를 뜻한다. 이 명령은 example.com의 모든 파일의 소유자는 varins가 되고, 소유그룹은 웹 서버가 되도록 분리하는 설정이다. 이를 통해 기본적으로 모든 파일을 varins가 소유하도록 해서 보안을 확립하고, 편의를 위한 일부 기능 (첨부 파일 업로드, 워드프레스 내부의 버튼을 클릭해서 플러그인과 테마를 설치하고 업그레이드하는 기능 등) 에만 웹 서버에게 권한을 부여하기 위함이다.

sudo find /var/www/example.com/html -type d -exec chmod g+s {} \;

example.com의 각 디렉토리에 setgid (g+s) 권한을 설정한다. 이제 새롭게 생성되는 디렉토리의 소유그룹도 www-data가 된다.

sudo chmod g+w /var/www/example.com/html/wp-content

wp-content 디렉토리의 소유그룹 www-data에 쓰기 (+w) 권한을 부여한다. 웹 서버가 첨부 파일을 다루고 테마와 플러그인을 설치하고 업그레이드할 수 있도록 설정하는 것이다.

sudo chmod -R g+w /var/www/example.com/html/wp-content/themes

themes 디렉토리 및 그 하위 디렉토리(-R)의 소유그룹 www-data에 쓰기 (+w) 권한을 부여한다. 웹 서버가 테마를 설치하고 업그레이드할 수 있도록 설정하는 것이다.

sudo chmod -R g+w /var/www/example.com/html/wp-content/plugins

plugins 디렉토리 및 그 하위 디렉토리(-R)의 소유그룹 www-data에 쓰기 (+w) 권한을 부여한다. 웹 서버가 플러그인을 설치하고 업그레이드할 수 있도록 설정하는 것이다.

nano /var/www/example.com/html/wp-config.php

미완성인 워드프레스 설정 파일 wp-config.php을 nano 편집기로 열어서 아래를 참고해서 완성한다.

define('DB_NAME', 'wordpress');    → 앞에서 생성한 데이터베이스 이름
define('DB_USER', 'wpuser');    → 앞에서 생성한 데이터베이스 사용자 이름
define('DB_PASSWORD', '비밀번호');    → 앞에서 생성한 데이터베이스 사용자 비밀번호
define('DB_CHARSET', 'utf8mb4');    → 앞에서 생성한 데이터베이스 문자셋

define('AUTH_KEY',         'X)[5H4Rc=*ihp8l`2Eh@5;xRHE~O4ys~ECw-sVicd9x]vioJvXGb*1w&G{)$)9#_');
define('SECURE_AUTH_KEY',  'nC{ D5IcAOy`b8+u+H~^WRvB+tj_C{]|Y!sp,U$^$%^X|gWt)Y3~N-azhf{Fw?5O');
define('LOGGED_IN_KEY',    '8fudo^Lk[B*=Pr: +Nc?+_LJ5JZ,@a-m+L*@+x+KP4-sH0.c6)-;KsL$ @wI#xP{');
define('NONCE_KEY',        'mo*x~(P-{Z+H31CN]/L9uGiSn@It7eYZ^1~``Z-]/$[g4[[%-K-Y`7~!`bZb8Dd-');
define('AUTH_SALT',        'Sp5c;?6I)t(fwIXXL*/w6TlEUQ,Jr/YtHKd-Yh1!~@!)85sy9L:v]:J7[?Jj=I4i');
define('SECURE_AUTH_SALT', 'LtrjX&69gei$R^WSQ|-KW]CM%PVhVEDiYh-f^J7(B8|-=Zx_re-|pue0Xo)!aNRz');
define('LOGGED_IN_SALT',   '6x{tz2FGXL0yI3Hm&!e,%?7*&L,J0QyFy@U[Q:|-*Z;^^McR$G=L|[rF-f_P +w[');
define('NONCE_SALT',       'W0zRBR`5cS.F?*t=)$DE]]ospQ4cm3+hWZh^W,lIfB|Z,$+a(||-Kih}T$c{3Oxu');

몇 가지 인증에 사용되는 키를 입력하는데 완전히 유일한 문자열이어야 하므로 위 내용을 복사해서 넣으면 안 되고 웹사이트 https://api.wordpress.org/secret-key/1.1/salt/ 에 접속해서 접속할 때마다 무작위로 만들어주는 문자열을 입력하면 된다. 이 문자열을 우분투 서버상에서 얻으려면 curl -s https://api.wordpress.org/secret-key/1.1/salt/ 명령을 사용하면 된다.

define('FS_METHOD', 'direct');

이 항목은 wp-config.php 파일에 없는 항목인데 직접 추가한다. 워드프레스가 플러그인 등을 업그레이드하기 위해서 파일 시스템에 접근할 때 권한이 있는 작업이라면 FTP 프로토콜을 통하지 않고 바로 작업하도록 하는 옵션이다.

편집을 끝냈으면 Ctrl키와 x키를 동시에 눌러서 nano 편집기를 빠져나오면서 저장한다.

sudo rm /tmp/latest.tar.gz
sudo rm -rf /tmp/wordpress

/tmp에 내려받은 워드프레스 설치 파일 및 압축을 해제한 디렉토리를 삭제하려면 위의 명령을 실행한다.

WordPress 설치

모든 준비가 끝났으면 웹브라우저로 https://example.com에 접속해서 워드프레스를 설치한다. 사용할 언어를 선택하고, 웹사이트 이름을 결정하고, 관리자 ID와 비밀번호를 결정하고, 이메일 주소를 입력하고, 검색엔진에 이 웹사이트를 노출할 것인지를 선택하면 설치가 끝난다.

WordPress 업그레이드

테마와 플러그인의 업그레이드는 위에서 웹 서버에게 권한을 부여했기 때문에 워드프레스 내부에서 버튼을 클릭하는 것으로 끝낼 수 있다. 반면에 워드프레스 자체의 업그레이드는 때에 따라 웹 서버에게 권한이 부족해서 자동으로 진행되지 않을 수도 있다. 이럴 때는 sudo chown -R www-data /var/www/example.com/html 명령을 내려서 임시로 웹 서버에게 권한을 준 다음, 워드프레스 내부의 업그레이드 버튼을 클릭해서 업그레이드를 완료하고, 다시 sudo chown -R varins /var/www/example.com/html 명령을 내려서 권한을 복구하면 된다. varins를 자신의 사용자 이름으로 바꿔서 실행한다.

 

홈 서버 만들기 목차 
https://varins.com/category/server

01. 하드웨어 구성과 전기 요금
02. 우분투 서버 18.04 LTS 설치
03. 우분투 서버 18.04 LTS 기본 설정
04. 파일 복원: Btrfs 스냅샷
05. 네트워크 파일 공유: Samba (SMB)
06. Dynamic DNS: 구글 도메인 + ddclient
07. SSL/TLS 인증서: Let's Encrypt (Wildcard)
08. 웹 서버: Nginx + https 보안연결
09. 웹사이트: php + MariaDB + WordPress
10. 서버 모니터링: Monitorix + Nginx Proxy
11. FTPS: vsftpd
12. VPN: IKEv2 (strongSwan)
13. Torrent: Transmission
14. 클라우드 스토리지: Nextcloud (Nginx, MariaDB)
15. 온라인 오피스: ONLYOFFICE (Docker, Nginx)
16. 트랜스코딩: Plex

Leave a comment

Your email address will not be published. Required fields are marked *

Prev Post Next Post