Tự động cài đặt WordPress với NGINX Unit và Ubuntu

Tự động cài đặt WordPress với NGINX Unit và Ubuntu

Có rất nhiều hướng dẫn về cách cài đặt WordPress, tìm kiếm "WordPress install" trên Google sẽ cho ra khoảng nửa triệu kết quả. Tuy nhiên, trên thực tế, có rất ít hướng dẫn tốt trong số đó, theo đó bạn có thể cài đặt và định cấu hình WordPress và hệ điều hành cơ bản để chúng có khả năng hỗ trợ trong thời gian dài. Có lẽ các cài đặt chính xác phụ thuộc nhiều vào các nhu cầu cụ thể hoặc điều này là do phần giải thích chi tiết khiến bài viết khó đọc.

Trong bài viết này, chúng tôi sẽ cố gắng kết hợp những gì tốt nhất của cả hai thế giới bằng cách cung cấp một tập lệnh bash để tự động cài đặt WordPress trên Ubuntu, cũng như xem qua nó, giải thích chức năng của từng phần, cũng như những thỏa hiệp mà chúng tôi đã thực hiện khi phát triển nó . Nếu bạn là người dùng nâng cao, bạn có thể bỏ qua nội dung của bài viết và chỉ lấy kịch bản để sửa đổi và sử dụng trong môi trường của bạn. Đầu ra của tập lệnh là một bản cài đặt WordPress tùy chỉnh có hỗ trợ Lets Encrypt, chạy trên NGINX Unit và phù hợp để sử dụng trong sản xuất.

Kiến trúc được phát triển để triển khai WordPress bằng Đơn vị NGINX được mô tả trong bài viết cũ hơn, bây giờ chúng ta cũng sẽ cấu hình thêm những thứ chưa được đề cập ở đó (như trong nhiều hướng dẫn khác):

  • CLI WordPress
  • Hãy mã hóa và chứng chỉ TLSSSL
  • Tự động gia hạn chứng chỉ
  • Bộ nhớ đệm NGINX
  • Nén NGINX
  • Hỗ trợ HTTPS và HTTP/2
  • Tự động hóa quá trình

Bài viết sẽ mô tả quá trình cài đặt trên một máy chủ, máy chủ này sẽ lưu trữ đồng thời máy chủ xử lý tĩnh, máy chủ xử lý PHP và cơ sở dữ liệu. Một cài đặt hỗ trợ nhiều dịch vụ và máy chủ ảo là một chủ đề tiềm năng cho tương lai. Nếu bạn muốn chúng tôi viết về điều gì đó không có trong các bài viết này, hãy viết trong phần bình luận.

Yêu cầu

  • Máy chủ vùng chứa (LXC hoặc Lxd), máy ảo hoặc máy chủ sắt thông thường có ít nhất 512 MB RAM và cài đặt Ubuntu 18.04 trở lên.
  • Cổng truy cập Internet 80 và 443
  • Tên miền được liên kết với địa chỉ ip công khai của máy chủ này
  • Quyền truy cập gốc (sudo).

Tổng quan về kiến ​​trúc

Kiến trúc giống như mô tả sớm hơn, một ứng dụng web ba tầng. Nó bao gồm các tập lệnh PHP chạy trên công cụ PHP và các tệp tĩnh được xử lý bởi máy chủ web.

Tự động cài đặt WordPress với NGINX Unit và Ubuntu

Nguyên tắc chung

  • Nhiều lệnh cấu hình trong một tập lệnh được bao bọc trong các điều kiện if cho tính bình thường: tập lệnh có thể được chạy nhiều lần mà không có nguy cơ thay đổi các cài đặt đã có sẵn.
  • Tập lệnh cố gắng cài đặt phần mềm từ các kho lưu trữ, vì vậy bạn có thể áp dụng các bản cập nhật hệ thống trong một lệnh (apt upgrade cho Ubuntu).
  • Các lệnh cố gắng phát hiện rằng chúng đang chạy trong một vùng chứa để chúng có thể thay đổi cài đặt của chúng cho phù hợp.
  • Để đặt số lượng quy trình luồng bắt đầu trong cài đặt, tập lệnh sẽ cố gắng đoán cài đặt tự động để hoạt động trong vùng chứa, máy ảo và máy chủ phần cứng.
  • Khi mô tả cài đặt, trước hết chúng tôi luôn nghĩ đến tự động hóa, điều mà chúng tôi hy vọng sẽ trở thành cơ sở để tạo cơ sở hạ tầng của riêng bạn dưới dạng mã.
  • Tất cả các lệnh được chạy với tư cách người dùng nguồn gốc, bởi vì họ thay đổi cài đặt hệ thống cơ bản, nhưng WordPress trực tiếp chạy như một người dùng thông thường.

Đặt biến môi trường

Đặt các biến môi trường sau trước khi chạy tập lệnh:

  • WORDPRESS_DB_PASSWORD - Mật khẩu cơ sở dữ liệu WordPress
  • WORDPRESS_ADMIN_USER - Tên quản trị viên WordPress
  • WORDPRESS_ADMIN_PASSWORD - Mật khẩu quản trị WordPress
  • WORDPRESS_ADMIN_EMAIL - Email quản trị viên WordPress
  • WORDPRESS_URL là URL đầy đủ của trang web WordPress, bắt đầu từ https://.
  • LETS_ENCRYPT_STAGING - trống theo mặc định, nhưng bằng cách đặt giá trị thành 1, bạn sẽ sử dụng các máy chủ phân tầng Let's Encrypt, cần thiết cho các chứng chỉ yêu cầu thường xuyên khi kiểm tra cài đặt của bạn, nếu không, Let's Encrypt có thể tạm thời chặn địa chỉ ip của bạn do một số lượng lớn yêu cầu .

Tập lệnh kiểm tra xem các biến liên quan đến WordPress này đã được đặt chưa và thoát nếu không.
Các dòng script 572-576 kiểm tra giá trị LETS_ENCRYPT_STAGING.

Đặt biến môi trường dẫn xuất

Tập lệnh trên các dòng 55-61 đặt các biến môi trường sau, thành một số giá trị được mã hóa cứng hoặc sử dụng giá trị thu được từ các biến được đặt trong phần trước:

  • DEBIAN_FRONTEND="noninteractive" - Thông báo cho các ứng dụng rằng chúng đang chạy trong một tập lệnh và không có khả năng tương tác với người dùng.
  • WORDPRESS_CLI_VERSION="2.4.0" là phiên bản của ứng dụng WordPress CLI.
  • WORDPRESS_CLI_MD5= "dedd5a662b80cda66e9e25d44c23b25c" — tổng kiểm tra tệp thực thi WordPress CLI 2.4.0 (phiên bản được chỉ định trong biến WORDPRESS_CLI_VERSION). Tập lệnh trên dòng 162 sử dụng giá trị này để kiểm tra xem tệp WordPress CLI chính xác đã được tải xuống chưa.
  • UPLOAD_MAX_FILESIZE="16M" - kích thước tệp tối đa có thể được tải lên trong WordPress. Cài đặt này được sử dụng ở một số nơi, vì vậy việc đặt cài đặt này ở một nơi sẽ dễ dàng hơn.
  • TLS_HOSTNAME= "$(echo ${WORDPRESS_URL} | cut -d'/' -f3)" - tên máy của hệ thống, lấy từ biến WORDPRESS_URL. Được sử dụng để lấy chứng chỉ TLS/SSL thích hợp từ Let's Encrypt cũng như xác minh WordPress nội bộ.
  • NGINX_CONF_DIR="/etc/nginx" - đường dẫn đến thư mục có cài đặt NGINX, bao gồm tệp chính nginx.conf.
  • CERT_DIR="/etc/letsencrypt/live/${TLS_HOSTNAME}" — đường dẫn đến chứng chỉ Let's Encrypt cho trang web WordPress, thu được từ biến TLS_HOSTNAME.

Gán tên máy chủ cho máy chủ WordPress

Tập lệnh đặt tên máy chủ của máy chủ khớp với tên miền của trang web. Điều này là không bắt buộc, nhưng sẽ thuận tiện hơn khi gửi thư đi qua SMTP khi thiết lập một máy chủ duy nhất, như được cấu hình bởi tập lệnh.

mã kịch bản

# 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

Thêm tên máy chủ vào/etc/hosts

Ngoài ra WP-Cron dùng để chạy các tác vụ định kỳ, yêu cầu WordPress có thể tự truy cập thông qua HTTP. Để đảm bảo WP-Cron hoạt động chính xác trên mọi môi trường, tập lệnh sẽ thêm một dòng vào tệp / Etc / hostsđể WordPress có thể tự truy cập thông qua giao diện loopback:

mã kịch bản

# 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

Cài đặt các công cụ cần thiết cho các bước tiếp theo

Phần còn lại của tập lệnh cần một số chương trình và giả định rằng các kho lưu trữ đã được cập nhật. Chúng tôi cập nhật danh sách các kho lưu trữ, sau đó chúng tôi cài đặt các công cụ cần thiết:

mã kịch bản

# 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

Thêm đơn vị NGINX và kho lưu trữ NGINX

Tập lệnh cài đặt NGINX Unit và NGINX mã nguồn mở từ kho NGINX chính thức để đảm bảo các phiên bản có bản vá bảo mật và bản sửa lỗi mới nhất được sử dụng.

Tập lệnh thêm kho lưu trữ NGINX Unit và sau đó là kho lưu trữ NGINX, thêm khóa kho lưu trữ và các tệp cấu hình apt, xác định quyền truy cập vào kho thông qua Internet.

Quá trình cài đặt thực sự của NGINX Unit và NGINX diễn ra trong phần tiếp theo. Chúng tôi thêm trước các kho lưu trữ để không phải cập nhật siêu dữ liệu nhiều lần, giúp cài đặt nhanh hơn.

mã kịch bản

# 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

Cài đặt NGINX, NGINX Unit, PHP MariaDB, Certbot (Let's Encrypt) và các phụ thuộc của chúng

Sau khi tất cả các kho lưu trữ được thêm vào, hãy cập nhật siêu dữ liệu và cài đặt các ứng dụng. Các gói được cài đặt bởi tập lệnh cũng bao gồm các tiện ích mở rộng PHP được đề xuất khi chạy WordPress.org

mã kịch bản

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

Thiết lập PHP để sử dụng với NGINX Unit và WordPress

Tập lệnh tạo tệp cài đặt trong thư mục conf.d. Thao tác này đặt kích thước tối đa cho các tệp tải lên PHP, bật đầu ra lỗi PHP thành STDERR để chúng sẽ được ghi vào nhật ký Đơn vị NGINX và khởi động lại Đơn vị NGINX.

mã kịch bản

# 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

Chỉ định cài đặt cơ sở dữ liệu MariaDB cho WordPress

Chúng tôi đã chọn MariaDB thay vì MySQL vì nó có nhiều hoạt động cộng đồng hơn và cũng có khả năng cung cấp hiệu suất tốt hơn theo mặc định (có lẽ, mọi thứ đơn giản hơn ở đây: để cài đặt MySQL, bạn cần thêm một kho lưu trữ khác, xấp xỉ. dịch giả).

Tập lệnh tạo cơ sở dữ liệu mới và tạo thông tin đăng nhập để truy cập WordPress thông qua giao diện loopback:

mã kịch bản

# 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;"

Cài đặt chương trình WordPress CLI

Ở bước này, kịch bản cài đặt chương trình WP-CLI. Với nó, bạn có thể cài đặt và quản lý cài đặt WordPress mà không phải chỉnh sửa tệp theo cách thủ công, cập nhật cơ sở dữ liệu hoặc vào bảng điều khiển. Nó cũng có thể được sử dụng để cài đặt các chủ đề và tiện ích bổ sung cũng như cập nhật WordPress.

mã kịch bản

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

Cài đặt và cấu hình WordPress

Tập lệnh cài đặt phiên bản WordPress mới nhất trong một thư mục /var/www/wordpressvà cũng thay đổi cài đặt:

  • Kết nối cơ sở dữ liệu hoạt động trên ổ cắm tên miền unix thay vì TCP trên loopback để cắt giảm lưu lượng TCP.
  • WordPress thêm một tiền tố https:// tới URL nếu máy khách kết nối với NGINX qua HTTPS và cũng gửi tên máy chủ từ xa (do NGINX cung cấp) tới PHP. Chúng tôi sử dụng một đoạn mã để thiết lập điều này.
  • WordPress cần HTTPS để đăng nhập
  • Cấu trúc URL mặc định dựa trên tài nguyên
  • Đặt quyền chính xác trên hệ thống tệp cho thư mục WordPress.

mã kịch bản

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

Thiết lập đơn vị NGINX

Tập lệnh định cấu hình Đơn vị NGINX để chạy PHP và xử lý các đường dẫn WordPress, cách ly không gian tên quy trình PHP và tối ưu hóa cài đặt hiệu suất. Có ba tính năng cần chú ý ở đây:

  • Hỗ trợ cho các không gian tên được xác định theo điều kiện, dựa trên việc kiểm tra xem tập lệnh có đang chạy trong vùng chứa hay không. Điều này là cần thiết vì hầu hết các thiết lập vùng chứa không hỗ trợ khởi chạy các vùng chứa lồng nhau.
  • Nếu có hỗ trợ cho không gian tên, hãy tắt không gian tên mạng. Điều này cho phép WordPress kết nối với cả hai điểm cuối và có sẵn trên web cùng một lúc.
  • Số lượng quy trình tối đa được xác định như sau: (Bộ nhớ khả dụng để chạy MariaDB và NGINX Uniy)/(giới hạn RAM trong PHP + 5)
    Giá trị này được đặt trong cài đặt Đơn vị NGINX.

Giá trị này cũng ngụ ý rằng luôn có ít nhất hai quy trình PHP đang chạy, điều này rất quan trọng vì WordPress tạo ra rất nhiều yêu cầu không đồng bộ cho chính nó và nếu không có các quy trình bổ sung, việc chạy, chẳng hạn như WP-Cron sẽ bị hỏng. Bạn có thể muốn tăng hoặc giảm các giới hạn này dựa trên cài đặt cục bộ của mình, vì cài đặt được tạo ở đây mang tính bảo thủ. Trên hầu hết các hệ thống sản xuất, cài đặt nằm trong khoảng từ 10 đến 100.

mã kịch bản

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

Thiết lập NGINX

Định cấu hình cài đặt NGINX cơ bản

Tập lệnh tạo một thư mục cho bộ đệm NGINX và sau đó tạo tệp cấu hình chính nginx.conf. Hãy chú ý đến số lượng quy trình xử lý và cài đặt kích thước tệp tối đa để tải lên. Ngoài ra còn có một dòng bao gồm tệp cài đặt nén được xác định trong phần tiếp theo, tiếp theo là cài đặt bộ nhớ đệm.

mã kịch bản

# 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

Thiết lập nén NGINX

Nén nhanh nội dung trước khi gửi cho khách hàng là một cách tuyệt vời để cải thiện hiệu suất trang web, nhưng chỉ khi quá trình nén được định cấu hình chính xác. Phần này của tập lệnh dựa trên cài đặt do đó.

mã kịch bản

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

Thiết lập NGINX cho WordPress

Tiếp theo, tập lệnh tạo tệp cấu hình cho WordPress mặc định.conf trong danh mục conf.d. Nó được cấu hình ở đây:

  • Kích hoạt chứng chỉ TLS nhận được từ Let's Encrypt thông qua Certbot (việc thiết lập sẽ có trong phần tiếp theo)
  • Định cấu hình cài đặt bảo mật TLS dựa trên các đề xuất từ ​​Let's Encrypt
  • Bật yêu cầu bỏ qua bộ nhớ đệm trong 1 giờ theo mặc định
  • Vô hiệu hóa ghi nhật ký truy cập, cũng như ghi nhật ký lỗi nếu không tìm thấy tệp, đối với hai tệp được yêu cầu phổ biến: favicon.ico và robots.txt
  • Ngăn truy cập vào các tệp ẩn và một số tệp Php.để ngăn chặn truy cập bất hợp pháp hoặc bắt đầu ngoài ý muốn
  • Vô hiệu hóa ghi nhật ký truy cập cho các tệp tĩnh và phông chữ
  • Cài đặt tiêu đề Kiểm soát truy cập-Cho phép-Xuất xứ cho các tập tin phông chữ
  • Thêm định tuyến cho index.php và các số liệu thống kê khác.

mã kịch bản

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

Thiết lập Certbot cho các chứng chỉ từ Let's Encrypt và tự động gia hạn chúng

certbot là một công cụ miễn phí từ Electronic Frontier Foundation (EFF) cho phép bạn lấy và tự động gia hạn chứng chỉ TLS từ Let's Encrypt. Tập lệnh thực hiện như sau để định cấu hình Certbot xử lý chứng chỉ từ Let's Encrypt trong NGINX:

  • Ngừng NGINX
  • Tải xuống cài đặt TLS được đề xuất
  • Chạy Certbot để nhận chứng chỉ cho trang web
  • Khởi động lại NGINX để sử dụng chứng chỉ
  • Định cấu hình Certbot để chạy hàng ngày lúc 3:24 sáng để kiểm tra xem các chứng chỉ có cần được gia hạn hay không và nếu cần, hãy tải xuống các chứng chỉ mới và khởi động lại NGINX.

mã kịch bản

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

Tùy chỉnh bổ sung cho trang web của bạn

Chúng tôi đã nói ở trên về cách tập lệnh của chúng tôi định cấu hình NGINX và NGINX Unit để phục vụ một trang web sẵn sàng sản xuất có bật TLSSSL. Bạn cũng có thể, tùy thuộc vào nhu cầu của mình, thêm vào trong tương lai:

  • Hỗ trợ Brotli, cải thiện khả năng nén nhanh chóng qua HTTPS
  • ModSecurity с quy tắc cho wordpressđể ngăn chặn các cuộc tấn công tự động trên trang web của bạn
  • Sao lưu cho WordPress phù hợp với bạn
  • Sự bảo vệ thông qua AppArmor (trên Ubuntu)
  • Postfix hoặc msmtp để WordPress có thể gửi thư
  • Kiểm tra trang web của bạn để bạn biết nó có thể xử lý bao nhiêu lưu lượng truy cập

Để có hiệu suất trang web tốt hơn nữa, chúng tôi khuyên bạn nên nâng cấp lên NGINX Plus, sản phẩm cấp doanh nghiệp, thương mại của chúng tôi dựa trên NGINX mã nguồn mở. Những người đăng ký của nó sẽ nhận được một mô-đun Brotli được tải động, cũng như (với một khoản phí bổ sung) NGINX ModSecurity WAF. chúng tôi cũng cung cấp Bảo vệ ứng dụng NGINX, một mô-đun WAF cho NGINX Plus dựa trên công nghệ bảo mật hàng đầu trong ngành từ F5.

NB Để được hỗ trợ về một trang web được tải cao, bạn có thể liên hệ với các chuyên gia Cầu nam. Chúng tôi sẽ đảm bảo hoạt động nhanh chóng và đáng tin cậy của trang web hoặc dịch vụ của bạn dưới bất kỳ tải trọng nào.

Nguồn: www.habr.com