{"id":2775,"date":"2018-01-24T17:14:27","date_gmt":"2018-01-24T14:14:27","guid":{"rendered":"https:\/\/www.howtoforge.com\/tutorial\/how-to-install-nginx-with-php-and-mysql-lemp-on-debian-9\/"},"modified":"2018-01-24T17:14:27","modified_gmt":"2018-01-24T14:14:27","slug":"how-to-install-nginx-with-php-mysql-lemp-on-debian-9","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/how-to-install-nginx-with-php-mysql-lemp-on-debian-9\/","title":{"rendered":"How to Install Nginx with PHP + MySQL (LEMP) on Debian 9"},"content":{"rendered":"<p>This tutorial will show you the installation of the Nginx web server on Debian 9 (Stretch).\u00a0<a href=\"http:\/\/nginx.net\/\" target=\"_blank\" rel=\"noopener noreferrer\">Nginx<\/a> (pronounced &#8220;engine x&#8221;) is a free, open-source, high-performance HTTP server. Nginx is known for its stability, rich feature set, simple configuration, and low resource consumption. This tutorial shows\u00a0the installation of Nginx with PHP support (through PHP-FPM) and MySQL and MariaDB. This setup is often referred to as LEMP = <b>L<\/b>inux + nginx (pronounced &#8220;<b>e<\/b>ngine x&#8221;) + <b>M<\/b>ySQL + <b>P<\/b>HP) .<\/p>\n<h2 id=\"preliminary-note\">Preliminary Note<\/h2>\n<p>In this tutorial, I use the hostname <span class=\"system\">server1.example.com<\/span> with the IP address <span class=\"system\">192.168.1.100<\/span>. These settings might differ for you, so you have to replace them where appropriate. You should have a Debian 9 server, I will use the <a href=\"https:\/\/www.howtoforge.com\/tutorial\/debian-minimal-server\/\" target=\"_blank\" rel=\"noopener\">Debian minimal server<\/a>\u00a0as the\u00a0base system for this tutorial.<\/p>\n<h2 id=\"update-the-debian-system\">Update the Debian System<\/h2>\n<p>It is recommended to update the package lists and install any pending updates before we start with the Nginx setup. Run the following commands to install any pending updates.<\/p>\n<p class=\"command\">apt-get update<br \/>apt-get upgrade -y<\/p>\n<p>I will use the nano editor later to edit configuration files. Nano can be installed with this command:<\/p>\n<p class=\"command\">apt-get -y install nano<\/p>\n<h2 id=\"install-nginx\">Install Nginx<\/h2>\n<p>Nginx is available as a package for Debian\u00a09 which we can be installed with this command:<\/p>\n<p class=\"command\">apt-get -y install nginx<\/p>\n<p>Now start Nginx web server:<\/p>\n<p class=\"command\">systemctl start nginx.service<\/p>\n<p>Type in your web server&#8217;s IP address or hostname into a browser (e.g. <span class=\"system\">http:\/\/192.168.1.100<\/span>), and you\u00a0will see the following page:<\/p>\n<p><a class=\"fancybox\" id=\"img-nginx-welcome-page\" href=\"https:\/\/www.howtoforge.com\/images\/installing-nginx-with-php-and-mysql-lemp-on-debian-9\/big\/nginx-welcome-page.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/afaghhosting.net\/blog\/wp-content\/uploads\/2018\/01\/how-to-install-nginx-with-php-mysql-lemp-on-debian-9.png\" alt=\"Nginx Welcome Page\" width=\"550\" height=\"323\" title=\"\"><\/a><\/p>\n<p>The default nginx document root on Debian Linux is <span class=\"system\">\/var\/www\/html<\/span>.<\/p>\n<h2 id=\"install-mysql-or-mariadb\">Install MySQL or MariaDB<\/h2>\n<p>In this step, I will show you how to install MySQL or MariaDB. You are free to choose which database system you prefer. Just ensure that you install only one database engine and not MySQL and MariaDB together.<\/p>\n<h3 id=\"install-mysql\">Install MySQL<\/h3>\n<p>The MySQL packages for Debian 9 can be obtained from Oracle directly. Oracle provides a MySQL repository package which integrates the Oracle MySQL repository into Debian so that we can install and update MySQL with apt. Get the MySQL apt repository package\u00a0<a href=\"https:\/\/dev.mysql.com\/downloads\/repo\/apt\/\" target=\"_blank\" rel=\"noopener\">here<\/a> in case the wget download below fails due to changes in the download URL.<\/p>\n<p class=\"command\">cd \/tmp<br \/>wget\u00a0https:\/\/dev.mysql.com\/get\/mysql-apt-config_0.8.9-1_all.deb<br \/>dpkg -i\u00a0mysql-apt-config_0.8.9-1_all.deb<\/p>\n<p>Choose to configure &#8216;OK&#8217; in the list, then focus the OK button at the footer and press enter. This will select the current stable version, which is MySQL 5.7.<\/p>\n<p><a class=\"fancybox\" id=\"img-select-mysql-version\" href=\"https:\/\/www.howtoforge.com\/images\/installing-nginx-with-php-and-mysql-lemp-on-debian-9\/big\/select-mysql-version.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/afaghhosting.net\/blog\/wp-content\/uploads\/2018\/01\/how-to-install-nginx-with-php-mysql-lemp-on-debian-9-1.png\" alt=\"Select current stable MySQL version\" width=\"550\" height=\"158\" title=\"\"><\/a><\/p>\n<p>Now we&#8217;ll update the package list and install the MySQL server and client package.<\/p>\n<p class=\"command\">apt-get update<br \/>apt-get -y install mysql-community-client mysql-community-server<\/p>\n<p>The MySQL installer will ask you to set a password for the MySQL root user. Choose a long and secure password as this pasword allows full administrative access to the MySQL database.<\/p>\n<p><a class=\"fancybox\" id=\"img-set-mysql-password\" href=\"https:\/\/www.howtoforge.com\/images\/installing-nginx-with-php-and-mysql-lemp-on-debian-9\/big\/set-mysql-password.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/afaghhosting.net\/blog\/wp-content\/uploads\/2018\/01\/how-to-install-nginx-with-php-mysql-lemp-on-debian-9-2.png\" alt=\"Set the MySQL root password\" width=\"550\" height=\"126\" title=\"\"><\/a><\/p>\n<p>Re-enter the password as requested.<\/p>\n<h3 id=\"install-mariadb\">Install MariaDB<\/h3>\n<p>In order to install MariaDB, we run:<\/p>\n<p class=\"command\"><span>apt-get -y install mariadb-server mariadb-client<\/span><\/p>\n<p>Unlike the MySQL installer, the MariaDB installer will not set a root password during installation. To secure the MariaDB installation, remove the anonymous user and to disable the test database, run this command:<\/p>\n<p class=\"command\">mysql_secure_installation<\/p>\n<p>Answer the questions as follows:<\/p>\n<p class=\"system\">Change the root password? [Y\/n]<span>\u00a0<\/span><span class=\"highlight\">&lt;&#8211; y<\/span><br \/>New password:<span>\u00a0<\/span><span class=\"highlight\">&lt;&#8211; Enter a new MySQL root password<\/span><br \/>Re-enter new password:<span>\u00a0<\/span><span class=\"highlight\">&lt;&#8211; Repeat the MySQL root password<\/span><br \/>Remove anonymous users? [Y\/n]<span>\u00a0<\/span><span class=\"highlight\">&lt;&#8211; y<\/span><br \/>Disallow root login remotely? [Y\/n]<span>\u00a0<\/span><span class=\"highlight\">&lt;&#8211; y<\/span><br \/>Remove test database and access to it? [Y\/n]<span>\u00a0<\/span><span class=\"highlight\">&lt;&#8211; y<\/span><br \/>Reload privilege tables now? [Y\/n]<span>\u00a0<\/span><span class=\"highlight\">&lt;&#8211; y<\/span><\/p>\n<h2 id=\"installing-php\">Installing PHP<\/h2>\n<p>We can make PHP work in nginx through PHP-FPM (PHP FastCGI Process Manager). This is an alternative PHP FastCGI implementation with some additional features useful for sites of any size, especially busier sites. Install PHP 7 as follows:<\/p>\n<p class=\"command\">apt-get -y install\u00a0php7.0-fpm<\/p>\n<p>PHP-FPM is a daemon process (with the systemd unit file php7.0-fpm.service) that runs a FastCGI server on the socket <span class=\"system\">\/var\/run\/php\/php7.0-fpm.sock<\/span>.<\/p>\n<h2 id=\"configuring-nginx\">Configuring Nginx<\/h2>\n<p>The Nginx configuration is in <span class=\"system\">\/etc\/nginx\/nginx.conf<\/span> which we open now:<\/p>\n<p class=\"command\">nano \/etc\/nginx\/nginx.conf<\/p>\n<p>The configuration is easy to understand (you can learn more about it here:\u00a0<a href=\"https:\/\/www.nginx.com\/resources\/wiki\/start\/topics\/examples\/full\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.nginx.com\/resources\/wiki\/start\/topics\/examples\/full\/<\/a> and here: <a href=\"https:\/\/www.nginx.com\/resources\/wiki\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.nginx.com\/resources\/wiki\/<\/a>)<\/p>\n<p>First set the <span class=\"system\">keepalive_timeout<\/span> to a reasonable value like 2 seconds:<\/p>\n<pre>[...]<br\/>keepalive_timeout 2;<br\/>[...]<\/pre>\n<p>The virtual hosts are defined in <span class=\"system\">server {}<\/span> containers. The default vhost is defined in the file <span class=\"system\">\/etc\/nginx\/sites-available\/default<\/span> &#8211; let&#8217;s modify it as follows:<\/p>\n<p class=\"command\">nano \/etc\/nginx\/sites-available\/default<\/p>\n<pre readability=\"25\">[...]&#13;\nserver {<br\/>listen 80 default_server;<br\/>listen [::]:80 default_server;<p># SSL configuration<br\/>#<br\/># listen 443 ssl default_server;<br\/># listen [::]:443 ssl default_server;<br\/>#<br\/># Note: You should disable gzip for SSL traffic.<br\/># See: https:\/\/bugs.debian.org\/773332<br\/>#<br\/># Read up on ssl_ciphers to ensure a secure configuration.<br\/># See: https:\/\/bugs.debian.org\/765782<br\/>#<br\/># Self signed certs generated by the ssl-cert package<br\/># Don't use them in a production server!<br\/>#<br\/># include snippets\/snakeoil.conf;<\/p><p>root \/var\/www\/html;<\/p><p># Add index.php to the list if you are using PHP<br\/>index index.php index.html index.htm index.nginx-debian.html;<\/p><p>server_name _;<\/p><p>location \/ {<br\/># First attempt to serve request as file, then<br\/># as directory, then fall back to displaying a 404.<br\/>try_files $uri $uri\/ =404;<br\/>}<\/p><p># pass PHP scripts to FastCGI server<br\/>#<br\/>location ~ \\.php$ {<br\/>include snippets\/fastcgi-php.conf;<\/p><p># With php-fpm (or other unix sockets):<br\/>fastcgi_pass unix:\/var\/run\/php\/php7.0-fpm.sock;<br\/># With php-cgi (or other tcp sockets):<br\/># fastcgi_pass 127.0.0.1:9000;<br\/>}<\/p><p># deny access to .htaccess files, if Apache's document root<br\/># concurs with nginx's one<br\/>#<br\/>location ~ \/\\.ht {<br\/>deny all;<br\/>}<br\/>}&#13;\n[...]<\/p><\/pre>\n<p><span class=\"system\">server_name _;<\/span> makes this a default catchall vhost (of course, you can as well specify a hostname here like <span class=\"system\">www.example.com<\/span>).<\/p>\n<p>I&#8217;ve added <span class=\"system\">index.php<\/span> to the <span class=\"system\">index<\/span> line. <span class=\"system\">root \/var\/www\/html;<\/span> means that the document root is the directory <span class=\"system\">\/var\/www\/html<\/span>.<\/p>\n<p>The important part for PHP is the <span class=\"system\">location ~ \\.php$ {}<\/span> stanza. Uncomment it like shown above to enable it. There are two fastcgi_pass lines included, uncomment just the one for the php-7.0-fpm.sock file.<\/p>\n<p>Now save the file and reload Nginx:<\/p>\n<p class=\"command\">systemctl reload nginx.service<\/p>\n<p>Next open <span class=\"system\">\/etc\/php\/7.0\/fpm\/php.ini<\/span>&#8230;<\/p>\n<p class=\"command\">nano \/etc\/php\/7.0\/fpm\/php.ini<\/p>\n<p>&#8230; and set <span class=\"system\">cgi.fix_pathinfo=0<\/span>:<\/p>\n<pre>[...]&#13;\n; cgi.fix_pathinfo provides *real* PATH_INFO\/PATH_TRANSLATED support for CGI. PHP's&#13;\n; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok&#13;\n; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting&#13;\n; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting&#13;\n; of zero causes PHP to behave as before. Default is 1. You should fix your scripts&#13;\n; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.&#13;\n; http:\/\/php.net\/cgi.fix-pathinfo&#13;\ncgi.fix_pathinfo=0&#13;\n[...]<\/pre>\n<p>&#8230; then you might want to rise the POST limit and the file upload limit:<\/p>\n<pre>post_max_size = 25M<br\/>upload_max_filesize = 20M<\/pre>\n<p>When you plan to upload large files by PHP then you should raise the values to even 500M or more. M stands here for Megabytes.<\/p>\n<p>Finally, you might want to set the timezone to your local timezone. In my case, the timezone is:<\/p>\n<pre>date.timezone = 'Europe\/Berlin'<\/pre>\n<p>You can find the list of supported timezones <a href=\"http:\/\/php.net\/manual\/de\/timezones.php\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n<p>Reload PHP-FPM to apply the changes:<\/p>\n<p class=\"command\">systemctl reload php7.0-fpm.service<\/p>\n<p>Now create the following PHP file in the document root <span class=\"system\">\/var\/www\/html\/<\/span>:<\/p>\n<p class=\"command\">nano \/var\/www\/html\/info.php<\/p>\n<pre>&lt;?php&#13;\nphpinfo();<\/pre>\n<p>Now we call that file in a browser (e.g. <span class=\"system\">http:\/\/192.168.1.100\/info.php<\/span>):<\/p>\n<p><a class=\"fancybox\" id=\"img-php-info-nginx\" href=\"https:\/\/www.howtoforge.com\/images\/installing-nginx-with-php-and-mysql-lemp-on-debian-9\/big\/php-info-nginx.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/afaghhosting.net\/blog\/wp-content\/uploads\/2018\/01\/how-to-install-nginx-with-php-mysql-lemp-on-debian-9-3.png\" alt=\"PHP-FPM info\" width=\"550\" height=\"349\" title=\"\"><\/a><\/p>\n<p>As you see, PHP 7 is working, and it&#8217;s working through FPM\/FastCGI, as shown in the <span class=\"system\">Server API<\/span> line. If you scroll further down, you will see all modules that are already enabled in PHP. MySQL is not listed there which means we don&#8217;t have MariaDB \/ MySQL support in PHP yet.<\/p>\n<h2 id=\"getting-mysql-mariadb-support-in-php\">Getting MySQL \/ MariaDB Support in PHP<\/h2>\n<p>To get MySQL support in PHP, we can install the <span class=\"system\">php7.0-mysqlnd<\/span> package. It&#8217;s a good idea to install some other PHP modules as well as you might need them for your applications. You can search for available PHP modules like this:<\/p>\n<p class=\"command\">apt-cache search php7.0<\/p>\n<p>Pick the ones you need and install them like this:<\/p>\n<p class=\"command\">apt-get -y install php7.0-mysqlnd php7.0-curl php7.0-gd php7.0-intl php-pear php-imagick php7.0-imap php7.0-mcrypt php-memcache php7.0-intl php7.0-pspell php7.0-recode php7.0-sqlite3 php7.0-tidy php7.0-xmlrpc php7.0-xsl<\/p>\n<p>Now reload PHP-FPM:<\/p>\n<p class=\"command\">systemctl reload php7.0-fpm.service<\/p>\n<p>Now reload <span class=\"system\">http:\/\/192.168.1.100\/info.php<\/span> in your browser and scroll down to the modules section again. You should now find lots of new modules there, including the MySQLi and MySQLnd module:<\/p>\n<p><a class=\"fancybox\" id=\"img-mysql-php\" href=\"https:\/\/www.howtoforge.com\/images\/installing-nginx-with-php-and-mysql-lemp-on-debian-9\/big\/mysql-php.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/afaghhosting.net\/blog\/wp-content\/uploads\/2018\/01\/how-to-install-nginx-with-php-mysql-lemp-on-debian-9-4.png\" alt=\"PHP with builtin MySQL support\" width=\"550\" height=\"349\" title=\"\"><\/a><\/p>\n<h2 id=\"making-phpfpm-use-a-tcp-connection-optional\">Making PHP-FPM use a TCP connection (optional)<\/h2>\n<p>By default, PHP-FPM is listening on the socket <span class=\"system\">\/var\/run\/php\/php7.0-fpm.sock<\/span>\u00a0and that&#8217;s the recommended and fastest way to connect PHP to Nginx. However, there might be setups where you want to let Nginx connect to PHP over the network. It is possible to make PHP-FPM use a TCP connection. To do this, open <span class=\"system\">\/etc\/php\/7.0\/fpm\/pool.d\/www.conf<\/span>&#8230;<\/p>\n<p class=\"command\">nano\u00a0\/etc\/php\/7.0\/fpm\/pool.d\/www.conf<\/p>\n<p>&#8230; and make the <span class=\"system\">listen<\/span> line look as follows:<\/p>\n<pre>[...]&#13;\n;listen = \/var\/run\/php5-fpm.sock&#13;\nlisten = 127.0.0.1:9000&#13;\n[...]<\/pre>\n<p>This will make PHP-FPM listen on port <span class=\"system\">9000<\/span> on the IP <span class=\"system\">127.0.0.1<\/span> (<span class=\"system\">localhost<\/span>). Make sure you use a port that is not in use on your system.<\/p>\n<p>Then reload PHP-FPM:<\/p>\n<p class=\"command\">systemctl reload php7.0-fpm.service<\/p>\n<p>Next go through your Nginx configuration and all your vhosts and change the line <span class=\"system\">fastcgi_pass unix:\/var\/run\/php7.0-fpm.sock;<\/span> to <span class=\"system\">fastcgi_pass 127.0.0.1:9000;<\/span>, e.g. like this:<\/p>\n<p class=\"command\">nano \/etc\/nginx\/sites-available\/default<\/p>\n<pre readability=\"6\">[...]<br\/>location ~ \\.php$ {<br\/>include snippets\/fastcgi-php.conf;<p># With php-fpm (or other unix sockets):<br\/># fastcgi_pass unix:\/var\/run\/php\/php7.0-fpm.sock;<br\/># With php-cgi (or other tcp sockets):<br\/>fastcgi_pass 127.0.0.1:9000;<br\/>}&#13;\n[...]<\/p><\/pre>\n<p>Finally, reload Nginx:<\/p>\n<p class=\"command\">systemctl reload nginx.service<\/p>\n<h2 id=\"enable-ssl-and-http-in-nginx\">Enable SSL and HTTP\/2 in Nginx<\/h2>\n<p>Most websites today use SSL (TLS) to provide secure access. In this chapter, I&#8217;ll show you how to create an SSL certificate an how to activate SSL in Nginx. You can either use a self-signed SSL certificate or request an officially signed SSL certificate from Let&#8217;s encrypt. Let#s encrypt SSL certificates are available free of charge, but you must have a valid domain name that points to your server in DNS already. If you have no domain name yet or when your server is on a local network and not accessible from outside, then use a self-signed SSL certificate. Follow either the steps for a self-signed SSL certificate or the Let&#8217;s encrypt certificate below but not both.<\/p>\n<h3 id=\"create-a-selfsigned-ssl-certificate\">Create a self-signed SSL certificate<\/h3>\n<p>Create the SSL key file with the\u00a0OpenSSL command:<\/p>\n<p class=\"command\">openssl genrsa -out \/etc\/ssl\/private\/nginx.key 4096<\/p>\n<p><a class=\"fancybox\" id=\"img-create-openssl-key\" href=\"https:\/\/www.howtoforge.com\/images\/installing-nginx-with-php-and-mysql-lemp-on-debian-9\/big\/create-openssl-key.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/afaghhosting.net\/blog\/wp-content\/uploads\/2018\/01\/how-to-install-nginx-with-php-mysql-lemp-on-debian-9-5.png\" alt=\"Create the SSL certificate key with OpenSSL\" width=\"550\" height=\"141\" title=\"\"><\/a><\/p>\n<p>Then create the self-signed SSL certificate:<\/p>\n<p class=\"command\">openssl req -new -x509 -key \/etc\/ssl\/private\/nginx.key -out \/etc\/ssl\/certs\/nginx.pem -days 3650<\/p>\n<p>The command will ask for details like country, state, city, company name and domain name.<\/p>\n<p><a class=\"fancybox\" id=\"img-create-openssl-certificate\" href=\"https:\/\/www.howtoforge.com\/images\/installing-nginx-with-php-and-mysql-lemp-on-debian-9\/big\/create-openssl-certificate.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/afaghhosting.net\/blog\/wp-content\/uploads\/2018\/01\/how-to-install-nginx-with-php-mysql-lemp-on-debian-9-6.png\" alt=\"Create an SSL cert with OpenSSL\" width=\"550\" height=\"173\" title=\"\"><\/a><\/p>\n<p>Activate the self-signed SSL certificate in Nginx. To do so, edit the nginx.conf file again:<\/p>\n<p class=\"command\"><span>nano \/etc\/<\/span>nginx<span>\/sites-available\/default<\/span><\/p>\n<p><span>and make the server part it look like this:<\/span><\/p>\n<pre readability=\"32\">server {<br\/>listen 80 default_server;<br\/>listen [::]:80 default_server;<p># SSL configuration<\/p><p>listen 443 ssl http2 default_server;<br\/>listen [::]:443 ssl http2 default_server;<\/p><p>ssl on;<br\/>ssl_certificate_key \/etc\/ssl\/private\/nginx.key;<br\/>ssl_certificate \/etc\/ssl\/certs\/nginx.pem;<br\/>ssl_protocols TLSv1 TLSv1.1 TLSv1.2;<br\/>ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';<br\/>ssl_prefer_server_ciphers on;<\/p><p># Note: You should disable gzip for SSL traffic.<br\/># See: https:\/\/bugs.debian.org\/773332<br\/>#<br\/># Read up on ssl_ciphers to ensure a secure configuration.<br\/># See: https:\/\/bugs.debian.org\/765782<br\/>#<br\/># Self signed certs generated by the ssl-cert package<br\/># Don't use them in a production server!<br\/>#<br\/># include snippets\/snakeoil.conf;<\/p><p>root \/var\/www\/html;<\/p><p># Add index.php to the list if you are using PHP<br\/>index index.php index.html index.htm index.nginx-debian.html;<\/p><p>server_name _;<\/p><p>location \/ {<br\/># First attempt to serve request as file, then<br\/># as directory, then fall back to displaying a 404.<br\/>try_files $uri $uri\/ =404;<br\/>}<\/p><p># pass PHP scripts to FastCGI server<br\/>#<br\/>location ~ \\.php$ {<br\/>include snippets\/fastcgi-php.conf;<\/p><p># With php-fpm (or other unix sockets):<br\/>fastcgi_pass unix:\/var\/run\/php\/php7.0-fpm.sock;<br\/># With php-cgi (or other tcp sockets):<br\/># fastcgi_pass 127.0.0.1:9000;<br\/>}<\/p><p># deny access to .htaccess files, if Apache's document root<br\/># concurs with nginx's one<br\/>#<br\/>location ~ \/\\.ht {<br\/>deny all;<br\/>}<br\/>}<\/p><\/pre>\n<p>Restart Nginx to apply the changes.<\/p>\n<p class=\"command\">systemctl restart nginx.service<\/p>\n<p>Now open the https URL of your server in a browser, e.g. <a href=\"https:\/\/192.169.1.100\/\">https:\/\/192.169.1.100\/<\/a>. You will get a security warning which you&#8217;ll have to accept to proceed. Afterwards, you will see the Nginx start page, the warning icon in the URL bar of the browser indicates that we use a self-signed SSL certificate.<\/p>\n<p><a class=\"fancybox\" id=\"img-nginx-ssl-connection\" href=\"https:\/\/www.howtoforge.com\/images\/installing-nginx-with-php-and-mysql-lemp-on-debian-9\/big\/nginx-ssl-connection.png\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/afaghhosting.net\/blog\/wp-content\/uploads\/2018\/01\/how-to-install-nginx-with-php-mysql-lemp-on-debian-9-7.png\" alt=\"\" title=\"\"><\/a><\/p>\n<h3 id=\"use-a-free-lets-encrypt-ssl-certificate\">Use a free Let&#8217;s Encrypt SSL certificate<\/h3>\n<p>In this chapter, I&#8217;ll describe how to secure your Nginx server by using a free Let&#8217;s encrypt SSL certificate. A prerequisite is that you own a domain name which points to the IP of the server where you install Nginx on at the moment.<\/p>\n<p>Install Certbot, the Let&#8217;s encrypt client that is used to obtain a free SSL certificate.<\/p>\n<p class=\"command\">apt-get -y install certbot\u00a0python-certbot-nginx<\/p>\n<p>Edit the website configuration file \/etc\/nginx\/sites-available\/default and set your domain name(s) in the server_name line:<\/p>\n<p class=\"command\">nano \/etc\/nginx\/sites-available\/default<\/p>\n<p>The line should look like this after editing:<\/p>\n<pre>server_name example.com;<\/pre>\n<p>Replace example.com with your own domain name. If you have multiple domain names or subdomains, then add them separated by whitespace.<\/p>\n<pre>server_name example.com www.example.com\u00a0otherdomain.tld;<\/pre>\n<p>Now we request an SSL certificate from let&#8217;s encrypt by using the nginx plugin from Certbot.<\/p>\n<p class=\"command\">certbot &#8211;nginx -d example.com<\/p>\n<p>Multiple domains can be added by repeating the -d option. Example:<\/p>\n<p class=\"command\"><span><span>certbot\u00a0certonly\u00a0<\/span>&#8211;webroot<\/span><span><span>\u00a0<\/span>-d example.com -d www.example.com<\/span><\/p>\n<p>Certbot will ask you for an email address where renewal notifications shall be sent to. Enter\u00a0a valid email address here:<\/p>\n<p class=\"system\">Enter email address (used for urgent renewal and security notices) (Enter &#8216;c&#8217; to cancel): <span class=\"highlight\"><a href=\"https:\/\/www.howtoforge.com\/cdn-cgi\/l\/email-protection\" class=\"__cf_email__\" data-cfemail=\"a0d9cfd5d2cec1cdc5e0c5d8c1cdd0ccc58ec3cfcd\" target=\"_blank\" rel=\"noopener\">[email\u00a0protected]<\/a><\/span><\/p>\n<p>Accept the license terms by entering &#8216;A&#8217;.<\/p>\n<p class=\"system\">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>Please read the Terms of Service at<br \/>https:\/\/letsencrypt.org\/documents\/LE-SA-v1.2-November-15-2017.pdf. You must<br \/>agree in order to register with the ACME server at<br \/>https:\/\/acme-v01.api.letsencrypt.org\/directory<br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>(A)gree\/(C)ancel: <span class=\"highlight\">A<\/span><\/p>\n<p>Here the further dialog that requests the SSL certificate. I&#8217;ve added my answers in red.<\/p>\n<p class=\"system\">Saving debug log to \/var\/log\/letsencrypt\/letsencrypt.log<br \/>Obtaining a new certificate<br \/>Performing the following challenges:<br \/>http-01 challenge for example.com<br \/>http-01 challenge for www.example.com<\/p>\n<p class=\"system\">Select the webroot for example.com:<br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>1: Enter a new webroot<br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>Press 1 [enter] to confirm the selection (press &#8216;c&#8217; to cancel): <span class=\"highlight\">1<\/span><br \/>Input the webroot for example.com: (Enter &#8216;c&#8217; to cancel):<span class=\"highlight\">\/var\/www\/html<\/span><\/p>\n<p class=\"system\">Select the webroot for www.example.com:<br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>1: Enter a new webroot<br \/>2: \/var\/www\/html<br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>Select the appropriate number [1-2] then [enter] (press &#8216;c&#8217; to cancel): <span class=\"highlight\">2<\/span><br \/>Waiting for verification&#8230;<br \/>Cleaning up challenges<br \/>Generating key (2048 bits): \/etc\/letsencrypt\/keys\/0000_key-certbot.pem<br \/>Creating CSR: \/etc\/letsencrypt\/csr\/0000_csr-certbot.pem<\/p>\n<p class=\"system\">IMPORTANT NOTES:<br \/>&#8211; Congratulations! Your certificate and chain have been saved at<br \/>\/etc\/letsencrypt\/live\/example.com\/fullchain.pem. Your cert will<br \/>expire on 2018-04-23. To obtain a new or tweaked version of this<br \/>certificate in the future, simply run certbot again. To<br \/>non-interactively renew *all* of your certificates, run &#8220;certbot<br \/>renew&#8221;<br \/>&#8211; If you like Certbot, please consider supporting our work by:<\/p>\n<p class=\"system\">Donating to ISRG \/ Let&#8217;s Encrypt: https:\/\/letsencrypt.org\/donate<br \/>Donating to EFF: https:\/\/eff.org\/donate-le<\/p>\n<p>There is an alternate method by using the &#8216;&#8211;nginx&#8217; option in Certbot, but this method does not seem to work at the moment due to the TLS-SNI-01 problem in Let&#8217;s encrypt. The webroot method, as shown above, works fine though.<\/p>\n<p>The newly generated SSL certificate is in a subfolder of\u00a0\/etc\/letsencrypt\/live\/ folder. The exact path is shown in the Certbot output.<\/p>\n<p>Now we&#8217;ll add this SSL certificate in our Nginx website file. Edit the Nginx default file:<\/p>\n<p class=\"command\"><span>nano \/etc\/<\/span>nginx<span>\/sites-available\/default<\/span><\/p>\n<p><span>and change the SSL section like this:<\/span><\/p>\n<pre readability=\"32\">[...]&#13;\nserver {<br\/>listen 80 default_server;<br\/>listen [::]:80 default_server;<p># SSL configuration<\/p><p>listen 443 ssl http2 default_server;<br\/>listen [::]:443 ssl http2 default_server;<\/p><p>ssl on;<br\/>ssl_certificate_key \/etc\/letsencrypt\/live\/example.com\/privkey.pem;<br\/>ssl_certificate \/etc\/letsencrypt\/live\/example.com\/fullchain.pem;<br\/>ssl_protocols TLSv1 TLSv1.1 TLSv1.2;<br\/>ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';<br\/>ssl_prefer_server_ciphers on;<\/p><p># Note: You should disable gzip for SSL traffic.<br\/># See: https:\/\/bugs.debian.org\/773332<br\/>#<br\/># Read up on ssl_ciphers to ensure a secure configuration.<br\/># See: https:\/\/bugs.debian.org\/765782<br\/>#<br\/># Self signed certs generated by the ssl-cert package<br\/># Don't use them in a production server!<br\/>#<br\/># include snippets\/snakeoil.conf;<\/p><p>root \/var\/www\/html;<\/p><p># Add index.php to the list if you are using PHP<br\/>index index.php index.html index.htm index.nginx-debian.html;<\/p><p>server_name _;<\/p><p>location \/ {<br\/># First attempt to serve request as file, then<br\/># as directory, then fall back to displaying a 404.<br\/>try_files $uri $uri\/ =404;<br\/>}<\/p><p># pass PHP scripts to FastCGI server<br\/>#<br\/>location ~ \\.php$ {<br\/>include snippets\/fastcgi-php.conf;<\/p><p># With php-fpm (or other unix sockets):<br\/>fastcgi_pass unix:\/var\/run\/php\/php7.0-fpm.sock;<br\/># With php-cgi (or other tcp sockets):<br\/># fastcgi_pass 127.0.0.1:9000;<br\/>}<\/p><p># deny access to .htaccess files, if Apache's document root<br\/># concurs with nginx's one<br\/>#<br\/>location ~ \/\\.ht {<br\/>deny all;<br\/>}<br\/>}&#13;\n[...]<\/p><\/pre>\n<p>Replace &#8216;example.com&#8217; in the SSL certificate path with your own domain name. Restart Nginx to apply the changes.<\/p>\n<p class=\"command\">systemctl restart<span>\u00a0<\/span>nginx.service<\/p>\n<h2 id=\"virtual-machine-image\">Virtual Machine image<\/h2>\n<p>This tutorial is available as ready to use virtual machine in OVA \/ OVF format for Howtoforge subscribers. The VM format is compatible with VMWare and Virtualbox and probably some other tools that can import this format. You can find the download link in the right menu on the top. Click on the file name to start the download.<\/p>\n<p>The login details of the VM are:<\/p>\n<h3 id=\"ssh-login\">SSH Login<\/h3>\n<p>Username: administrator<br \/>Password: howtoforge<\/p>\n<p>Run &#8216;su&#8217; to become root user, the root password is &#8216;howtoforge&#8217; as well.<\/p>\n<p>The virtual machine image uses MySQL as the database server.<\/p>\n<h3 id=\"mysql-login\">MySQL Login<\/h3>\n<p><span>Username: root<\/span><br \/><span>Password: howtoforge<\/span><\/p>\n<p><span>Please change the passwords after the first boot.<\/span><\/p>\n<p><span>The VM is configured for the static IP 192.168.1.100, the IP can be changed in the file \/etc\/network\/interfaces.<\/span><\/p>\n<h2 id=\"links\">Links<\/h2>\n<div>\n<p><b>Share this page:<\/b><\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial will show you the installation of the Nginx web server on Debian 9 (Stretch).\u00a0Nginx (pronounced &#8220;engine x&#8221;) is a free, open-source, high-performance HTTP server. Nginx is known for its stability, rich feature set, simple configuration, and low resource consumption. This tutorial shows\u00a0the installation of Nginx with PHP support (through PHP-FPM) and MySQL and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[36],"tags":[],"class_list":["post-2775","post","type-post","status-publish","format-standard","hentry","category-36"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/2775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=2775"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/2775\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=2775"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=2775"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=2775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}