Установка WordPress на веб-сервер Nginx с обработчиком PHP-FPM

Векторная иллюстрация облачного сервера

Это пошаговое руководство по развертыванию сайта под управлением WordPress 6.4.3 на виртуальном сервере со стеком LEMP и менеджером процессов PHP-FPM, а также расширением HTTPS, поддержкой протокола HTTP/2, алгоритма сжатия Brotli на основе Ubuntu Server 22.04.3 LTS

Технические требования

Требования к серверу включают несколько элементов: оперативная память, версия сервера баз данных, вычислительная мощность, дисковое пространство и используемый веб-сервер.

Минимальные технические требования для установки WordPress:

Сервер Nginx или Apache с модулем mod-rewrite
Дисковое пространство Не менее 1 GB
PHP Версия 7.4 или выше
База данных MySQL 5.015 или выше (MariaDB, версия 10.1 или выше)
RAM Не менее 512 MB
CPU Не менее 1.0 GHz

В процессе создания этого материала был использован облачный сервер с тарифом Turbo-1 REG.RU. Перед установкой веб-сервера, убедитесь в корректности настроек DNS для домена у вашего хостинг-провайдера.

Установка PHP 8.1

Подключитесь к серверу по SSH под логином root и обновите менеджер пакетов Ubuntu:

apt update

Установите PHP, менеджер процессов PHP-FPM и другие зависимости для корректной работы WordPress:

apt install --no-install-recommends php8.1
apt install -y php8.1-bcmath php8.1-bz2 php8.1-cli php8.1-common php8.1-curl php8.1-fpm php8.1-gd php8.1-imagick php8.1-intl php8.1-mbstring php8.1-mysql php8.1-readline php8.1-soap php8.1-xml php8.1-xmlrpc php8.1-zip

Проверьте корректность установки PHP:

php -v

Установка Nginx 1.24

Для быстрой работы WordPress потребуется установка дополнительных модулей, таких как: ngx_brotli, ngx_purge_cache. Выполните установку веб-сервера методом ручной сборки из исходного кода.

Подготовка для сборки Nginx из исходных файлов

В корневой директории пользователя root создайте новый каталог для более удобной сборки веб-сервера и перейдите в нее:

mkdir build
cd build

Установите зависимости для сборки Nginx из репозитория Ubuntu:

apt install build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev libgd-dev libxml2 libxml2-dev uuid-dev

Загрузите актуальную версию Nginx и разверните ее, затем добавьте нового пользователя nginx, и создайте каталог для хранения кэша:

wget https://nginx.org/download/nginx-1.24.0.tar.gz 
tar zxf nginx-1.24.0.tar.gz
useradd nginx
mkdir /var/cache/nginx/

Внедрение алгоритма сжатия Brotli

Загрузите модуль сжатия Brotli из официального репозитория Google:

git clone --recursive https://github.com/google/ngx_brotli.git

Внедрение модуля для очистки кэша FastCGI

Загрузите и разверните модуль для ручной очистки кэша с сайта разработчика и переименуйте каталог модуля для сборки:

wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
tar zxf ngx_cache_purge-2.3.tar.gz
mv ngx_cache_purge-2.3 ngx_cache_purge

Перейдите в каталог, где был развернут Nginx и выполните сборку с параметрами:

cd nginx-1.24.0
./configure --add-module=/root/build/ngx_cache_purge --add-module=/root/build/ngx_brotli --without-http_autoindex_module --without-http_empty_gif_module --without-http_memcached_module --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -ffile-prefix-map=/usr/local/src/nginx-1.24.0=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -flto=auto -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'

Обратите внимание, что в данной конфигурации, мы исключили несколько стандартных модулей, а именно: http_autoindex_module, http_empty_gif_module, http_memcached_module.

Если вам нужен какой-либо из этих модулей для вашего проекта на Nginx, удалите соответствующую строку из приведенной выше команды:

  • —without-http_autoindex_module,
  • —without-http_empty_gif_module,
  • —without-http_memcached_module.

Выполните сборку и проверьте состояние конфигурации сервера:

make
make install
nginx -t

Добавление Nginx в подсистему управления службами

Создание службы позволит автоматически запускать веб-сервер на VPS и удобно управлять процессом работы. Для этого создайте конфигурацию для управления Nginx в системе Ubuntu:

nano /lib/systemd/system/nginx.service

Вставьте инструкцию и сохраните новый юнит для systemd:

[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Включите автозапуск сервиса при загрузке системы, запустите веб-сервер и проверьте его статус:

systemctl enable nginx
systemctl start nginx
systemctl status nginx

Настройка конфигурации

Измените стандартный файл конфигурации nginx.conf, для этого сотрите содержимое и вставьте новые инструкции:

nano /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /var/run/nginx.pid;

events {
    worker_connections 768;
}

include /etc/nginx/sites-enabled/*.stream;

http {

    # Basic
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    types_hash_max_size 2048;
    server_tokens off;
    ignore_invalid_headers on;

    # Decrease default timeouts to drop slow clients
    keepalive_timeout 40s;
    send_timeout 20s;
    client_header_timeout 20s;
    client_body_timeout 20s;
    reset_timedout_connection on;

    # Hash sizes
    server_names_hash_bucket_size 64;

    # Mime types
    default_type  application/octet-stream;
    include /etc/nginx/mime.types;

    # Logs
    log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent" "$gzip_ratio"';
    access_log /var/log/nginx/access.log main;
    error_log /var/log/nginx/error.log warn;

    # Limits
    limit_req_zone $binary_remote_addr zone=flood:20m rate=30r/m;

    # Gzip
    gzip on;
    gzip_disable "msie6";
    gzip_vary off;
    gzip_proxied any;
    gzip_comp_level 5;
    gzip_min_length 1000;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types
        application/atom+xml
        application/javascript
        application/json
        application/ld+json
        application/manifest+json
        application/rss+xml
        application/vnd.geo+json
        application/vnd.ms-fontobject
        application/x-font-ttf
        application/x-web-app-manifest+json
        application/xhtml+xml
        application/xml
        font/opentype
        image/bmp
        image/svg+xml
        image/x-icon
        text/cache-manifest
        text/css
        text/plain
        text/vcard
        text/vnd.rim.location.xloc
        text/vtt
        text/x-component
        text/x-cross-domain-policy;

    # Brotli
    brotli on;
    brotli_comp_level 6;
    brotli_types
        text/xml
        image/svg+xml
        application/x-font-ttf
        image/vnd.microsoft.icon
        application/x-font-opentype
        application/json
        font/eot
        application/vnd.ms-fontobject
        application/javascript
        font/otf
        application/xml
        application/xhtml+xml
        text/javascript
        application/x-javascript
        text/$;

    # Virtual Hosts
    include /etc/nginx/sites-enabled/*;

    # Configs
    include /etc/nginx/conf.d/*.conf;
    include /usr/share/nginx/modules/*.conf;
}

Настройка виртуального хоста

Создайте директории для размещения конфигураций виртуальных хостов:

mkdir /etc/nginx/sites-available
mkdir /etc/nginx/sites-enabled

Создайте корневую директорию для сайта, где example.com — его доменное имя:

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

Разместите конфигурацию Nginx c поддержкой менеджера процессов PHP-FPM:

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

Cодержание nginx.conf:

upstream example-php-handler {
        server unix:/var/run/php/php8.1-fpm.sock;
}
server {
        listen 80;
        server_name example.com www.example.com;
        root /var/www/example.com/html;
        index index.php;
        location / {
                try_files $uri $uri/ /index.php?$args;
        }
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass example-php-handler;
        }
}

Создайте символьную ссылку на файл конфигурации для подключения нового виртуального хоста:

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

Для проверки синтаксиса конфигурации выполните:

nginx -t

Перезагрузите сервер:

systemctl restart nginx

Настройка протокола HTTPS

Для включения поддержки HTTPS, потребуется выпуск SSL-сертификата для домена и настройка перенаправлений на сервере.

Создайте ключ не менее 2048 бит:

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

Запишите параметры безопасности:

nano /etc/nginx/snippets/ssl-params.conf
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

add_header Strict-Transport-Security "max-age=63072000" always;

Установите утилиту Snap:

apt install snapd
snap install core

Установите certbot:

snap install --classic certbot

Создайте символьную ссылку:

ln -s /snap/bin/certbot /usr/bin/certbot

Начните процесс получения сертификата в соответствии с конфигурацией сервера:

certbot certonly --nginx

Выполнение сценария:

Enter email address (used for urgent renewal and security notices)
Укажите действительный адрес эл. почты для получения уведомлений.
You must agree in order to register with the ACME server. Do you agree?
Y
Which names would you like to activate HTTPS for?
1 2

Измените конфигурацию Nginx для поддержки протокола HTTPS:

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

Cодержание nginx.conf:

upstream example-php-handler {
        server unix:/var/run/php/php8.1-fpm.sock;
}
server {
        listen 80;
        listen [::]:80;

        server_name example.com www.example.com;
        return 301 https://example.com$request_uri;
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;

        server_name example.com;
        root /var/www/example.com/html;
        index index.html index.php;

        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

        include snippets/ssl-params.conf;

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

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass example-php-handler;
        }
}

Для проверки синтаксиса конфигурации выполните:

nginx -t

Перезагрузите сервер:

systemctl restart nginx

Создайте в корневой директории файл index.php:

nano /var/www/example.com/html/index.php
<?php
    phpinfo();
?>

Откройте сайт и убедитесь, что сервер использует в качестве API — FPM/FastCGi:

Вывод результата функции phpinfo в браузере

А затем удалите файл:

rm /var/www/example.com/html/index.php

Установка MariaDB

Установите MariaDB Server и запустите сервис:

apt install mariadb-server
systemctl start mariadb.service

Запустите сценарий оболочки для настройки параметров безопасности и создания нового пароля для пользователя root:

mysql_secure_installation

Выполнение сценария:

Enter current password for root (enter for none):
Enter
Switch to unix_socket authentication
Y
Change the root password?
Y
Remove anonymous users?
Y
Disable root login remotely?
Y
Remove test database and access to it?
Y
Reload privilege tables now?
Y
Reload privilege tables now?
Y

Проверьте корректность установки MariaDB:

systemctl status mysql

Создание пользователя и базы данных

Начните новый сеанс:

mysql -u root -p

Создайте новую базу данных, где database_name название новой базы данных:

CREATE DATABASE database_name DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Создайте нового пользователя, где database_user — имя пользователя, user_password — пароль:

CREATE USER 'database_user' IDENTIFIED BY 'user_password';

Предоставьте пользователю права доступа:

GRANT ALL ON *.* TO 'database_user'@localhost IDENTIFIED BY 'user_password';

Перезагрузите все таблицы предоставления привилегий:

FLUSH PRIVILEGES;

Завершите сеанс:

exit

При переносе сайта на новый сервер Ubuntu, импортируйте дамп базы данных предварительно загрузив его на сервер, выйдите из оболочки MariaDB и наберите команду:

mysql -u database_user -p database_name < /path/dump.sql

где, database_user — имя пользователя, database_name — название базы данных, path — каталог в котором расположен дамп базы данных, а dump — название файла для импорта.

Установка phpMyAdmin

Установите приложение из репозитория:

apt install phpmyadmin

Выполнение сценария:

Web server to reconfigure automatically?
Изменение конфигурации не требуется, наведите курсор на <ОК> нажатием клавиш Tab, затем Enter.
Настройка конфигурации phpMyAdmin в консоли
Configure database for phpmyadmin with dbconfig-common?
<YES>
MySQL application password for phpmyadmin:
Задайте пароль и нажмите <ОК>.
Password confirmation:
Повторите пароль и нажмите <ОК>.

В случае возникновения ошибки ERROR 1819 (HY00), выберите пункт ignore:

Настройка конфигурации phpMyAdmin в случае ошибки

Для исправления ошибки: отключите компонент проверки паролей или понизьте уровень требований в MySQL. После установки phpMyAdmin восстановите прежние настройки.

Создайте символьную ссылку:

ln -s /usr/share/phpmyadmin/ /var/www/example.com/html/

Наберите адрес phpMyAdmin в адресной строке браузера и авторизуйтесь под логином root:

https://example.com/phpmyadmin

Установка Uncomplicated Firewall

Если в вашем образе Ubuntu Server утилита UFW уже установлена, включите файрвол и разрешите сервисы: Nginx Full, OpenSSH.

В иных случаях, установите утилиту для конфигурирования межсетевого экрана:

apt install ufw

Добавьте Nginx в список приложений доступных для использования. Для этого создайте файл:

nano /etc/ufw/applications.d/nginx

Запишите конфигурацию:

[Nginx HTTP]
title=Web Server
description=Enable NGINX HTTP traffic
ports=80/tcp

[Nginx HTTPS] \
title=Web Server (HTTPS) \
description=Enable NGINX HTTPS traffic
ports=443/tcp

[Nginx Full]
title=Web Server (HTTP, HTTPS)
description=Enable NGINX HTTP and HTTPS traffic
ports=80,443/tcp

Добавьте OpenSSH в список приложений UFW. Для этого создайте файл:

nano /etc/ufw/applications.d/open-ssh-server
[OpenSSH]
title=Secure shell server, an rshd replacement
description=OpenSSH is a free implementation of the Secure Shell protocol.
ports=22/tcp

Проверьте список доступных приложений:

ufw app list

Включите файрвол:

ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)?
Y

Разрешите сервисы:

ufw allow 'Nginx Full'
ufw allow 'OpenSSH'

Проверьте статус:

ufw status

Вывод статуса утилиты UFW в консоль

Установка WordPress

Перейдите в корневую директорию сайта:

cd /var/www/example.com/html/

Загрузите последнюю версию WordPress:

wget https://ru.wordpress.org/latest-ru_RU.tar.gz

Выполните процесс разархивирования:

tar -xzvf latest-ru_RU.tar.gz

Перенесите файлы из папки wordpress в корень сайта:

mv wordpress/* /var/www/example.com/html

Удалите загруженный архив и папку wordpress:

rm latest-ru_RU.tar.gz
rm -rf wordpress/

Измените владельца файлов:

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

Измените права доступа к файлам и папкам:

find . -type f -exec chmod 644 {} +
find . -type d -exec chmod 755 {} +

Выполните настройку конфигурации WordPress в файле wp-config.php, для этого создайте файл:

cp wp-config-sample.php wp-config.php
nano wp-config.php

И заполните значения констант:

  • DB_NAME,
  • DB_USER,
  • DB_PASSWORD.

Редактирование файла wp-config.php из консоли

Получите уникальный ключи и соли аутентификации по ссылке: https://api.wordpress.org/secret-key/1.1/salt/.

И впишите их в wp-config.php:

Редактирование файла wp-config.php из консоли

Откройте сайт в браузере и выполните установку WordPress, авторизуйтесь в панели администратора и перейдите на экран Здоровье сайта для проверки корректности установки:

Проверка корректности установки WordPress в панели администратора

Проверьте наличие сжатия Brotli в заголовке веб-сервера, для этого наберите команду, где example.com — адрес вашего сайта:

curl -H 'Accept-Encoding: br' -I example.com

Результат:

Content-Encoding: br

В руководстве приведена демонстрационная версия файла конфигурации Nginx для WordPress. Установите заголовки безопасности HTTP, настройте правила кэширования и сжатия статических файлов самостоятельно перед публикацией сайта в Интернете.