Configure Web Server for Magento [Ubuntu, Nginx…] (Part 1)

There are some default good practice when installing/configure a server and I think is good to follow them and improve where is possible.

I tend to use [ apt ] instead of  [ apt-get ] as they are almost the same: apt is designed for end-users (human) and its output may be changed between versions > Means the output is more reach and pleasant.

All the commands should be run with sudo so it is better to elevate your user from beginning  to root privileges  

# take the power into your hands :)
sudo su
  1. Updates: Start with getting the server updated:
    # update the repository
    apt update
    
    # update the applications/services
    apt upgrade
  2. Add normal user (will not have sudo permissions)
    # This will add a user with a directory in the /home folder
    # it is good to have a full user as later you can setup an SSH key
    adduser developer
  3. SSH: harden a bit the SSH service:
    ### Change SSH PORT ###
    # Open the file
    vim /etc/ssh/sshd_config
    
    # Edit the following line(save and close the file), 
    # we are using the port 3451
    Port 3451
    
    ### Disable ROOT logins ###
    # SSH server settings are stored in the 
    #       /etc/ssh/sshd_config 
    # file. To disable root logins, make sure you have the following entry:
    PermitRootLogin no
    
    ### Limit User Logins ###
    AllowUsers developer
    
    ### Do not use Password authentication ###
    PasswordAuthentication no
    
    
    ### Generate Public/Private Keys for Authentication ###
    ssh-keygen -t rsa 
    
    # if you have more keys to add, load all of them into this file
    ~/.ssh/authorized_keys
    
    # Restart the SSH service and test it by opening a new terminal window (don't 
    # close the current one as you can lock you outside of your server)
    systemctl restart ssh
  4. UFW: First of all, make sure you have the minimum security in place ( later will follow fail2ban and possible CSF & LFD)
    # install the UFW 
    apt-get install ufw
    
    # whitelist your IP to connect to SSH before enable UFW
    ufw allow from 8.8.8.8 to any port 3451
    
    # enable UFW, (again, don't disconnect from the current 
    # connection, just get a new one and test if you can connect)
    ufw enable

Next will go all the needed services

  1. Nginx: I strongly believe you have to have the last stable version that fits your needs and as the ubuntu repository takes years to update itself I tend to add official repositories to speed up the things a little (if you consider to have PageSpeed then Nginx will have to be build from source).
    # check the possible version that can be installed
    # apt search nginx - gives too much information 
    # the apt-cache says the version 1.9 is available, while this is good 
    # I would still prefer the last one which is 1.10.3
    apt-cache policy nginx 
    

    You can add Nginx official repository by following their instructions page or these instructions:

    # download the KEY
    wget http://nginx.org/keys/nginx_signing.key
    
    # and add it to APT program keyring 
    sudo apt-key add nginx_signing.key
    
    # create a file and add the repo lines.
    # Usually they can go into:
    #      /etc/apt/source.list 
    # but I think it would be better to keep them separate 
    # into a file and add them into [source.list.d] folder
    vim /etc/apt/source.list.d/nginx.list
    
    # add the following lines and save it
    deb http://nginx.org/packages/ubuntu/ xenial nginx
    deb-src http://nginx.org/packages/ubuntu/ xenial nginx
    
    # and update the repo so the new location will be taken in account
    apt-get update
    
    # check again the available version of Nginx and it is: 1.10.3
    apt-cache policy nginx

    Now, the last step is just to install Nginx 

    # i'm using [apt] but it can also be used [apt-get]
    apt install nginx 
    
    # check what version it is installed: 
    # returns: nginx version: nginx/1.10.3
    nginx -v
    
    # Allow Nginx ports into UFW firewall to be accessed externally:
    sudo ufw allow from any to any port 80 
    sudo ufw allow from any to any port 443
  2.  PHP: the entire environment is for Magento 2 which at the moment is not working properly with PHP 7.1 because of mcrypt deprecation. But we still can update the APT to the last PHP official repo (Ondrej Surey):
    # we can update it in 2 ways:
    # 1. through add-apt-repository
    #        for this we have to run first:
                 sudo apt-get install software-properties-common python-software-properties
    # 2. similar to Nginx by adding the lines into source list
    #
    # The firs one:
    sudo add-apt-repository ppa:ondrej/php
    sudo apt-get update
    
    
    # the second method is to get the KEY
    # from the section: Technical details about this PPA
    # and save it on you server
    
    # install the key into the system
    sudo apt-key add php_sign.key
    
    # create a file into the following location 
    vim /etc/apt/sources.list.d/php.list
    
    # add the source lines into it and save 
    deb http://ppa.launchpad.net/ondrej/php/ubuntu xenial main 
    deb-src http://ppa.launchpad.net/ondrej/php/ubuntu xenial main 
    
    # update the APT 
    sudo apt-get update
    
    #check available PHP version 
    apt-cache policy php
    
    # I'm getting both of them the 7.0 and 7.1 and 
    # if I check for older version like 5.6 is also there and can be installed 
    

    And here goes the command that will install the PHP7.0 (pay attention, this is not the default version):

    # All the additional libraries are for PHP 7.0
    sudo apt-get install php7.0-fpm php7.0-cli php7.0-mysql php7.0-curl php7.0-gd \
    php7.0-imagick php7.0-intl php7.0-mbstring php-soap php7.0-xmlrpc php7.0-xsl \
    mcrypt php7.0-mcrypt php7.0-dev zip php7.0-zip
  3. MySQL 5.7: the installation is quite simple just make sure to save the root password 🙂
    sudo apt install mysql-server mysql-client
  4. Redis: is very good as a cache DB or even session manager, is fast and reliable but the problem is that in Ubuntu is all the time old
    # redis "official" repo
    sudo add-apt-repository ppa:chris-lea/redis-server
    
    #refresh the repos
    sudo apt-get update
    
    #install Redis Server
    apt install redis-server
  5. Postfix: as Magento will  need to send emails we need an SMTP server and the most comfortable and reliable is Postfix
    # Before installing, check the hostname and the domain you want to add
    hostname
    
    # change hostname
    hostname new-domain.com
    
    # Ubuntu has the latest version so you can install directly 
    apt-get install postfix
  6. Elasticsearch:
    #get the Elasticsearch PGP key
    wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
    Installing from the APT repository

    You may need to install the apt-transport-https package on Debian(Ubuntu) before proceeding:

    sudo apt-get install apt-transport-https

    Save the repository definition to /etc/apt/sources.list.d/elastic-5.x.list:

    echo "deb https://artifacts.elastic.co/packages/5.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-5.x.list
    Next step, just install elasticsearch
    # update packages list
    sudo apt-get update 
    
    # install Elstaisearch
    sudo apt-get install elasticsearch

    Running Elasticsearch with systemd (Ubuntu 16.04)

    # This will configure Elasticsearch to start automatically 
    # when the system will boot up
    sudo /bin/systemctl daemon-reload
    sudo /bin/systemctl enable elasticsearch.service
    
    # Elasticsearch can be started and stoped as follows
    sudo systemctl start elasticsearch.service
    sudo systemctl start elasticsearch.service 
    
    ## OR the old way
    /etc/init.d/elasticsearch start
    /etc/init.d/elasticsearch stop

    When systemd logging is enabled, the logging information are available using the journalctl commands:

    To tail the journal:

    sudo journalctl -f

    To list journal entries for the elasticsearch service:

    sudo journalctl --unit elasticsearch

    To list journal entries for the elasticsearch service starting from a given time:

    sudo journalctl --unit elasticsearch --since  "2016-10-30 18:17:16"
  7. NPM: Install the Node.js package manager (npm)
    sudo apt-get update
    
    sudo apt-get install nodejs
    
    sudo apt-get install npm

This would be the first part, in the second we will look into tools more common to magento 2.