Compile Nginx on ubuntu 18.04 LTS with PHP 7

Well, here is my setup of Ubuntu 18.04 + NGINX + PHP7-FPM, most part of the following content I referred comes from https://www.howtoforge.com/tutorial/how-to-build-nginx-from-source-on-ubuntu-1804-lts/. And I've just made some substantial changes. Massive thanks to the original author.

0. If the server is located in China, you may consider use TUNA mirror

sudo sed -i 's/cn.archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list

1. update the apt repo and upgrade system packages

sudo apt-get update
sudo apt-get upgrade

2. Massive dependencies

sudo apt-get install -y software-properties-common \
    wget curl build-essential git libpcre3-dev zlib1g-dev \
    libgd3 libgd-dev libgeoip1 libgeoip-dev geoip-bin \
    libxml2 libxml2-dev libxslt1.1 libxslt1-dev

3. Find out the following packages' version

i) Nginx, http://nginx.org/en/download.html

ii) PCRE, https://ftp.pcre.org/pub/pcre/

iii) ZLIB, https://www.zlib.net

iv) OpenSSL, https://www.openssl.org/source/

At the time of writing, we have

Nginx: 1.17.2

PCRE: 8.43

ZLIB: 1.2.11

OpenSSL: 1.1.1c

4. Download aforementioned packages

NGINX_VER=1.17.2
PCRE_VER=8.43
ZLIB_VER=1.2.11
OPENSSL_VER=1.1.1c

wget http://nginx.org/download/nginx-${NGINX_VER}.tar.gz && \
    tar xf nginx-\${NGINX_VER}.tar.gz

wget https://ftp.pcre.org/pub/pcre/pcre-${PCRE_VER}.tar.gz && \
    tar xf pcre-\${PCRE_VER}.tar.gz

wget https://www.zlib.net/zlib-${ZLIB_VER}.tar.gz && \
    tar xf zlib-\${ZLIB_VER}.tar.gz

wget https://www.openssl.org/source/openssl-${OPENSSL_VER}.tar.gz && \
    tar xf openssl-\${OPENSSL_VER}.tar.gz

5. Configure, Compile and Install Nginx

cd nginx-\${NGINX_VER}

./configure --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 \
  --user=nginx \
  --group=nginx \
  --build=Ubuntu \
  --builddir=nginx-\${NGINX_VER} \
  --with-select_module \
  --with-poll_module \
  --with-threads \
  --with-file-aio \
  --with-http_ssl_module \
  --with-http_v2_module \
  --with-http_realip_module \
  --with-http_addition_module \
  --with-http_xslt_module=dynamic \
  --with-http_image_filter_module=dynamic \
  --with-http_sub_module \
  --with-http_dav_module \
  --with-http_flv_module \
  --with-http_mp4_module \
  --with-http_gunzip_module \
  --with-http_gzip_static_module \
  --with-http_random_index_module \
  --with-http_secure_link_module \
  --with-http_stub_status_module \
  --with-http_degradation_module \
  --with-http_slice_module \
  --with-http_stub_status_module \
  --http-log-path=/var/log/nginx/access.log \
  --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 \
  --with-mail=dynamic \
  --with-mail_ssl_module \
  --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2' \
  --with-ld-opt='-Wl,-Bsymbolic-functions -fPIC -Wl,-z,relro -Wl,-z,now' \
  --with-http_auth_request_module \
  --with-http_geoip_module \
  --with-stream=dynamic \
  --with-stream_realip_module \
  --with-stream_geoip_module=dynamic \
  --with-stream_ssl_module \
  --with-stream_ssl_preread_module \
  --with-compat \
  --with-pcre=../pcre-\${PCRE_VER} \
  --with-pcre-jit \
  --with-zlib=../zlib-\${ZLIB_VER} \
  --with-openssl=../openssl-\${OPENSSL_VER} \
  --with-openssl-opt=no-nextprotoneg

make -j`nproc` && sudo make install

6. Make a symbol link to meet the standard of where modules should go for Nginx

sudo ln -s /usr/lib/nginx/modules /etc/nginx/modules

7. Create Nginx group and user

sudo adduser --system --home /nonexistent --shell /bin/false \
    --no-create-home --disabled-login --disabled-password \
    --gecos "nginx user" --group nginx

8. Create systemd unit file

sudo cat <<EOF> /etc/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=https://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP \$MAINPID
ExecStop=/bin/kill -s TERM \$MAINPID

[Install]
WantedBy=multi-user.target
EOF

9. Create directories and set proper permissions

sudo mkdir -p /var/cache/nginx/{client_temp,proxy_temp,fastcgi_temp,uwsgi_temp,scgi_temp}
sudo mkdir /etc/nginx/{conf.d,snippets,sites-available,sites-enabled}
sudo chmod 700 /var/cache/nginx/*
sudo chown nginx:root /var/cache/nginx/*

10. Enable and start it

sudo systemctl enable nginx.service
sudo systemctl start nginx.service

And you may check whether nginx works by accessing the corresponding IP

11. Set permissions for logs

sudo chmod 640 /var/log/nginx/*
sudo chown nginx:adm /var/log/nginx/access.log /var/log/nginx/error.log

11. remove autogenerated .default files in /etc/nginx, they're just backup

sudo rm /etc/nginx/*.default

12. If you need syntax highlight in Vim

sudo mkdir -p ~/.vim/
cp -r contrib/vim/* ~/.vim/

13. And the logrotation config

sudo cat <<EOF> /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 640 nginx adm
    sharedscripts
    postrotate
            if [ -f /var/run/nginx.pid ]; then
                    kill -USR1 `cat /var/run/nginx.pid`
            fi
    endscript
}
EOF

14. Create Apache-like modsite command

And thanks to https://github.com/ajsalkeld/nginx-modsite/blob/master/nginx-modsite, we have an Apache-like modsite command

Just copy and paste the following codes to /usr/bin/nginx_modsite

#!/bin/bash

### /usr/bin/nginx_modsite

##
# Default Settings
##

NGINX_CONF_FILE="\$(awk -F= -v RS=' ' '/conf-path/ {print \$2}' <<< \$(nginx -V 2>&1))"
NGINX_CONF_DIR="\${NGINX_CONF_FILE%/*}"
NGINX_SITES_AVAILABLE="\$NGINX_CONF_DIR/sites-available"
NGINX_SITES_ENABLED="\$NGINX_CONF_DIR/sites-enabled"
SELECTED_SITE="\$2"

##
# Script Functions
##

ngx_enable_site() {
    [[ ! "\$SELECTED_SITE" ]] &&
        ngx_select_site "not_enabled"

    [[ ! -e "\$NGINX_SITES_AVAILABLE/\$SELECTED_SITE" ]] && 
        ngx_error "Site does not appear to exist."
    [[ -e "\$NGINX_SITES_ENABLED/\$SELECTED_SITE" ]] &&
        ngx_error "Site appears to already be enabled"

    ln -sf "\$NGINX_SITES_AVAILABLE/\$SELECTED_SITE" -T "\$NGINX_SITES_ENABLED/\$SELECTED_SITE"
    ngx_reload
}

ngx_disable_site() {
    [[ ! "\$SELECTED_SITE" ]] &&
        ngx_select_site "is_enabled"

    [[ ! -e "\$NGINX_SITES_AVAILABLE/\$SELECTED_SITE" ]] &&
        ngx_error "Site does not appear to be \'available\'. - Not Removing"
    [[ ! -e "\$NGINX_SITES_ENABLED/\$SELECTED_SITE" ]] &&
        ngx_error "Site does not appear to be enabled."

    rm -f "\$NGINX_SITES_ENABLED/\$SELECTED_SITE"
    ngx_reload
}

ngx_list_site() {
    echo "Available sites:"
    ngx_sites "available"
    echo "Enabled Sites"
    ngx_sites "enabled"
}

##
# Helper Functions
##

ngx_select_site() {
    sites_avail=(\$NGINX_SITES_AVAILABLE/*)
    sa="\${sites_avail[@]##*/}"
    sites_en=(\$NGINX_SITES_ENABLED/*)
    se="\${sites_en[@]##*/}"

    case "\$1" in
        not_enabled) sites=\$(comm -13 <(printf "%s\n" \$se) <(printf "%s\n" \$sa));;
        is_enabled) sites=\$(comm -12 <(printf "%s\n" \$se) <(printf "%s\n" \$sa));;
    esac

    ngx_prompt "\$sites"
}

ngx_prompt() {
    sites=(\$1)
    i=0

    echo "SELECT A WEBSITE:"
    for site in \${sites[@]}; do
        echo -e "\$i:\t\${sites[\$i]}"
        ((i++))
    done

    read -p "Enter number for website: " i
    SELECTED_SITE="\${sites[\$i]}"
}

ngx_sites() {
    case "\$1" in
        available) dir="\$NGINX_SITES_AVAILABLE";;
        enabled) dir="\$NGINX_SITES_ENABLED";;
    esac

    for file in \$dir/*; do
        echo -e "\t\${file#*\$dir/}"
    done
}

ngx_reload() {
    read -p "Would you like to reload the Nginx configuration now? (Y/n) " reload
    [[ "\$reload" != "n" && "\$reload" != "N" ]] && invoke-rc.d nginx reload
}

ngx_error() {
    echo -e "\${0##*/}: ERROR: \$1"
    [[ "\$2" ]] && ngx_help
    exit 1
}

ngx_help() {
    echo "Usage: \${0##*/} [options]"
    echo "Options:"
    echo -e "\t<-e|--enable> <site>\tEnable site"
    echo -e "\t<-d|--disable> <site>\tDisable site"
    echo -e "\t<-l|--list>\t\tList sites"
    echo -e "\t<-h|--help>\t\tDisplay help"
    echo -e "\n\tIf <site> is left out a selection of options will be presented."
    echo -e "\tIt is assumed you are using the default sites-enabled and"
    echo -e "\tsites-disabled located at \$NGINX_CONF_DIR."
}

##
# Core Piece
##

case "\$1" in
    -e|--enable)    ngx_enable_site;;
    -d|--disable)   ngx_disable_site;;
    -l|--list)  ngx_list_site;;
    -h|--help)  ngx_help;;
    *)      ngx_error "No Options Selected" 1; ngx_help;;
esac

15. The site specific config files should go in /etc/nginx/sites-available. For example, place the config file for blog.[data deleted].com in /etc/nginx/sites-available/blog, and to enable it, type

sudo nginx_modsite -e blog

16. PHP7

It's really simple to install PHP7 (at the time of writing, it's PHP 7.2)

sudo apt install -y php-fpm

And this command will automatically install the following packages for you:

libsodium23 php-common php7.2-cli php7.2-common php7.2-fpm php7.2-json php7.2-opcache php7.2-readline

17. Enable PHP for specific site

To enable PHP for a given site, only a few lines of code is required to add into the corresponding config.

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

And please noting that, at the time of writing, PHP 7.2 is the default php7 version on Ubuntu 18.04. You may need to change the version number in the future.

Leave a Reply

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

13 − 9 =