{"id":1829,"date":"2019-11-09T17:02:08","date_gmt":"2019-11-09T09:02:08","guid":{"rendered":"https:\/\/www.techcoil.com\/blog\/?p=1829"},"modified":"2020-05-12T13:57:18","modified_gmt":"2020-05-12T05:57:18","slug":"how-to-setup-a-raspberry-pi-lemp-server-with-raspbian-buster-lite-for-running-php-applications","status":"publish","type":"post","link":"https:\/\/www.techcoil.com\/blog\/how-to-setup-a-raspberry-pi-lemp-server-with-raspbian-buster-lite-for-running-php-applications\/","title":{"rendered":"How to setup a Raspberry Pi LEMP server with Raspbian Buster Lite for running PHP applications"},"content":{"rendered":"<p>Many useful applications are written in <a href=\"https:\/\/www.php.net\/\" rel=\"noopener\" target=\"_blank\">PHP<\/a> backed by <a href=\"https:\/\/mariadb.org\/\" rel=\"noopener\" target=\"_blank\">MariaDB<\/a>\/<a href=\"https:\/\/www.mysql.com\/\" rel=\"noopener\" target=\"_blank\">MySQL<\/a> for data persistency.<\/p>\n<p>When you wondering what you can use a Raspberry Pi for, one way is to turn it into a LEMP server for hosting PHP applications.<\/p>\n<p>With this in mind, let us look at how we can setup a Raspberry Pi LEMP server with Raspbian Buster Lite for running PHP applications.<\/p>\n<h2>Recommended parts<\/h2>\n<p>In order for you to follow this tutorial, it is recommended that you have a version of Raspberry Pi with either WiFi or RJ45 network connection.<\/p>\n<p>For example, you can get the following items to follow this tutorial:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.amazon.com\/CanaKit-Raspberry-4GB-Basic-Kit\/dp\/B07TXKY4Z9\/ref=as_li_ss_tl?ie=UTF8&linkCode=ll1&tag=clivsperswebs-20&linkId=ee0bc12c3f4cdcf9d11b2736e813db35&language=en_US\" rel=\"noopener\" target=\"_blank\">CanaKit Raspberry Pi 4 Basic Kit 4GB<\/a><\/li>\n<li><a href=\"https:\/\/www.amazon.com\/SanDisk-128GB-Extreme-microSD-Adapter\/dp\/B07FCMKK5X\/ref=as_li_ss_tl?ie=UTF8&linkCode=ll1&tag=clivsperswebs-20&linkId=449c21149acf87d69f38abf28778dd6f&language=en_US\" rel=\"noopener\" target=\"_blank\">SanDisk 128GB Extreme microSDXC UHS-I Memory Card with Adapter<\/a><\/li>\n<li><a href=\"https:\/\/www.amazon.com\/dp\/B07WV9H1V4\/ref=as_li_ss_tl?ie=UTF8&linkCode=ll1&tag=clivsperswebs-20&linkId=2ba999d51cce65ad705ad8f2347cb079&language=en_US\" rel=\"noopener\" target=\"_blank\">ZkeeShop Magnetic Installation Acrylic Case for Raspberry Pi 4 Model B<\/a><\/li>\n<li><a href=\"https:\/\/www.amazon.com\/Ethernet-VANDESAIL-Gigabit-Network-Plated\/dp\/B013W0ARNY\/ref=as_li_ss_tl?ie=UTF8&linkCode=ll1&tag=clivsperswebs-20&linkId=2144de5a3a7469fc8587b1162b13a280&language=en_US\" rel=\"noopener\" target=\"_blank\">Gigabit Ethernet Cable<\/a><\/li>\n<\/ul>\n<p>In addition to the list of recommended hardware, you will need a computer with an <a href=\"https:\/\/www.amazon.com\/s\/ref=as_li_ss_tl?k=SD+card+writer&ref=nb_sb_noss&linkCode=ll2&tag=clivsperswebs-20&linkId=b9cd84bafd28eae586a6dded418d3b10&language=en_US\" rel=\"noopener\" target=\"_blank\">SD card writer<\/a>.<\/p>\n<h2>Setting up the LEMP stack on your Raspberry Pi<\/h2>\n<p>Once you had gathered the parts to build your server, you can setup the LEMP stack on your Raspberry Pi.<\/p>\n<h3>Setup Raspbian Buster Lite for server projects<\/h3>\n<p>First, <a href=\"https:\/\/www.techcoil.com\/blog\/how-to-setup-raspbian-buster-lite-for-raspberry-pi-server-projects\/\" target=\"_blank\" rel=\"noopener\">setup Raspbian Buster Lite for Raspberry Pi server projects<\/a>.<\/p>\n<p>After you had done so, you will be able to use SSH to administrate your Raspbian Buster Lite from your computer.<\/p>\n<p>In order to keep it simple, let's assume that you had ran the following command in a terminal program:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nssh pi@192.168.1.114\r\n<\/pre>\n<p>and logged into your Raspbian Buster Lite successfully.<\/p>\n<h3>Installing Nginx web server on Raspbian Buster Lite<\/h3>\n<p>Once you had setup the operating system to run your Raspberry Pi, install <a href=\"http:\/\/nginx.org\" target=\"_blank\" rel=\"noopener\">Nginx<\/a> by running the following command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo apt-get update\r\nsudo apt install nginx -y\r\n<\/pre>\n<p>When the commands had completed, you can run the following command to check if Nginx is successfully installed on your Raspberry Pi:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsystemctl status nginx.service\r\n<\/pre>\n<p>If Nginx is successfully installed, then you should see output similar to the following:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n\u25cf nginx.service - A high performance web server and a reverse proxy server\r\nLoaded: loaded (\/lib\/systemd\/system\/nginx.service; enabled; vendor preset: enabled)\r\nActive: active (running) since Sun 2019-10-22 15:04:28 +08; 2min 03s ago\r\nDocs: man:nginx(8)\r\nMain PID: 2962 (nginx)\r\nTasks: 5 (limit: 4915)\r\nMemory: 7.6M\r\nCGroup: \/system.slice\/nginx.service\r\n\u251c\u25002962 nginx: master process \/usr\/sbin\/nginx -g daemon on; master_process on;\r\n\u251c\u25002963 nginx: worker process\r\n\u251c\u25002964 nginx: worker process\r\n\u251c\u25002965 nginx: worker process\r\n\u2514\u25002966 nginx: worker process\r\n\r\nOct 22 15:04:28 raspberrypi systemd&#x5B;1]: Starting A high performance web server and a reverse proxy server...\r\nOct 22 15:04:28 raspberrypi systemd&#x5B;1]: Started A high performance web server and a reverse proxy server.\r\n<\/pre>\n<p>Another way to verify your Nginx installation is by accessing http:\/\/&lt;your_raspberry_pi_ip_address&gt; from your web browser. When Nginx is up and running, the <a href=\"https:\/\/www.techcoil.com\/blog\/understanding-the-default-nginx-virtual-host-or-server-configuration\/\" rel=\"noopener\" target=\"_blank\">default Nginx configurations<\/a> will render the following page:<br \/>\n<img decoding=\"async\" width=\"579\" height=\"259\" src=\"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/default-welcome-page-of-Nginx-1.14.2.gif\" class=\"aligncenter size-full wp-image-1756\" alt=\"default welcome page of Nginx 1.14.2\"><\/p>\n<h3>Installing MariaDB server and command line client on Raspbian Buster Lite<\/h3>\n<p>Once you had installed the Nginx web server, install MariaDB server and command line client with the following command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo apt install mariadb-server mariadb-client -y\r\n<\/pre>\n<p>After the command had completed, you can verify your installation by running the following command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo mariadb\r\n<\/pre>\n<p>When you do so, you are using the MariaDB command line client to interact with the server. If these two components are installed properly, you should get an interactive command line session like the following:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nWelcome to the MariaDB monitor. Commands end with ; or \\g.\r\nYour MariaDB connection id is 47\r\nServer version: 10.3.17-MariaDB-0+deb10u1 Raspbian 10\r\n\r\nCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.\r\n\r\nType 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.\r\n\r\nMariaDB &#x5B;(none)]&gt;\r\n<\/pre>\n<p>When you wish to setup the database instance for your PHP application later, this tool is what you will use.<\/p>\n<p>In order to continue with the rest of the setup, type <strong>exit<\/strong> and then <strong>Enter<\/strong> to quit the command line client.<\/p>\n<h3>Installing PHP and PHP FPM on Raspbian Buster Lite<\/h3>\n<p>After you had fulfilled the database part of the LEMP equation, install PHP, PHP FPM and the necessary libraries with the following command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo apt install php php-fpm php-mysql -y\r\n<\/pre>\n<p>Once the command had completed, check your <a href=\"https:\/\/php-fpm.org\/\" rel=\"noopener\" target=\"_blank\">PHP FPM<\/a> installation with the following command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsystemctl status php7*\r\n<\/pre>\n<p>If PHP FPM was installed properly, then you should see output similar to the following:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n\u25cf php7.3-fpm.service - The PHP 7.3 FastCGI Process Manager\r\nLoaded: loaded (\/lib\/systemd\/system\/php7.3-fpm.service; enabled; vendor preset: enabled)\r\nActive: active (running) since Sun 2019-10-22 15:08:15 +08; 1min 14s ago\r\nDocs: man:php-fpm7.3(8)\r\nMain PID: 16080 (php-fpm7.3)\r\nStatus: &quot;Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req\/sec&quot;\r\nTasks: 3 (limit: 4915)\r\nMemory: 5.0M\r\nCGroup: \/system.slice\/php7.3-fpm.service\r\n\u251c\u250016080 php-fpm: master process (\/etc\/php\/7.3\/fpm\/php-fpm.conf)\r\n\u251c\u250016081 php-fpm: pool www\r\n\u2514\u250016082 php-fpm: pool www\r\n\r\nOct 22 15:08:15 raspberrypi systemd&#x5B;1]: Starting The PHP 7.3 FastCGI Process Manager...\r\nOct 22 15:08:15 raspberrypi systemd&#x5B;1]: Started The PHP 7.3 FastCGI Process Manager.\r\n<\/pre>\n<p>So what had we installed? In case you are wondering, we had installed:<\/p>\n<ul>\n<li>PHP hypertext processor,<\/li>\n<li>a <a href=\"https:\/\/www.techcoil.com\/glossary\/http-server\/\" rel=\"noopener\" target=\"_blank\">HTTP server<\/a> that will pick up PHP codes and run them to serve <a href=\"https:\/\/www.techcoil.com\/glossary\/http-request\/\" rel=\"noopener\" target=\"_blank\">HTTP requests<\/a> and<\/li>\n<li>the PHP library to interact with the MariaDB server.<\/li>\n<\/ul>\n<h2>Configuring your Raspberry Pi LEMP stack for running your PHP application<\/h2>\n<p>Once you had installed the components that make up your Raspberry Pi LEMP stack, you can then configure the stack to run your PHP application.<\/p>\n<h3>Configuring Nginx to serve requests for your PHP application by default<\/h3>\n<p>Since Nginx is the first to process HTTP requests in a LEMP stack, we need to <a href=\"https:\/\/www.techcoil.com\/blog\/configuring-nginx-for-php-web-applications\/\" rel=\"noopener\" target=\"_blank\">configure Nginx to serve requests for your PHP application<\/a>.<\/p>\n<p>As I had mentioned in <a href=\"https:\/\/www.techcoil.com\/blog\/understanding-the-default-nginx-virtual-host-or-server-configuration\/\" target=\"_blank\" rel=\"noopener\">understanding default Nginx virtual host configurations<\/a>, there is a set of configurations that make Nginx respond to any HTTP requests directed at port 80 of the host computer.<\/p>\n<p>If you just want to serve HTTP requests directed at the <code>.php<\/code> scripts from your PHP application, you can uncomment some configurations in the default Nginx configurations.<\/p>\n<p>Given that, open up the default Nginx configuration file with the following command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo nano \/etc\/nginx\/sites-available\/default\r\n<\/pre>\n<p>Once <code>nano<\/code> loads the file, change:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n# Add index.php to the list if you are using PHP\r\nindex index.html index.htm index.nginx-debian.html;\r\n<\/pre>\n<p>to<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n# Add index.php to the list if you are using PHP\r\nindex index.html index.htm index.php index.nginx-debian.html;\r\n<\/pre>\n<p>And change:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n    # pass PHP scripts to FastCGI server\r\n    #\r\n    #location ~ \\.php$ {\r\n    #   include snippets\/fastcgi-php.conf;\r\n    #\r\n    #   # With php-fpm (or other unix sockets):\r\n    #   fastcgi_pass unix:\/run\/php\/php7.3-fpm.sock;\r\n    #   # With php-cgi (or other tcp sockets):\r\n    #   fastcgi_pass 127.0.0.1:9000;\r\n    #}\r\n<\/pre>\n<p>to:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n# pass PHP scripts to FastCGI server\r\n#\r\nlocation ~ \\.php$ {\r\n    include snippets\/fastcgi-php.conf;\r\n\r\n    # With php-fpm (or other unix sockets):\r\n    fastcgi_pass unix:\/run\/php\/php7.3-fpm.sock;\r\n}\r\n<\/pre>\n<p>When you are done with the changes, press <strong>Ctrl-X<\/strong>, <strong>Y<\/strong> and <strong>Enter<\/strong> to save the changes.<\/p>\n<p>Once you are done with the changes, restart Nginx with the following command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo systemctl restart nginx.service\r\n<\/pre>\n<p>If you want to test whether your Nginx configurations can run PHP application, then you can create a PHP script at <code>\/var\/www\/html\/index.php<\/code>:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo nano \/var\/www\/html\/index.php\r\n<\/pre>\n<p>Once <code>nano<\/code> starts, you can write the following codes into the editor:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n&lt;?php\r\nphpinfo();\r\n<\/pre>\n<p>When you are done with the changes, press <strong>Ctrl-X<\/strong>, <strong>Y<\/strong> and <strong>Enter<\/strong> to save the changes.<\/p>\n<p>At this point in time, you can then use your browser to access http:\/\/&lt;your_raspberry_pi_ip_address&gt; to verify your Nginx configurations for running your PHP application.<\/p>\n<p>Since you had marked <code>index.php<\/code> with the <a href=\"http:\/\/nginx.org\/en\/docs\/http\/ngx_http_index_module.html\" rel=\"noopener\" target=\"_blank\">index module<\/a> in the Nginx configuration, you should be able to see the following web page:<\/p>\n<p><img decoding=\"async\" width=\"972\" height=\"988\" src=\"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/PHP-7.3.9-phpinfo-output-running-on-Raspbian-Buster-Lite-LEMP-stack.gif\" class=\"aligncenter size-full wp-image-1845\" alt=\"PHP 7.3.9 phpinfo output running on Raspbian Buster Lite LEMP stack\"><\/p>\n<p>When you see this page, you can be sure that your Nginx web server is able to pass HTTP requests over to PHP FPM server to run PHP scripts from your PHP application.<\/p>\n<h4>So what does this set of Nginx configurations do?<\/h4>\n<p>In case you are wondering, we had introduced two kinds of configuration changes.<\/p>\n<p>First, by including <code>index.php<\/code> with the <code>index<\/code> module, Nginx will append index.php to the end of request URLs directed at directories. For example, requests made to <strong>http:\/\/192.168.1.114<\/strong> will be redirected to <strong>http:\/\/192.168.1.114\/index.php<\/strong>.<\/p>\n<p>Second, by uncommenting the location block, Nginx will pass HTTP requests that are directed at requests ending with <code>.php<\/code> over to the PHP FPM server. <\/p>\n<p>After instructions in <code>\/etc\/nginx\/snippets\/fastcgi-php.conf<\/code> has been processed, Nginx is then instructed to use <a href=\"http:\/\/nginx.org\/en\/docs\/http\/ngx_http_fastcgi_module.html#fastcgi_pass\" rel=\"noopener\" target=\"_blank\">fastcgi_pass<\/a> to hand over the HTTP request to our PHP FPM server. The PHP FPM server is reachable via the unix socket at <code>\/run\/php\/php7.3-fpm.sock<\/code>.<\/p>\n<h3>Configuring Nginx to serve requests for your PHP application for a domain name<\/h3>\n<p>The earlier section makes Nginx respond to HTTP requests that are directed at any domain name or IP address. <\/p>\n<p>If you want to serve your PHP application for a domain name, then you will need to configure your Nginx differently. <\/p>\n<p>Suppose that we want to serve requests for your PHP application for <strong>abcd1234.com<\/strong>.<\/p>\n<p>Given that requirement, we will first run the following command to create a separate Nginx configuration file:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo nano \/etc\/nginx\/sites-enabled\/abcd1234.com.conf\r\n<\/pre>\n<p>Once <code>nano<\/code> starts up, we then write the following content into the editor:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nserver {\r\n        listen   80;\r\n        ## Your website name goes here.\r\n        server_name abcd1234.com  www.abcd1234.com;\r\n        root \/var\/www\/abcd1234.com;\r\n        ## This should be in your http block and if it is, it's not needed here.\r\n        index index.php;\r\n  \r\n        location \/ {\r\n                try_files $uri $uri\/ \/index.php?$args;\r\n        }\r\n  \r\n        location ~ \\.php$ {\r\n                include fastcgi.conf;\r\n                fastcgi_intercept_errors on;\r\n                fastcgi_pass unix:\/run\/php\/php7.3-fpm.sock;\r\n                fastcgi_buffers 16 16k;\r\n                fastcgi_buffer_size 32k;\r\n        }\r\n}\r\n<\/pre>\n<p>Once you are done with the changes, press <strong>Ctrl-X<\/strong>, <strong>Y<\/strong> and <strong>Enter<\/strong> to save the changes.<\/p>\n<p>Your Nginx server will take this set of configurations after you had restarted it with the following command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo systemctl restart nginx.service\r\n<\/pre>\n<h4>So what does this set of Nginx configurations do?<\/h4>\n<p>For the astute reader, you will have noticed that this set of configurations is quite different to the earlier version.<\/p>\n<p>First, we use <a href=\"http:\/\/nginx.org\/en\/docs\/http\/ngx_http_core_module.html#server_name\" rel=\"noopener\" target=\"_blank\"><code>server_name<\/code><\/a> to tell Nginx that this set of configurations will apply to HTTP requests made to <strong>abcd1234.com<\/strong> and <strong>www.abcd1234.com<\/strong>.<\/p>\n<p>After that, we tell Nginx to look into <strong>\/var\/www\/abcd1234.com<\/strong> for resources to serve incoming HTTP requests.<\/p>\n<p>In addition, we tell Nginx to append <code>index.php<\/code> to the end of URLs directed at directories.<\/p>\n<p>If a HTTP request is made to a URL ending with <strong>.php<\/strong>, we use <a href=\"http:\/\/nginx.org\/en\/docs\/http\/ngx_http_core_module.html#try_files\" rel=\"noopener\" target=\"_blank\"><code>try_files<\/code><\/a> to attempt to serve the HTTP request with a file inside the root directory. In case Nginx is unable to find a file to return as a HTTP response, it will serve the HTTP request by running <code>\/var\/www\/abcd1234.com\/index.php<\/code> through the PHP FPM server.<\/p>\n<p>In such a situation, we will be able to include our request dispatcher logic inside <code>\/var\/www\/abcd1234.com\/index.php<\/code>.<\/p>\n<h3>Creating the MariaDB user and database instance that your PHP application uses<\/h3>\n<p>In order for your application to save data into the MariaDB, you will first need to create a MariaDB user. Therefore, start the MariaDB command line client again with the following command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo mariadb\r\n<\/pre>\n<h4>Creating a MariaDB User<\/h4>\n<p>Once you have started the command line client, you can create a user (anewuser) with the following command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nCREATE USER 'anewuser'@'localhost' IDENTIFIED BY 'password';\r\n<\/pre>\n<h4>Creating a MariaDB instance<\/h4>\n<p>When you want to create a database instance (adatabase), you can then run the following command:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nCREATE DATABASE adatabase;\r\n<\/pre>\n<p>Once you have the database user and instance, you can then grant privileges for your user to access that instance:<\/p>\n<h4>Granting privileges for a MariaDB user to access a MariaDB instance<\/h4>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nGRANT ALL ON adatabase.* TO 'anewuser'@'localhost';\r\n<\/pre>\n<h2>Let's Encrypt your PHP application with a browser-trusted SSL\/TLS certificate<\/h2>\n<p>At this point in time, you will be able to reach your PHP application running on your Raspberry Pi with a browser within the same local network.<\/p>\n<p>So what if you want to access your PHP application from outside your home network via HTTPS? <\/p>\n<p>If your local ISP <strong>provides your home router with a public IP address and allows you to host server applications with that IP address<\/strong>, then you will be able to expose your PHP application to the internet.<\/p>\n<p>Along with <a href=\"https:\/\/letsencrypt.org\/\" rel=\"noopener\" target=\"_blank\">Let's Encrypt<\/a>, you will be able to serve your PHP application with a browser-trusted SSL\/TLS certificate.<\/p>\n<p>Since <a href=\"https:\/\/support.google.com\/webmasters\/answer\/6073543?hl=en\" rel=\"noopener\" target=\"_blank\">Google encourages securing website with HTTPS for better user experience<\/a> and Let's Encrypt gives us free browser-trusted SSL\/TLS certificates, let's see how we can secure your Raspberry Pi PHP application.<\/p>\n<h3>Forwarding port 80 and 443 of your router's public IP address to your Pi's private IP address<\/h3>\n<p>Before your Pi can receive HTTP requests from the internet, you will need to forward port 80 and 443 of your router's public IP address to your Pi's private IP address.<\/p>\n<p>Most routers should have such a feature. For example if you use a Linksys router, you should be able to <a href=\"https:\/\/www.techcoil.com\/blog\/host-web-server-behind-linksys-ea7500-max-stream-ac1900-router\/\" rel=\"noopener\" target=\"_blank\">forward network traffic made to port 80 and 443 to the web server running on your Raspberry Pi<\/a>.<\/p>\n<h3>Installing Certbot on Raspbian Buster Lite for obtaining Let\u2019s Encrypt\u2019s browser-trusted certificates<\/h3>\n<p>In order to use Let's Encrypt facilities, we will need a <a href=\"https:\/\/letsencrypt.org\/docs\/client-options\/\" rel=\"noopener\" target=\"_blank\">ACME client<\/a> to help us get the SSL artefacts from Let's Encrypt. Therefore, <a href=\"https:\/\/www.techcoil.com\/blog\/installing-certbot-on-raspbian-buster-for-obtaining-lets-encrypts-browser-trusted-certificates-for-your-raspberry-pi-server-applications\/\" rel=\"noopener\" target=\"_blank\">install Certbot on Raspbian Buster Lite for obtaining Let\u2019s Encrypt\u2019s browser-trusted certificates<\/a>.<\/p>\n<h3>Configuring Nginx to facilitate Certbot in acquiring the SSL certificate for your domain<\/h3>\n<p>Once you have installed Certbot on Raspbian Buster Lite, configure Nginx to facilitate Certbot in acquiring the SSL certificate for your domain.<\/p>\n<p>Given that, open up <code>abcd1234.com.conf<\/code> again:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo nano \/etc\/nginx\/sites-enabled\/abcd1234.com.conf\r\n<\/pre>\n<p>Once nano loads up your configuration file, add in the following location block:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nlocation ~ \/.well-known {\r\n        allow all;\r\n} \r\n<\/pre>\n<p>inside the server block. After you do so, your configuration file should look like this:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n\r\nserver {\r\n        listen   80;\r\n        ## Your website name goes here.\r\n        server_name abcd1234.com  www.abcd1234.com;\r\n        root \/var\/www\/abcd1234.com;\r\n        ## This should be in your http block and if it is, it's not needed here.\r\n        index index.php;\r\n\r\n        location ~ \/.well-known {\r\n                allow all;\r\n        }   \r\n   \r\n        location \/ {\r\n                try_files $uri $uri\/ \/index.php?$args;\r\n        }\r\n   \r\n        location ~ \\.php$ {\r\n                include fastcgi.conf;\r\n                fastcgi_intercept_errors on;\r\n                fastcgi_pass unix:\/run\/php\/php7.3-fpm.sock;\r\n                fastcgi_buffers 16 16k;\r\n                fastcgi_buffer_size 32k;\r\n        }\r\n}\r\n<\/pre>\n<p>Once you are done with the changes, press <strong>Ctrl-X<\/strong>, <strong>Y<\/strong> and <strong>Enter<\/strong> to save the changes. This set of changes allow Nginx to respond to HTTP requests made by Let's Encrypt servers to confirm that your Certbot is running on the server that serves content for your domain. <\/p>\n<p>Restart your Nginx server so that it takes the new configuration changes:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo systemctl restart nginx.service\r\n<\/pre>\n<h3>Using Certbot to get Let's Encrypt to issue browser-trusted SSL certificate for your domain<\/h3>\n<p>After Nginx is ready to facilitate Certbot in acquiring the SSL certificate artefacts, run the following command to acquire them:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo certbot certonly -a webroot --webroot-path=\/var\/www\/abcd1234.com -d abcd1234.com -d www.abcd1234.com\r\n<\/pre>\n<h3>Generating a strong Diffie-Hellman group for your website<\/h3>\n<p>Once Certbot had fetched the SSL certificate artefacts for your domain, generate a Diffie-Hellman group for Nginx to use for exchanging cryptographic keys with its clients:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo openssl dhparam -out \/etc\/ssl\/certs\/dhparam.pem 2048\r\n<\/pre>\n<h3>Updating the Nginx configurations for serving HTTPS for your PHP application<\/h3>\n<p>At this point in time, you will have the necessary artefacts for Nginx to serve your PHP application over HTTPS. Therefore, update the Nginx configurations to use those artefacts for serving your WordPress site over HTTPS.<\/p>\n<p>Given that, open up <code>abcd1234.com.conf<\/code> again:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nserver {\r\n    listen 80;\r\n    server_name  abcd1234.com www.abcd1234.com;\r\n    return 301 https:\/\/$host$request_uri;\r\n}\r\n\r\nserver {\r\n        ssl on;\r\n        ssl_certificate \/etc\/letsencrypt\/live\/abcd1234.com\/fullchain.pem;\r\n        ssl_certificate_key \/etc\/letsencrypt\/live\/abcd1234.com\/privkey.pem;\r\n        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\r\n        ssl_prefer_server_ciphers on;\r\n        ssl_dhparam \/etc\/ssl\/certs\/dhparam.pem;\r\n        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';\r\n        ssl_session_timeout 1d;\r\n        ssl_session_cache shared:SSL:50m;\r\n        ssl_stapling on;\r\n        ssl_stapling_verify on;\r\n        add_header Strict-Transport-Security max-age=15768000;\r\n\r\n        listen   443;\r\n        \r\n        server_name abcd1234.com  www.abcd1234.com;\r\n        root \/var\/www\/abcd1234.com;\r\n        ## This should be in your http block and if it is, it's not needed here.\r\n        index index.php;\r\n  \r\n        location ~ \/.well-known {\r\n                allow all;\r\n        }   \r\n  \r\n        location \/ {\r\n                try_files $uri $uri\/ \/index.php?$args;\r\n        }\r\n  \r\n        location ~ \\.php$ {\r\n                include fastcgi.conf;\r\n                fastcgi_intercept_errors on;\r\n                fastcgi_pass local_php;\r\n                fastcgi_buffers 16 16k;\r\n                fastcgi_buffer_size 32k;\r\n        }\r\n\r\n}\r\n<\/pre>\n<p>Once you had done so, press <strong>Ctrl-X<\/strong>, <strong>Y<\/strong> and <strong>Enter<\/strong> to save the changes.<\/p>\n<p>Restart your Nginx server to take the new configurations:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo systemctl restart nginx.service\r\n<\/pre>\n<p>Once your Nginx server had restarted, it will then serve your PHP application with a browser-trusted certificate.<\/p>\n<p><img decoding=\"async\" width=\"600\" height=\"900\" src=\"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/How-to-setup-a-Raspberry-Pi-LEMP-server-with-Raspbian-Buster-Lite-for-running-PHP-applications.jpg\" alt=\"How to setup a Raspberry Pi LEMP server with Raspbian Buster Lite for running PHP applications\" class=\"aligncenter size-full wp-image-1862\" \/><\/p>\n\n      <ul id=\"social-sharing-buttons-list\">\n        <li class=\"facebook\">\n          <a href=\"https:\/\/www.facebook.com\/sharer\/sharer.php?u=https%3A%2F%2Fwp.me%2Fp245TQ-tv\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n            <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Facebook.png\" alt=\"Facebook icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"twitter\">\n          <a href=\"https:\/\/twitter.com\/intent\/tweet?text=&url=https%3A%2F%2Fwp.me%2Fp245TQ-tv&via=Techcoil_com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Twitter.png\" alt=\"Twitter icon\"> Tweet\n          <\/a>\n        <\/li>\n        <li class=\"linkedin\">\n          <a href=\"https:\/\/www.linkedin.com\/shareArticle?mini=1&title=&url=https%3A%2F%2Fwp.me%2Fp245TQ-tv&source=https:\/\/www.techcoil.com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/linkedin.png\" alt=\"Linkedin icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"pinterest\">\n          <a href=\"https:\/\/pinterest.com\/pin\/create\/button\/?url=https%3A%2F%2Fwww.techcoil.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1829&description=\" class=\"pin-it-button\" target=\"_blank\" role=\"button\" rel=\"nofollow\" count-layout=\"horizontal\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Pinterest.png\" alt=\"Pinterest icon\"> Save\n          <\/a>\n        <\/li>\n      <\/ul>\n    ","protected":false},"excerpt":{"rendered":"<p>Many useful applications are written in <a href=\"https:\/\/www.php.net\/\" rel=\"noopener\" target=\"_blank\">PHP<\/a> backed by <a href=\"https:\/\/mariadb.org\/\" rel=\"noopener\" target=\"_blank\">MariaDB<\/a>\/<a href=\"https:\/\/www.mysql.com\/\" rel=\"noopener\" target=\"_blank\">MySQL<\/a> for data persistency.<\/p>\n<p>When you wondering what you can use a Raspberry Pi for, one way is to turn it into a LEMP server for hosting PHP applications.<\/p>\n<p>With this in mind, let us look at how we can setup a Raspberry Pi LEMP server with Raspbian Buster Lite for running PHP applications.<\/p>\n","protected":false},"author":1,"featured_media":1495,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"footnotes":""},"categories":[4],"tags":[446,9,225,13,444,243,240,412,678,438],"jetpack_featured_media_url":"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/Raspberry-Pi-LEMP-Linux-Nginx-MariaDB-PHP.jpg","jetpack_shortlink":"https:\/\/wp.me\/p245TQ-tv","jetpack-related-posts":[],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/1829"}],"collection":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/comments?post=1829"}],"version-history":[{"count":0,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/1829\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media\/1495"}],"wp:attachment":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media?parent=1829"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/categories?post=1829"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/tags?post=1829"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}