Аўтаматызуем усталёўку WordPress з NGINX Unit і Ubuntu

Аўтаматызуем усталёўку WordPress з NGINX Unit і Ubuntu

Ёсць мноства матэрыялаў па ўсталёўцы WordPress, пошук у Google па ключавых словах "WordPress install" выдасць каля паўмільёна вынікаў. Але тым не менш фактычна сярод іх вельмі мала прыдатных кіраўніцтваў, па якіх можна ўсталяваць і наладзіць WordPress і ніжэйлеглую аперацыйную сістэму так, каб яны былі здольныя да падтрымкі на працягу працяглага перыяду часу. Магчыма, правільныя налады моцна залежаць ад канкрэтных патрэбаў, ці ж гэта звязана з тым, што падрабязнае тлумачэнне робіць артыкул цяжкім для чытання.

У гэтым артыкуле мы пастараемся сабраць лепшае з двух падыходаў, падаючы скрыпт на bash для аўтаматычнай усталёўкі WordPress на Ubuntu, а таксама пройдземся па ім, тлумачачы, што робіць кожны яго кавалачак, а таксама на якія кампрамісы мы пайшлі пры ім распрацоўцы. Калі вы дасведчаны карыстальнік - можаце прапусціць тэкст артыкула і проста узяць скрыпт для мадыфікацыі і выкарыстання ў вашых асяродках. На выхадзе скрыпту атрымліваецца наладжвальная ўстаноўка WordPress з падтрымкай Lets Encrypt, якая працуе на NGINX Unit і прыдатная для прамысловага прымянення.

Распрацаваная архітэктура для разгортвання WordPress з выкарыстаннем NGINX Unit апісана ў больш старым артыкуле, зараз мы таксама дадаткова наладзім рэчы, якія там не былі ахоплены (як і ў многіх іншых кіраўніцтвах):

  • WordPress CLI
  • Let's Encrypt і сертыфікаты TLSSSL
  • Аўтаматычнае абнаўленне сертыфікатаў
  • Кэшаванне NGINX
  • Сціск NGINX
  • Падтрымка HTTPS і HTTP/2
  • Аўтаматызацыя працэсу

У артыкуле будзе апісана ўстаноўка на адным серверы, на якім будуць размешчаны адначасова сервер апрацоўкі статыкі, сервер апрацоўкі PHP, база даных. Ўстаноўка з падтрымкай мноства віртуальных хастоў і сэрвісаў – патэнцыйная тэма на будучыню. Хочаце, каб мы напісалі пра нешта, чаго няма ў гэтых артыкулах - пішыце ў каментарах.

Патрабаванні

  • Сервер-кантэйнер (LXC або LXD), віртуальная машына, або звычайны жалезны сервер, з не менш чым 512Мб аператыўнай памяці і ўсталяванай Ubuntu 18.04/XNUMX або больш свежай.
  • Даступныя з інтэрнэту парты 80 і 443
  • Даменнае імя, звязанае з публічным ip-адрасам гэтага сервера
  • Доступ з правамі root (sudo).

Агляд архітэктуры

Архітэктура такая ж, як было апісана раней, трохузроўневае web-дадатак. Яно складаецца са скрыптоў PHP, выкананых на апрацоўшчыку PHP, і статычных файлаў, апрацоўваных вэб-серверам.

Аўтаматызуем усталёўку WordPress з NGINX Unit і Ubuntu

агульныя прынцыпы

  • Многія каманды для налады ў скрыпце абгорнутыя ва ўмовы (if) для ідэмпатэнтнасці: скрыпт можна запускаць некалькі разоў без рызыкі змены налад, якія ўжо гатовыя.
  • Скрыпт імкнецца ўсталёўваць ПЗ з рэпазітараў, так што вы можаце ўжываць абнаўленні сістэмы ў адну каманду (apt upgrade для Ubuntu).
  • Каманды імкнуцца вызначыць, што яны запускаюцца ў кантэйнеры, каб змяніць якая адпавядае выявай свае налады.
  • Для таго, каб задаць лік запускаемых працэсаў струменяў у наладах, скрыпт спрабуе адгадаць аўтаматычныя параметры налады для працы ў кантэйнерах, віртуальных машынах, "жалезных" серверах.
  • Пры апісанні налад заўсёды думаем у першую чаргу аб аўтаматызацыі, якая, як мы спадзяемся, стане асновай для стварэння вашай уласнай інфраструктуры як кода.
  • Усе каманды запускаюцца ад карыстальніка корань, таму што яны змяняюць асноўныя сістэмныя наладкі, але непасрэдна WordPress працуе ад звычайнага карыстальніка.

Ўстаноўка зменных асяроддзя

Усталюйце наступныя зменныя асяроддзі, перш чым запускаць скрыпт:

  • WORDPRESS_DB_PASSWORD - пароль да базы дадзеных WordPress
  • WORDPRESS_ADMIN_USER - імя адміністратара WordPress
  • WORDPRESS_ADMIN_PASSWORD - пароль адміністратара WordPress
  • WORDPRESS_ADMIN_EMAIL - email адміністратара WordPress
  • WORDPRESS_URL - поўны URL сайта WordPress, пачынаючы з https://.
  • LETS_ENCRYPT_STAGING - пустая па-змаўчанні, але, выставіўшы значэнне ў 1, вы будзеце выкарыстоўваць staging сервера Let's Encrypt, неабходныя для частага запыту сертыфікатаў пры тэставанні вашых налад, інакш Let's Encrypt можа часова заблакаваць ваш ip-адрас з-за вялікай колькасці запытаў.

Скрыпт правярае, што гэтыя звязаныя з WordPress зменныя выстаўлены, і завяршае працу, калі не.
Радкі скрыпту 572-576 правяраюць значэнне LETS_ENCRYPT_STAGING.

Ўстаноўка вытворных зменных асяроддзя

Скрыпт у радках 55-61 выстаўляе наступныя зменныя асяроддзі, або ў некаторае цвёрда зададзенае значэнне, або з ужываннем значэння, атрыманага з зменных, усталяваных у папярэдняй частцы:

  • DEBIAN_FRONTEND="noninteractive" - Паведамляе прыкладанням, што яны запускаюцца ў скрыпце і няма магчымасці ўзаемадзеяння з карыстальнікам.
  • WORDPRESS_CLI_VERSION="2.4.0" - Версія прыкладання WordPress CLI.
  • WORDPRESS_CLI_MD5= "dedd5a662b80cda66e9e25d44c23b25c" - кантрольная сума выкананага файла WordPress CLI 2.4.0 (версія паказваецца ў зменнай WORDPRESS_CLI_VERSION). Скрыпт на 162 радку выкарыстоўвае гэтае значэнне для праверкі, што быў запампаваны карэктны файл WordPress CLI.
  • UPLOAD_MAX_FILESIZE="16M" - Максімальны памер файла, які можа быць запампаваны ў WordPress. Гэтая настройка выкарыстоўваецца ў некалькіх месцах, так што прасцей задаваць яе ў адным месцы.
  • TLS_HOSTNAME= "$(echo ${WORDPRESS_URL} | cut -d'/' -f3)" - hostname сістэмы, вымаемы з зменнай WORDPRESS_URL. Выкарыстоўваецца для атрымання адпаведных TLS/SSL сертыфікатаў ад Let's Encrypt, а таксама для ўнутранай праверкі WordPress.
  • NGINX_CONF_DIR="/etc/nginx" - шлях да каталога з наладамі NGINX, уключаючы асноўны файл nginx.conf.
  • CERT_DIR="/etc/letsencrypt/live/${TLS_HOSTNAME}" - шлях да сертыфікатаў Let's Encrypt для сайта WordPress, які атрымліваецца са зменнай TLS_HOSTNAME.

Прызначэнне hostname WordPress серверу

Скрыпт усталёўвае hostname серверу, каб значэнне адпавядала даменнаму імя сайта. Гэта не абавязкова, але так зручней адпраўляць выходную пошту праз SMTP пры наладзе адзінага сервера, як гэта наладжваецца скрыптам.

код скрыпту

# Change the hostname to be the same as the WordPress hostname
if [ ! "$(hostname)" == "${TLS_HOSTNAME}" ]; then
  echo " Changing hostname to ${TLS_HOSTNAME}"
  hostnamectl set-hostname "${TLS_HOSTNAME}"
fi

Даданне hostname у /etc/hosts

Дадатак WP‑Cron выкарыстоўваецца для запуску перыядычных задач, патрабуе, каб WordPress мог атрымаць доступ да самога сябе праз HTTP. Каб пераканацца, што WP-Cron працуе карэктна на ўсіх асяродках, скрыпт дадае радок у файл. / Etc / хастоў, так што WordPress можа атрымаць доступ да самога сябе праз інтэрфейс loopback:

код скрыпту

# Add the hostname to /etc/hosts
if [ "$(grep -m1 "${TLS_HOSTNAME}" /etc/hosts)" = "" ]; then
  echo " Adding hostname ${TLS_HOSTNAME} to /etc/hosts so that WordPress can ping itself"
  printf "::1 %sn127.0.0.1 %sn" "${TLS_HOSTNAME}" "${TLS_HOSTNAME}" >> /etc/hosts
fi

Ўстаноўка інструментаў, неабходных для наступных крокаў

Пакінутая частка скрыпту мае патрэбу ў некаторых праграмах і мае на ўвазе, што рэпазітары актуальныя. Мы абнаўляем спіс рэпазітараў, пасля чаго ўсталёўваем патрэбныя прылады:

код скрыпту

# Make sure tools needed for install are present
echo " Installing prerequisite tools"
apt-get -qq update
apt-get -qq install -y 
  bc 
  ca-certificates 
  coreutils 
  curl 
  gnupg2 
  lsb-release

Даданне рэпазітараў NGINX Unit і NGINX

Скрыпт усталёўвае NGINX Unit і NGINX з адчыненым зыходным кодам з афіцыйных рэпазітароў NGINX, каб пераканацца, што выкарыстоўваюцца версіі з апошнімі абнаўленнямі бяспекі і выпраўленнямі памылак.

Скрыпт дадае рэпазітар NGINX Unit, а затым - рэпазітар NGINX, дадаючы ключ рэпазітароў і файлы налад. apt, якія задаюць доступ да рэпазітараў праз інтэрнэт.

Рэальная ўстаноўка NGINX Unit і NGINX адбываецца ў наступнай частцы. Мы папярэдне дадаем рэпазітары, каб не абнаўляць метададзеныя некалькі разоў, што робіць усталёўку хутчэй.

код скрыпту

# Install the NGINX Unit repository
if [ ! -f /etc/apt/sources.list.d/unit.list ]; then
  echo " Installing NGINX Unit repository"
  curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
  echo "deb https://packages.nginx.org/unit/ubuntu/ $(lsb_release -cs) unit" > /etc/apt/sources.list.d/unit.list
fi

# Install the NGINX repository
if [ ! -f /etc/apt/sources.list.d/nginx.list ]; then
  echo " Installing NGINX repository"
  curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
  echo "deb https://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" > /etc/apt/sources.list.d/nginx.list
fi

Усталёўка NGINX, NGINX Unit, PHP MariaDB, Certbot (Let's Encrypt) і іх залежнасцяў

Як толькі ўсе рэпазітары дададзены, абнаўляем метададзеныя і ўсталёўваны прыкладанні. Пакеты, якія ўсталёўваюцца скрыптам, таксама ўключаюць пашырэнні PHP, якія рэкамендуюцца пры запуску WordPress.org.

код скрыпту

echo " Updating repository metadata"
apt-get -qq update

# Install PHP with dependencies and NGINX Unit
echo " Installing PHP, NGINX Unit, NGINX, Certbot, and MariaDB"
apt-get -qq install -y --no-install-recommends 
  certbot 
  python3-certbot-nginx 
  php-cli 
  php-common 
  php-bcmath 
  php-curl 
  php-gd 
  php-imagick 
  php-mbstring 
  php-mysql 
  php-opcache 
  php-xml 
  php-zip 
  ghostscript 
  nginx 
  unit 
  unit-php 
  mariadb-server

Настройка PHP для выкарыстання з NGINX Unit і WordPress

Скрыпт стварае файл налад у каталогу conf.d. Тут задаецца максімальны памер загружаных файлаў для PHP, уключаецца выснова памылак PHP у STDERR, так што яны будуць запісаныя ў часопіс NGINX Unit, а таксама перазапускаецца NGINX Unit.

код скрыпту

# Find the major and minor PHP version so that we can write to its conf.d directory
PHP_MAJOR_MINOR_VERSION="$(php -v | head -n1 | cut -d' ' -f2 | cut -d'.' -f1,2)"

if [ ! -f "/etc/php/${PHP_MAJOR_MINOR_VERSION}/embed/conf.d/30-wordpress-overrides.ini" ]; then
  echo " Configuring PHP for use with NGINX Unit and WordPress"
  # Add PHP configuration overrides
  cat > "/etc/php/${PHP_MAJOR_MINOR_VERSION}/embed/conf.d/30-wordpress-overrides.ini" << EOM
; Set a larger maximum upload size so that WordPress can handle
; bigger media files.
upload_max_filesize=${UPLOAD_MAX_FILESIZE}
post_max_size=${UPLOAD_MAX_FILESIZE}
; Write error log to STDERR so that error messages show up in the NGINX Unit log
error_log=/dev/stderr
EOM
fi

# Restart NGINX Unit because we have reconfigured PHP
echo " Restarting NGINX Unit"
service unit restart

Заданне настроек базы дадзеных MariaDB для WordPress

Мы выбралі MariaDB замест MySQL, паколькі ў яе больш актыўнасць супольнасці, акрамя таго, яна, магчыма, дае больш высокую прадукцыйнасць па змаўчанні (верагодна, тут усё прасцей: каб паставіць MySQL, трэба дадаць яшчэ адзін рэпазітар, заўв. перакладчыка).

Скрыпт стварае новую базу дадзеных і стварае уліковыя дадзеныя для доступу WordPress праз інтэрфейс loopback:

код скрыпту

# Set up the WordPress database
echo " Configuring MariaDB for WordPress"
mysqladmin create wordpress || echo "Ignoring above error because database may already exist"
mysql -e "GRANT ALL PRIVILEGES ON wordpress.* TO "wordpress"@"localhost" IDENTIFIED BY "$WORDPRESS_DB_PASSWORD"; FLUSH PRIVILEGES;"

Устаноўка праграмы WordPress CLI

На гэтым кроку скрыпт усталёўвае праграму WP-CLI. З яго дапамогай можна ўсталяваць і кіраваць наладамі WordPress без неабходнасці ручной праўкі файлаў, абнаўленні базы ці ўваходу ў панэль кіравання. Таксама з яго дапамогай можна ўсталяваць тэмы і дадаткі і выканаць абнаўленне WordPress.

код скрыпту

if [ ! -f /usr/local/bin/wp ]; then
  # Install the WordPress CLI
  echo " Installing the WordPress CLI tool"
  curl --retry 6 -Ls "https://github.com/wp-cli/wp-cli/releases/download/v${WORDPRESS_CLI_VERSION}/wp-cli-${WORDPRESS_CLI_VERSION}.phar" > /usr/local/bin/wp
  echo "$WORDPRESS_CLI_MD5 /usr/local/bin/wp" | md5sum -c -
  chmod +x /usr/local/bin/wp
fi

Ўстаноўка і настройка WordPress

Скрыпт усталёўвае апошнюю версію WordPress у каталог /var/www/wordpress, а таксама змяняе налады:

  • Злучэнне з базай даных працуе праз unix domain socket замест TCP на loopback, каб скараціць трафік TCP.
  • WordPress дадае прэфікс https:// да URL, калі кліенты злучаюцца з NGINX па пратаколе HTTPS, а таксама адпраўляе выдалены hostname (як гэта дае NGINX) у PHP. Мы ўжываем кавалачак кода, каб гэта наладзіць.
  • WordPress трэба HTTPS для ўваходу
  • Структура URL па маўчанні грунтуецца на рэсурсах
  • Выстаўляюцца правільныя правы на файлавай сістэме для каталога WordPress.

код скрыпту

if [ ! -d /var/www/wordpress ]; then
  # Create WordPress directories
  mkdir -p /var/www/wordpress
  chown -R www-data:www-data /var/www

  # Download WordPress using the WordPress CLI
  echo " Installing WordPress"
  su -s /bin/sh -c 'wp --path=/var/www/wordpress core download' www-data

  WP_CONFIG_CREATE_CMD="wp --path=/var/www/wordpress config create --extra-php --dbname=wordpress --dbuser=wordpress --dbhost="localhost:/var/run/mysqld/mysqld.sock" --dbpass="${WORDPRESS_DB_PASSWORD}""

  # This snippet is injected into the wp-config.php file when it is created;
  # it informs WordPress that we are behind a reverse proxy and as such
  # allows it to generate links using HTTPS
  cat > /tmp/wp_forwarded_for.php << 'EOM'
/* Turn HTTPS 'on' if HTTP_X_FORWARDED_PROTO matches 'https' */
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
    $_SERVER['HTTPS'] = 'on';
}
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
EOM

  # Create WordPress configuration
  su -s /bin/sh -p -c "cat /tmp/wp_forwarded_for.php | ${WP_CONFIG_CREATE_CMD}" www-data
  rm /tmp/wp_forwarded_for.php
  su -s /bin/sh -p -c "wp --path=/var/www/wordpress config set 'FORCE_SSL_ADMIN' 'true'" www-data

  # Install WordPress
  WP_SITE_INSTALL_CMD="wp --path=/var/www/wordpress core install --url="${WORDPRESS_URL}" --title="${WORDPRESS_SITE_TITLE}" --admin_user="${WORDPRESS_ADMIN_USER}" --admin_password="${WORDPRESS_ADMIN_PASSWORD}" --admin_email="${WORDPRESS_ADMIN_EMAIL}" --skip-email"
  su -s /bin/sh -p -c "${WP_SITE_INSTALL_CMD}" www-data

  # Set permalink structure to a sensible default that isn't in the UI
  su -s /bin/sh -p -c "wp --path=/var/www/wordpress option update permalink_structure '/%year%/%monthnum%/%postname%/'" www-data

  # Remove sample file because it is cruft and could be a security problem
  rm /var/www/wordpress/wp-config-sample.php

  # Ensure that WordPress permissions are correct
  find /var/www/wordpress -type d -exec chmod g+s {} ;
  chmod g+w /var/www/wordpress/wp-content
  chmod -R g+w /var/www/wordpress/wp-content/themes
  chmod -R g+w /var/www/wordpress/wp-content/plugins
fi

Настройка NGINX Unit

Скрыпт наладжвае NGINX Unit для запуску PHP і апрацоўкі шляхоў WordPress, ізалюючы прастору імёнаў працэсаў PHP і аптымізуючы налады прадукцыйнасці. Тут ёсць тры функцыі, на якія варта звярнуць увагу:

  • Падтрымка прастор імёнаў вызначаецца па ўмове, заснаваная на праверцы запуску скрыпту ў кантэйнеры. Гэта трэба, паколькі большасць налад кантэйнераў не падтрымліваюць укладзены запуск кантэйнераў.
  • Калі ёсць падтрымка прастор імёнаў, адключаецца прастора імёнаў сетку. Гэта трэба, каб дазволіць WordPress адначасова падлучацца і да endpoints і быць даступным у інтэрнэце.
  • Максімальная колькасць працэсаў вызначаецца наступным чынам: (Даступная памяць для запушчаных MariaDB і NGINX Uniy)/(мяжа па аператыўнай памяці ў PHP + 5)
    Гэта значэнне ўстанаўліваецца ў настройках NGINX Unit.

Таксама гэтае значэнне мае на ўвазе, што заўсёды ёсць як мінімум два запушчаных працэсу PHP, што важна, паколькі WordPress робіць шмат асінхронных запытаў да самога сябе, а без дадатковых працэсаў запуск, да прыкладу, WP-Cron, зламаецца. Вы, магчыма, захочаце павялічыць або паменшыць гэтыя абмежаванні, грунтуючыся на вашых лакальных наладах, таму што створаныя наладкі тут - кансерватыўныя. На большасці вытворчых сістэм наладкі знаходзяцца паміж 10 і 100.

код скрыпту

if [ "${container:-unknown}" != "lxc" ] && [ "$(grep -m1 -a container=lxc /proc/1/environ | tr -d '')" == "" ]; then
  NAMESPACES='"namespaces": {
        "cgroup": true,
        "credential": true,
        "mount": true,
        "network": false,
        "pid": true,
        "uname": true
    }'
else
  NAMESPACES='"namespaces": {}'
fi

PHP_MEM_LIMIT="$(grep 'memory_limit' /etc/php/7.4/embed/php.ini | tr -d ' ' | cut -f2 -d= | numfmt --from=iec)"
AVAIL_MEM="$(grep MemAvailable /proc/meminfo | tr -d ' kB' | cut -f2 -d: | numfmt --from-unit=K)"
MAX_PHP_PROCESSES="$(echo "${AVAIL_MEM}/${PHP_MEM_LIMIT}+5" | bc)"
echo " Calculated the maximum number of PHP processes as ${MAX_PHP_PROCESSES}. You may want to tune this value due to variations in your configuration. It is not unusual to see values between 10-100 in production configurations."

echo " Configuring NGINX Unit to use PHP and WordPress"
cat > /tmp/wordpress.json << EOM
{
  "settings": {
    "http": {
      "header_read_timeout": 30,
      "body_read_timeout": 30,
      "send_timeout": 30,
      "idle_timeout": 180,
      "max_body_size": $(numfmt --from=iec ${UPLOAD_MAX_FILESIZE})
    }
  },
  "listeners": {
    "127.0.0.1:8080": {
      "pass": "routes/wordpress"
    }
  },
  "routes": {
    "wordpress": [
      {
        "match": {
          "uri": [
            "*.php",
            "*.php/*",
            "/wp-admin/"
          ]
        },
        "action": {
          "pass": "applications/wordpress/direct"
        }
      },
      {
        "action": {
          "share": "/var/www/wordpress",
          "fallback": {
            "pass": "applications/wordpress/index"
          }
        }
      }
    ]
  },
  "applications": {
    "wordpress": {
      "type": "php",
      "user": "www-data",
      "group": "www-data",
      "processes": {
        "max": ${MAX_PHP_PROCESSES},
        "spare": 1
      },
      "isolation": {
        ${NAMESPACES}
      },
      "targets": {
        "direct": {
          "root": "/var/www/wordpress/"
        },
        "index": {
          "root": "/var/www/wordpress/",
          "script": "index.php"
        }
      }
    }
  }
}
EOM

curl -X PUT --data-binary @/tmp/wordpress.json --unix-socket /run/control.unit.sock http://localhost/config

Настройка NGINX

Настройка асноўных параметраў NGINX

Скрыпт стварае каталог для кэша NGINX, а затым стварае асноўны файл наладкі nginx.conf. Звярніце ўвагу на колькасць працэсаў-апрацоўшчыкаў і заданне максімальнага памеру файла для загрузкі. Таксама ёсць радок, на якой падлучаецца файл налады сціску, вызначаны ў наступнай частцы, далей ідуць налады кэшавання.

код скрыпту

# Make directory for NGINX cache
mkdir -p /var/cache/nginx/proxy

echo " Configuring NGINX"
cat > ${NGINX_CONF_DIR}/nginx.conf << EOM
user nginx;
worker_processes auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       ${NGINX_CONF_DIR}/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    client_max_body_size ${UPLOAD_MAX_FILESIZE};
    keepalive_timeout  65;
    # gzip settings
    include ${NGINX_CONF_DIR}/gzip_compression.conf;
    # Cache settings
    proxy_cache_path /var/cache/nginx/proxy
        levels=1:2
        keys_zone=wp_cache:10m
        max_size=10g
        inactive=60m
        use_temp_path=off;
    include ${NGINX_CONF_DIR}/conf.d/*.conf;
}
EOM

Настройка сціску NGINX

Сціск змесціва на лета перад адпраўкай яго кліентам - выдатны спосаб паляпшэння прадукцыйнасці сайта, але толькі калі сціск наладжана правільна. Гэты раздзел скрыпту заснаваны на наладах адсюль.

код скрыпту

cat > ${NGINX_CONF_DIR}/gzip_compression.conf << 'EOM'
# Credit: https://github.com/h5bp/server-configs-nginx/
# ----------------------------------------------------------------------
# | Compression                                                        |
# ----------------------------------------------------------------------
# https://nginx.org/en/docs/http/ngx_http_gzip_module.html
# Enable gzip compression.
# Default: off
gzip on;
# Compression level (1-9).
# 5 is a perfect compromise between size and CPU usage, offering about 75%
# reduction for most ASCII files (almost identical to level 9).
# Default: 1
gzip_comp_level 6;
# Don't compress anything that's already small and unlikely to shrink much if at
# all (the default is 20 bytes, which is bad as that usually leads to larger
# files after gzipping).
# Default: 20
gzip_min_length 256;
# Compress data even for clients that are connecting to us via proxies,
# identified by the "Via" header (required for CloudFront).
# Default: off
gzip_proxied any;
# Tell proxies to cache both the gzipped and regular version of a resource
# whenever the client's Accept-Encoding capabilities header varies;
# Avoids the issue where a non-gzip capable client (which is extremely rare
# today) would display gibberish if their proxy gave them the gzipped version.
# Default: off
gzip_vary on;
# Compress all output labeled with one of the following MIME-types.
# `text/html` is always compressed by gzip module.
# Default: text/html
gzip_types
  application/atom+xml
  application/geo+json
  application/javascript
  application/x-javascript
  application/json
  application/ld+json
  application/manifest+json
  application/rdf+xml
  application/rss+xml
  application/vnd.ms-fontobject
  application/wasm
  application/x-web-app-manifest+json
  application/xhtml+xml
  application/xml
  font/eot
  font/otf
  font/ttf
  image/bmp
  image/svg+xml
  text/cache-manifest
  text/calendar
  text/css
  text/javascript
  text/markdown
  text/plain
  text/xml
  text/vcard
  text/vnd.rim.location.xloc
  text/vtt
  text/x-component
  text/x-cross-domain-policy;
EOM

Настройка NGINX для WordPress

Далей скрыпт стварае файл наладкі для WordPress default.conf у каталогу conf.d. Тут настройваецца:

  • Актывацыя сертыфікатаў TLS, атрыманых ад Let's Encrypt праз Certbot (яго настройка будзе ў наступным раздзеле)
  • Настройка параметраў бяспекі TLS, заснаваная на рэкамендацыях ад Let's Encrypt
  • Падключэнне кэшавання прапускаемых запытаў на 1 гадзіну па змаўчанні
  • Адключэнне часопісавання доступу, а таксама часопісавання памылак, калі файл не знойдзены, для двух агульных запытаных файлаў: favicon.ico і robots.txt
  • Забарона доступу да ўтоеных файлаў і некаторым файлам .php, каб прадухіліць нелегальны доступ або ненаўмысны запуск
  • Адключэнне часопісавання доступу для статыкі і файлаў шрыфтоў
  • Заданне загалоўка Access-Control-Allow-Origin для файлаў шрыфтоў
  • Даданне маршрутызацыі для index.php і іншай статыкі.

код скрыпту

cat > ${NGINX_CONF_DIR}/conf.d/default.conf << EOM
upstream unit_php_upstream {
    server 127.0.0.1:8080;
    keepalive 32;
}
server {
    listen 80;
    listen [::]:80;
    # ACME-challenge used by Certbot for Let's Encrypt
    location ^~ /.well-known/acme-challenge/ {
      root /var/www/certbot;
    }
    location / {
      return 301 https://${TLS_HOSTNAME}$request_uri;
    }
}
server {
    listen      443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ${TLS_HOSTNAME};
    root        /var/www/wordpress/;
    # Let's Encrypt configuration
    ssl_certificate         ${CERT_DIR}/fullchain.pem;
    ssl_certificate_key     ${CERT_DIR}/privkey.pem;
    ssl_trusted_certificate ${CERT_DIR}/chain.pem;
    include ${NGINX_CONF_DIR}/options-ssl-nginx.conf;
    ssl_dhparam ${NGINX_CONF_DIR}/ssl-dhparams.pem;
    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    # Proxy caching
    proxy_cache wp_cache;
    proxy_cache_valid 200 302 1h;
    proxy_cache_valid 404 1m;
    proxy_cache_revalidate on;
    proxy_cache_background_update on;
    proxy_cache_lock on;
    proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # Deny all attempts to access hidden files such as .htaccess, .htpasswd,
    # .DS_Store (Mac)
    # Keep logging the requests to parse later (or to pass to firewall utilities
    # such as fail2ban)
    location ~ /. {
        deny all;
    }
    # Deny access to any files with a .php extension in the uploads directory;
    # works in subdirectory installs and also in multi-site network.
    # Keep logging the requests to parse later (or to pass to firewall utilities
    # such as fail2ban).
    location ~* /(?:uploads|files)/.*.php$ {
        deny all;
    }
    # WordPress: deny access to wp-content, wp-includes PHP files
    location ~* ^/(?:wp-content|wp-includes)/.*.php$ {
        deny all;
    }
    # Deny public access to wp-config.php
    location ~* wp-config.php {
        deny all;
    }
    # Do not log access for static 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)$ {
        access_log off;
    }
    location ~* .(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
        add_header Access-Control-Allow-Origin "*";
        access_log off;
    }
    location / {
        try_files $uri @index_php;
    }
    location @index_php {
        proxy_socket_keepalive on;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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 Host $host;
        proxy_pass       http://unit_php_upstream;
    }
    location ~* .php$ {
        proxy_socket_keepalive on;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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 Host $host;
        try_files        $uri =404;
        proxy_pass       http://unit_php_upstream;
    }
}
EOM

Настройка Certbot для сертыфікатаў ад Let's Encrypt і іх аўтаматычнае падаўжэнне

Certbot - бясплатная прылада ад Electronic Frontier Foundation (EFF), з дапамогай якога можна атрымліваць і аўтаматычна абнаўляць сертыфікаты TLS ад Let's Encrypt. Скрыпт выконвае наступныя дзеянні, якія прыводзяць да налады Certbot для апрацоўкі сертыфікатаў ад Let's Encrypt у NGINX:

  • Спыняе NGINX
  • Спампоўвае рэкамендуемыя параметры TLS
  • Запускае Certbot, каб атрымаць сертыфікаты для сайта
  • Перазапускае NGINX для выкарыстання сертыфікатаў
  • Наладжвае штодзённы запуск Certbot у 3:24 ночы для праверкі неабходнасці абнаўлення сертыфікатаў, а таксама, пры неабходнасці, спампоўкі новых сертыфікатаў і перазагрузкі NGINX.

код скрыпту

echo " Stopping NGINX in order to set up Let's Encrypt"
service nginx stop

mkdir -p /var/www/certbot
chown www-data:www-data /var/www/certbot
chmod g+s /var/www/certbot

if [ ! -f ${NGINX_CONF_DIR}/options-ssl-nginx.conf ]; then
  echo " Downloading recommended TLS parameters"
  curl --retry 6 -Ls -z "Tue, 14 Apr 2020 16:36:07 GMT" 
    -o "${NGINX_CONF_DIR}/options-ssl-nginx.conf" 
    "https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf" 
    || echo "Couldn't download latest options-ssl-nginx.conf"
fi

if [ ! -f ${NGINX_CONF_DIR}/ssl-dhparams.pem ]; then
  echo " Downloading recommended TLS DH parameters"
  curl --retry 6 -Ls -z "Tue, 14 Apr 2020 16:49:18 GMT" 
    -o "${NGINX_CONF_DIR}/ssl-dhparams.pem" 
    "https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem" 
    || echo "Couldn't download latest ssl-dhparams.pem"
fi

# If tls_certs_init.sh hasn't been run before, remove the self-signed certs
if [ ! -d "/etc/letsencrypt/accounts" ]; then
  echo " Removing self-signed certificates"
  rm -rf "${CERT_DIR}"
fi

if [ "" = "${LETS_ENCRYPT_STAGING:-}" ] || [ "0" = "${LETS_ENCRYPT_STAGING}" ]; then
  CERTBOT_STAGING_FLAG=""
else
  CERTBOT_STAGING_FLAG="--staging"
fi

if [ ! -f "${CERT_DIR}/fullchain.pem" ]; then
  echo " Generating certificates with Let's Encrypt"
  certbot certonly --standalone 
         -m "${WORDPRESS_ADMIN_EMAIL}" 
         ${CERTBOT_STAGING_FLAG} 
         --agree-tos --force-renewal --non-interactive 
         -d "${TLS_HOSTNAME}"
fi

echo " Starting NGINX in order to use new configuration"
service nginx start

# Write crontab for periodic Let's Encrypt cert renewal
if [ "$(crontab -l | grep -m1 'certbot renew')" == "" ]; then
  echo " Adding certbot to crontab for automatic Let's Encrypt renewal"
  (crontab -l 2>/dev/null; echo "24 3 * * * certbot renew --nginx --post-hook 'service nginx reload'") | crontab -
fi

Дадатковая настройка вашага сайта

Мы вышэй распавялі пра тое, як наш скрыпт настройвае NGINX і NGINX Unit для абслугоўвання гатовага да прамысловай працы сайта з уключаным TLSSSL. Вы можаце таксама, у залежнасці ад вашых патрэб, дадаць у будучыні:

Для яшчэ больш лепшай прадукцыйнасці сайта мы рэкамендуем абнавіцца да NGINX Plus, наш камерцыйны прадукт карпаратыўнага ўзроўню, заснаваны на NGINX c адкрытым зыходным кодам. Яго падпісчыкі атрымаюць модуль Brotli, які дынамічна загружаецца, а таксама (за дадатковую аплату) NGINX ModSecurity WAF. Мы таксама прапануем NGINX App Protect, модуль WAF для NGINX Plus, заснаваны на тэхналогіі, якая вядзе ў галіне бяспекі, ад F5.

NB За падтрымкай высоканагружанага сайта вы можаце звярнуцца да спецыялістаў Саўджыдж. Забяспечым хуткую і надзейную працу вашага сайта ці сэрвісу пад любой нагрузкай.

Крыніца: habr.com