π€ LEMP w/ PHP7.X & MariaDB on Ubuntu 16/17/18 x64
Last update: 04/09/2020, tested on Ubuntu 20.04 with PHP7.4
If you are looking for the older versions of the PHP, π at branches php7.2 or php7.1
π₯ Looking for cool t-shirts for web developers?
Check out my Devnull Clothing.
This document is a list of notes when installing several Ubuntu LEMP instances w/ PHP7.4. With some sort of imagination it can be considered as a step-by-step tutorial of really basic installation process of LEMP. I wrote it mainly for myself, but feel free to use it. The LEMP consists of:
To automatically install essentials, you can use the π startup.sh
script by downloading it and calling it with sudo sudo ./startup.sh
.
The file is deleted automatically.
If you want to have the installation in your hands, follow the manual installation. π
adduser admin
echo "admin ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
su - admin
exit
su - admin
mkdir .ssh
nano .ssh/authorized_keys
chmod 700 .ssh/
chmod 600 .ssh/authorized_keys
# Optional
echo "PasswordAuthentication no" | sudo tee --append /etc/ssh/sshd_config
sudo systemctl reload sshd
Or disable the password for some users only (admin, user_tld)
# Optional
sudo nano /etc/ssh/sshd_config
> Match User admin,user_tld
> PasswordAuthentication no
sudo systemctl reload sshd
sudo echo 'LC_ALL="en_US.UTF-8"' >> /etc/environment
# Log out & in
sudo dpkg-reconfigure tzdata
sudo apt-get -y dist-upgrade ; sudo apt-get -y update ; sudo apt-get -y upgrade
sudo apt-get -y install unattended-upgrades software-properties-common apache2-utils fail2ban
sudo dpkg-reconfigure -plow unattended-upgrades
sudo apt-get -y install mc htop
rm
with trash
This is optional but recommended. rm
is a dangerous command therefore is recommended to replace it by safer version trash
that instead of removing files moving them to a trash. More info here.
$ sudo apt-get -y install trash-cli
$ echo "alias rm='echo \"This is not the command you are looking for. Use <trash> instead.\"; false'" | sudo tee --append
Open SSH port only.
sudo ufw allow 22 #OpenSSH
sudo ufw allow 80 #http
sudo ufw allow 443 #https
yes | sudo ufw enable
sudo ufw status
You can skip steps 1-4 by downloading and running the lemp.sh
script:
wget https://raw.githubusercontent.com/lucien144/lemp-stack/master/lemp.sh && chmod u+x lemp.sh
sudo ./lemp.sh
sudo add-apt-repository -y ppa:nginx/development && sudo apt-get update
sudo apt-get -y install nginx
sudo apt-get -y install mariadb-server # Or MySQL: sudo apt-get install mysql-server
sudo service mysql stop # Stop the MySQL if is running.
sudo mysql_install_db
sudo service mysql start
sudo mysql_secure_installation
sudo add-apt-repository -y ppa:ondrej/php && sudo apt-get update
sudo apt-get -y install php7.4
sudo apt-cache search php7.4-*
sudo apt-get -y install php7.4-fpm php7.4-curl php7.4-gd php7.4-json php7.4-mysql php7.4-sqlite3 php7.4-pgsql php7.4-bz2 php7.4-mbstring php7.4-soap php7.4-xml php7.4-zip
php -v
/etc/nginx/nginx.conf
worker_processes auto;
events {
use epoll;
worker_connections 1024; # ~ RAM / 2
multi_accept on;
}
cd /etc/nginx/sites-available
sudo rm default
sudo wget https://raw.githubusercontent.com/lucien144/lemp-stack/master/nginx/sites-available/default
cd /etc/nginx/conf.d
sudo wget https://raw.githubusercontent.com/lucien144/lemp-stack/master/nginx/conf.d/gzip.conf
sudo mkdir -p /etc/nginx/conf.d/server/
cd /etc/nginx/conf.d/server/
sudo wget https://raw.githubusercontent.com/lucien144/lemp-stack/master/nginx/conf.d/server/1-common.conf
sudo nginx -t && sudo nginx -s reload
Steps 1. - 9. can be skipped by calling the add-vhost.sh
. Just download add-vhost.sh
, chmod u+x ./add-vhost.sh
and call it sudo ./add-vhost.sh
.
The file is deleted automatically.
$ cd ~ && wget https://raw.githubusercontent.com/lucien144/lemp-stack/master/add-vhost.sh && chmod u+x add-vhost.sh
$ sudo ./add-vhost.sh
sudo mkdir -p /var/www/vhosts/new-website.tld/{web,logs,ssl}
$ sudo groupadd new-website
$ sudo useradd -g new-website -d /var/www/vhosts/new-website.tld new-website
$ sudo passwd new-website
$ sudo usermod -s /bin/bash new-website
You can switch users by using sudo su - new-website
sudo chown -R new-website:new-website /var/www/vhosts/new-website.tld
sudo chmod -R 0775 /var/www/vhosts/new-website.tld
sudo nano /etc/php/7.4/fpm/pool.d/new-website.tld.conf
[new-website]
user = new-website
group = new-website
listen = /run/php/php7.4-fpm-new-website.sock
listen.owner = www-data
listen.group = www-data
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = off
pm = dynamic
pm.max_children = 5 # The hard-limit total number of processes allowed
pm.start_servers = 2 # When nginx starts, have this many processes waiting for requests
pm.min_spare_servers = 1 # Number spare processes nginx will create
pm.max_spare_servers = 3 # Number spare processes attempted to create
pm.max_requests = 500
chdir = /
pm.max_children
ps -A -o pid,rss,command | grep php-fpm
-> second row in bytes
pm.start_servers
, pm.min_spare_servers
, pm.max_spare_servers
pm.start_servers
== number of CPUspm.min_spare_servers
= pm.start_servers
/ 2pm.max_spare_servers
= pm.start_servers
* 3sudo service php7.4-fpm restart
ps aux | grep new-site
sudo nano /etc/nginx/sites-available/new-site.tld
server {
listen 80;
root /var/www/vhosts/new-site.tld/web;
index index.php index.html index.htm;
server_name www.new-site.tld new-site.tld;
include /etc/nginx/conf.d/server/1-common.conf;
access_log /var/www/vhosts/new-site.tld/logs/access.log;
error_log /var/www/vhosts/new-site.tld/logs/error.log warn;
location ~ \.php$ {
try_files $uri $uri/ /index.php?$args;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.4-fpm-new-site.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
cd /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/new-site.tld new-site.tld
sudo nginx -t && sudo nginx -s reload
sudo mysql
> CREATE DATABASE newwebsite_tld;
> CREATE USER 'newwebsite_tld'@'localhost' IDENTIFIED BY 'password';
> GRANT ALL PRIVILEGES ON newwebsite_tld.* TO 'newwebsite_tld'@'localhost';
> FLUSH PRIVILEGES;
If you want to have nice git-aware prompt with some handy aliases, use this:
sudo su virtualhostuser
cd ~
wget https://gist.githubusercontent.com/lucien144/56fbb184b1ec01fae1adf2e7abb626b6/raw/0928548acb2ff1618054069f0ae7e60f92d76cc3/install.sh && cat install.sh | bash
bash
More information about aliases and other in this gist.
sudo apt-get install git
Adminer is a mostly MySQL database management tool. It's really tiny, simple & easy to use.
cd /etc/nginx/conf.d/server/
sudo wget https://raw.githubusercontent.com/lucien144/lemp-stack/master/nginx/conf.d/server/4-adminer.conf
sudo mkdir -p /var/www/html/adminer/
cd /var/www/html/adminer/
sudo wget https://www.adminer.org/latest.php -O index.php
sudo chmod a+x index.php
sudo htpasswd -c .htpasswd user
sudo nginx -t && sudo nginx -s reload
Adminer is now ready at http://{server.ip}/adminer/
Also, don't forget to change the username π.
In case you cannot send emails from PHP and getting error (tail /var/log/mail.log
) Network is unreachable
, you need to switch Postfix from IPv6 to IPv6.
sudo apt-get install postfix
sudo nano /etc/postfix/main.cf
Now change the line inet_protocols = all
to inet_protocols = ipv4
and restart postfix by sudo /etc/init.d/postfix restart
.
You can also check if you have opened port 25 by netstat -nutlap | grep 25
apt-get install munin-node munin
#host 127.0.0.1
in /etc/munin/munin-node.conf
/etc/munin/munin-node.conf
[nginx*]
env.url http://localhost/nginx_status
/etc/nginx/sites-available/default
sudo nano /etc/nginx/sites-available/default
# Change listen 80 default_server; to
listen 80
#Change listen [::]:80 default_server; to
listen [::]:80
# Add settings for stub status to server {}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
# Add setting to access stats online
location /stats {
allow YOUR.IP.ADDRESS;
deny all;
alias /var/cache/munin/www/;
}
cd /usr/share/munin/plugins
sudo wget -O nginx_connection_request https://raw.github.com/munin-monitoring/contrib/master/plugins/nginx/nginx_connection_request
sudo wget -O nginx_status https://raw.github.com/munin-monitoring/contrib/master/plugins/nginx/nginx_status
sudo wget -O nginx_memory https://raw.github.com/munin-monitoring/contrib/master/plugins/nginx/nginx_memory
sudo chmod +x nginx_request
sudo chmod +x nginx_status
sudo chmod +x nginx_memory
sudo ln -s /usr/share/munin/plugins/nginx_request /etc/munin/plugins/nginx_request
sudo ln -s /usr/share/munin/plugins/nginx_status /etc/munin/plugins/nginx_status
sudo ln -s /usr/share/munin/plugins/nginx_memory /etc/munin/plugins/nginx_memory
sudo service munin-node restart
Install PHP extension
sudo apt-get install php-amqp
Install RabbitMQ
echo 'deb http://www.rabbitmq.com/debian/ testing main' | sudo tee /etc/apt/sources.list.d/rabbitmq.list
wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get install rabbitmq-server
sudo service rabbitmq-server status
sudo rabbitmq-plugins enable rabbitmq_management
sudo ufw allow 15672
sudo rabbitmqctl add_user admin *********
sudo rabbitmqctl set_user_tags admin administrator
sudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
sudo rabbitmqctl delete_user guest
sudo service rabbitmq-server restart
.ez
plugin to /usr/lib/rabbitmq/lib/rabbitmq_server-{version}/plugins
sudo rabbitmq-plugins enable {plugin name}
sudo apt-get install supervisor
echo "
[inet_http_server]
port=9001
username=admin
password=*********" | sudo tee --append /etc/supervisor/supervisord.conf
sudo service supervisor reload
sudo ufw allow 9001
The interface should be available on http://{SERVER_IP}:9001/
sudo apt-get install nodejs
sudo apt-get install npm
If you are getting error /usr/bin/env: βnodeβ: No such file or directory
run
sudo ln -s /usr/bin/nodejs /usr/bin/node
wget https://raw.githubusercontent.com/composer/getcomposer.org/76a7060ccb93902cd7576b67264ad91c8a2700e2/web/installer -O - -q | php -- --quiet
sudo mv composer.phar /usr/local/bin/composer
Reference: https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.