Hướng dẫn biên dịch và cấu hình NginX trên Ubuntu Server

T.V.T Marine Automation Company Limited, David Tran

Chú ý: Bài viết này được thực hiện cách đây nhiều năm và đã lỗi thời. Vui lòng đọc hướng dẫn mới nhất cho việc Biên dịch Nginx cho Ubuntu 22.04

Các đây ít lâu, tôi có viết một bài hướng dẫn Cài đặt NginX phiên bản mới nhất cho Ubuntu Server bằng phương pháp apt-get. Ưu điểm của phương pháp này là nhanh chóng, thuận tiện nhưng nhược điểm là chúng ta khó kiểm soát tính năng cũng như khả năng hoạt động ổn định rất thấp, chỉ phù hợp với môi trường kiểm thử (test) hoặc phát triển (development). Do đó, hôm nay tôi giới thiệu phương pháp biên dịch NginX từ mã nguồn.

Ưu điểm của phương pháp này là:

  1. Giúp chúng ta hiểu hơn về NginX nhờ quá trình biên dịch và cấu hình
  2. Chúng ta có thể cài những module mà mình mong muốn, do đó, giảm được việc tiêu thụ tài nguyên một cách không cần thiết cũng như giảm bề mặt lỗi và bền mặt an ninh của bản thân NginX.
  3. Hệ thống hoạt động cực nhanh và ổn định do đó rất phù hợp với các môi trường hoạt động thực sự (production environment) đòi hỏi tính ổn định cao cũng như các yêu cầu khắt khe về tiêu thụ tài nguyên và tính bảo mật

Trong phạm vi hướng dẫn này, tôi giả định:

  • Bạn đã có bản cài mới Ubuntu Server 12.04 LTS (download tại đây). Tuy nhiên, bạn có thể sử dụng phiên bản server khác (bao gồm cả các Linux distro khác như CentOS, RedHat Linux, v.v.). Trong trường đó, dĩ nhiên, các bước làm dưới đây sẽ không thể áp dụng tuyệt đối.
  • Bạn chưa cài đặt NginX. Nếu trước đây bạn đã cài rồi và cài bằng phương pháp sudo apt-get install nginx thì có thể gỡ ra bằng lệnh sudo apt-get remove nginx
  • Mã nguồn NginX download về sẽ được lưu trong thư mục /usr/src để phục vụ cho việc bảo trì trong tương lai

Hướng dẫn biên dịch NginX

Cài trình biên dịch và các gói phần mềm cần thiết để phục vụ quá trình biên dịch

sudo apt-get install build-essential libssl-dev libpcre3 libpcre3-dev \
libxml2-dev libxslt1-dev libgd2-xpm-dev libgeoip-dev libperl-dev

 Tải về mã nguồn của NginX (bản ổn định mới nhất tại thời điểm viết bài này có phiên bản 1.4.2)

sudo su
cd /usr/src
wget http://nginx.org/download/nginx-1.4.2.tar.gz

 Giải nén và chuyển đến thư mục vừa giải nén

tar xvfz nginx-1.4.2.tar.gz
cd nginx-1.4.2.tar.gz

 Cấu hình các thông số biên dịch để chuẩn bị cho việc biên dịch bằng lệnh configure như sau: (lưu ý, để biết các option của lệnh này, bạn có thể thực thi command ./configure --help)

./configure \
--prefix=/usr/local/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-client-body-temp-path=/var/lib/nginx/body \
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
--http-log-path=/var/log/nginx/access.log \
--http-proxy-temp-path=/var/lib/nginx/proxy \
--http-scgi-temp-path=/var/lib/nginx/scgi \
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
--lock-path=/var/lock/nginx.lock \
--pid-path=/var/run/nginx.pid \
--with-pcre-jit \
--with-debug \
--with-http_addition_module \
--with-http_dav_module \
--with-http_geoip_module \
--with-http_gzip_static_module \
--with-http_image_filter_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_sub_module \
--with-http_xslt_module \
--with-ipv6 \
--with-mail \
--with-mail_ssl_module \
--with-http_spdy_module

 Kết quả output ra terminal có thể trông như sau:

Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + md5: using OpenSSL library
  + sha1: using OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx configuration prefix: "/etc/nginx"
  nginx configuration file: "/etc/nginx/nginx.conf"
  nginx pid file: "/var/run/nginx.pid"
  nginx error log file: "/var/log/nginx/error.log"
  nginx http access log file: "/var/log/nginx/access.log"
  nginx http client request body temporary files: "/var/lib/nginx/body"
  nginx http proxy temporary files: "/var/lib/nginx/proxy"
  nginx http fastcgi temporary files: "/var/lib/nginx/fastcgi"
  nginx http uwsgi temporary files: "/var/lib/nginx/uwsgi"
  nginx http scgi temporary files: "/var/lib/nginx/scgi"

 Tạo các thư mục tạm (temporary directories) phục vụ cho NginX

mkdir -p /var/lib/nginx/body
mkdir /var/lib/nginx/proxy
mkdir /var/lib/nginx/fastcgi
mkdir /var/lib/nginx/uwsgi
mkdir /var/lib/nginx/scgi

Đến đây, chúng ta bắt đầu tiến hành biên dịch và cài đặt bằng các lệnh sau:

make
make install

 Lúc này, NginX 1.4.2 sẽ được cài đặt với các thông số như ở phần output sau khi chạy lệnh configure

Cấu hình và khởi chạy NginX

Tạo một tài khoản có tên nginx kiểu system với thư mục home là /var/www để thực thi NginX

adduser --system --home=/var/www/ \
--disabled-login \
--disabled-password \
--group nginx

Ghi chú:

  • tôi sử dụng tham số disable-login để ngăn ngừa việc đăng nhập bằng tài khoản này
  • tôi sử dụng tham số disable-password để loại bỏ password

Di chuyển đến thư mục chứa các tập tin cấu hình của NginX

cd /etc/nginx

 Cấu hình NginX bằng việc chỉnh sửa tập tin cấu hình chính như sau

nano nginx.conf

Đổi user từ nobody thành nginx vừa tạo bên trên bằng cách đổi #user nobody; thành #user nginx;

Nếu server của bạn có nhiều hơn 1 nhân thì có thể tối ưu NginX để tận dụng được hết sức mạnh CPU bằng chỉ mục worker_connection = xx trong đó, xx là số nhân mà server bạn có.

Bổ sung nội dung sau vào bên trong http block

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;

Lưu lại các thay đổi.

Tạo biến môi trường để bạn có thể gọi nginx mà không cần phải gõ đường dẫn đầy đủ:

sh -c "echo 'PATH=/usr/local/nginx/sbin:\$PATH' > /etc/profile.d/nginx.sh"
sh -c "echo 'export PATH' >> /etc/profile.d/nginx.sh"
ldconfig /usr/local/nginx/sbin/

 Tạo thư mục lưu trữ các tập tin cấu hình virtual host

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

 Tạo init script để nginx tự khởi chạy khi start server

 Tạo một tập tin có tên nginx trong thư mục /etc/init.d với nội dung như sau

#!/bin/sh
### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $network $remote_fs $local_fs 
# Required-Stop:     $network $remote_fs $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Stop/start nginx
### END INIT INFO

# Author: Sergey Budnevitch 

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC=nginx
NAME=nginx
CONFFILE=/etc/nginx/nginx.conf
#DAEMON=/usr/sbin/nginx
DAEMON=/usr/local/nginx/sbin/nginx
DAEMON_ARGS="-c $CONFFILE"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

[ -x $DAEMON ] || exit 0

[ -r /etc/default/$NAME ] && . /etc/default/$NAME

. /lib/init/vars.sh

. /lib/lsb/init-functions

do_start()
{
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
        $DAEMON_ARGS
    RETVAL="$?"
    return "$RETVAL"
}

do_stop()
{
    # Return
    #   0 if daemon has been stopped
    #   1 if daemon was already stopped
    #   2 if daemon could not be stopped
    #   other if a failure occurred
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
    RETVAL="$?"
    rm -f $PIDFILE
    return "$RETVAL"
}

do_reload() {
    #
    start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE --name $NAME
    RETVAL="$?"
    return "$RETVAL"
}

do_configtest() {
    if [ "$#" -ne 0 ]; then
        case "$1" in
            -q)
                FLAG=$1
                ;;
            *)
                ;;
        esac
        shift
    fi
    $DAEMON -t $FLAG -c $CONFFILE
    RETVAL="$?"
    return $RETVAL
}

do_upgrade() {
    OLDBINPIDFILE=$PIDFILE.oldbin

    do_configtest -q || return 6
    start-stop-daemon --stop --signal USR2 --quiet --pidfile $PIDFILE --name $NAME
    RETVAL="$?"
    sleep 1
    if [ -f $OLDBINPIDFILE -a -f $PIDFILE ]; then
        start-stop-daemon --stop --signal QUIT --quiet --pidfile $OLDBINPIDFILE --name $NAME
        RETVAL="$?"
    else
        echo $"Upgrade failed!"
        RETVAL=1
        return $RETVAL
    fi
}

case "$1" in
    start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
        do_start
        case "$?" in
            0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
            2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
    stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
            0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
            2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  status)
        status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
        ;;
  configtest)
        do_configtest
        ;;
  upgrade)
        do_upgrade
        ;;
  reload|force-reload)
        log_daemon_msg "Reloading $DESC" "$NAME"
        do_reload
        log_end_msg $?
        ;;
  restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_configtest -q || exit $RETVAL
        do_stop
        case "$?" in
            0|1)
                do_start
                case "$?" in
                    0) log_end_msg 0 ;;
                    1) log_end_msg 1 ;; # Old process is still running
                    *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
            *)
                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
    *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload|upgrade|configtest}" >&2
        exit 3
        ;;
esac

exit $RETVAL

Phân quyền thực thi cho tập tin này bằng lệnh

sudo chmod +x /etc/init.d/nginx

Thiết lập service tự khởi chạy khi start server

sudo update-rc.d nginx defaults

Đến đây, bạn đã hoàn thành việc biên dịch, cài đặt và cấu hình (cơ bản) cho nginx. Bạn có thể khởi động lại server và bắt đầu sử dụng/tạo vhosts, v.v.

Mọi thắc mắc, xin comment tại đây. Chúc vui!