Skip to content

Instantly share code, notes, and snippets.

@justinhartman
Last active July 11, 2023 08:23
Show Gist options
  • Save justinhartman/a35839f06a03a1929aff27fdf15181d6 to your computer and use it in GitHub Desktop.
Save justinhartman/a35839f06a03a1929aff27fdf15181d6 to your computer and use it in GitHub Desktop.

Revisions

  1. justinhartman revised this gist Dec 16, 2020. 4 changed files with 127 additions and 20 deletions.
    9 changes: 6 additions & 3 deletions 0_introduction.md
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,12 @@
    # How To Install Linux, Nginx, MySQL, PHP on an Ubuntu Azure Virtual Machine
    # How To Install Nginx, MySQL, PHP, SFTP on an Ubuntu Azure Virtual Machine

    This series of documents will configure and setup a Linux, Nginx, MySQL, and
    This series of documents will configure and setup a Nginx, MySQL, and
    PHP (LEMP) server on a basic `Standard B1s (1 vcpus, 1 GiB memory)` Ubuntu
    16.04 or 18.04 LTS Virtual Machine on Microsoft Azure.

    This will also install other useful packages and configurations for SFTP
    and a fully automated SSL service using certbot for Let's Encrypt.

    The `B1s` is Azure's entry level Linux VM and only comes with 1 GiB memory so
    you need to optimise the install and configuration to maximise the server to
    your advantage.
    @@ -12,7 +15,7 @@ These documents take you through each step of the configuration from:

    1. [General Setup][gen]
    1. [Creating swap on Azure Ubuntu VM][swap]
    1. [Install Linux, Nginx, MySQL, and PHP][lemp]
    1. [Install Nginx, MySQL, and PHP (LEMP)][lemp]
    1. [Create a new nginx vhost][vhost]
    1. [Setup Let's Encrypt SSL certificates][ssl]
    1. [Setup SFTP server][sftp]
    61 changes: 50 additions & 11 deletions 3_install-lemp.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Install Linux, Nginx, MySQL, and PHP
    # Install Nginx, MySQL, and PHP (LEMP)

    There are three steps to install the LEMP server and then there are some configuration changes which you need to do.

    @@ -38,8 +38,8 @@ mysql> exit
    $ sudo apt-get update
    $ sudo apt -y install software-properties-common
    $ sudo add-apt-repository ppa:ondrej/php
    $ sudo apt-get update
    $ sudo apt-get install php7.4-{fpm,cli,apc,bcmath,bz2,curl,gd,imagick,intl,mbstring,mysql,zip}
    $ sudo apt update
    $ sudo apt -y install php7.4-{fpm,cli,apc,bcmath,bz2,curl,gd,imagick,intl,memcached,mbstring,mysql,xml,zip}
    $ sudo systemctl start php7.4-fpm
    $ sudo systemctl enable php7.4-fpm
    ```
    @@ -54,24 +54,63 @@ Change these values:

    ```ini
    cgi.fix_pathinfo=0
    max_execution_time=120
    max_input_time=120
    post_max_size=128M
    upload_max_filesize=128M
    post_max_size=256M
    upload_max_filesize=256M
    date.timezone=Africa/Johannesburg
    # Add this for opcache support
    opcache.enable=1
    opcache.memory_consumption=128
    [opcache]
    opcache.memory_consumption=256
    opcache.max_accelerated_files=10000
    opcache_revalidate_freq=100
    opcache.validate_timestamps=120
    opcache.error_log=/var/log/opcache-errors.log
    [apc]
    apc.shm_size=128M
    apc.stat=1
    ; Relative to the number of cached files (you may need to watch your stats for
    ; a day or two to find out a good number).
    apc.num_files_hint=7000
    ; The number of seconds a cache entry is allowed to idle in a slot before APC
    ; dumps the cache.
    apc.ttl=7200
    apc.user_ttl=7200
    apc.include_once_override=0
    ; Allow 2 seconds after a file is created before it is cached to prevent users
    ; from seeing half-written/weird pages.
    apc.file_update_protection=2
    ; Ignore files
    apc.filters = "/var/www/html/apc.php"
    apc.cache_by_default=1
    apc.use_request_time=1
    apc.slam_defense=0
    apc.stat_ctime=0
    apc.canonicalize=1
    apc.write_lock=1
    apc.report_autofilter=0
    apc.rfc1867=0
    apc.rfc1867_prefix=upload_
    apc.rfc1867_name=APC_UPLOAD_PROGRESS
    apc.rfc1867_freq=0
    apc.rfc1867_ttl=3600
    apc.lazy_classes=0
    apc.lazy_functions=0
    ```

    ```console
    $ sudo systemctl reload php7.4-fpm
    $ sudo systemctl reload nginx
    ```

    ### Configure php-fpm.conf

    ```console
    $ sudo nano /etc/php/7.4/fpm/php-fpm.conf
    ```

    ```ini
    emergency_restart_threshold 10
    emergency_restart_interval 1m
    process_control_timeout 10s
    ```

    ### Configure nginx

    ```console
    1 change: 1 addition & 0 deletions 4_new-vhost.md
    Original file line number Diff line number Diff line change
    @@ -7,6 +7,7 @@ $ sudo nano /etc/nginx/sites-available/example.com
    ```nginx
    server {
    listen 80;
    listen [::]:80;
    root /var/www/example.com;
    index index.php index.html index.htm index.nginx-debian.html;
    server_name example.com www.example.com;
    76 changes: 70 additions & 6 deletions 5_setup-ssl.md
    Original file line number Diff line number Diff line change
    @@ -1,15 +1,79 @@
    # Setup Let's Encrypt SSL certificates

    ```console
    $ sudo add-apt-repository ppa:certbot/certbot
    $ sudo apt-get update
    $ sudo apt-get install python-certbot-nginx
    $ sudo certbot --nginx -d example.com -d www.example.com # domains must be added to nginx vhost
    $ sudo certbot renew --dry-run
    $ sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048
    $ sudo mkdir -p /var/www/_letsencrypt
    $ sudo chown www-data /var/www/_letsencrypt
    $ sudo certbot certonly --webroot -d example.com -d www.example.com --email [email protected] -w /var/www/_letsencrypt -n --agree-tos --force-renewal
    Saving debug log to /var/log/letsencrypt/letsencrypt.log
    Plugins selected: Authenticator webroot, Installer None
    Obtaining a new certificate
    Performing the following challenges:
    http-01 challenge for example.com
    Using the webroot path /var/www/_letsencrypt for all unmatched domains.
    Waiting for verification...
    Cleaning up challenges

    IMPORTANT NOTES:
    - Congratulations! Your certificate and chain have been saved at:
    /etc/letsencrypt/live/example.com/fullchain.pem
    Your key file has been saved at:
    /etc/letsencrypt/live/example.com/privkey.pem
    Your cert will expire on 2022-02-22. To obtain a new or tweaked
    version of this certificate in the future, simply run certbot
    again. To non-interactively renew *all* of your certificates, run
    "certbot renew"
    ```

    ## Configure Host

    ```console
    $ sudo nano /etc/nginx/sites-available/example.com
    ```

    Add (or change) the following SSL directives in the Nginx host:

    ```nginx
    server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    }
    server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    # ACME-challenge
    location ^~ /.well-known/acme-challenge/ {
    root /var/www/_letsencrypt;
    }
    # Redirect to HTTPS
    location / {
    return 301 https://$host$request_uri;
    }
    }
    ```

    ## Reload Nginx

    ```console
    $ sudo nginx -t && sudo systemctl reload nginx
    ```

    ## Adding new domains
    ## Renew Certificates

    Configure Certbot to reload NGINX when it successfully renews certificates:

    ```console
    $ sudo certbot --nginx -d example-two.com -d www.example-two.com
    $ echo -e '#!/bin/bash\nnginx -t && systemctl reload nginx' | sudo tee /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh
    $ sudo chmod a+x /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh
    $ sudo nginx -t && sudo systemctl reload nginx
    ```
  2. justinhartman revised this gist Dec 7, 2020. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions 3_install-lemp.md
    Original file line number Diff line number Diff line change
    @@ -54,6 +54,8 @@ Change these values:

    ```ini
    cgi.fix_pathinfo=0
    max_execution_time=120
    max_input_time=120
    post_max_size=128M
    upload_max_filesize=128M
    date.timezone=Africa/Johannesburg
  3. justinhartman revised this gist Aug 17, 2020. 7 changed files with 11 additions and 9 deletions.
    6 changes: 3 additions & 3 deletions 0_introduction.md
    Original file line number Diff line number Diff line change
    @@ -13,10 +13,10 @@ These documents take you through each step of the configuration from:
    1. [General Setup][gen]
    1. [Creating swap on Azure Ubuntu VM][swap]
    1. [Install Linux, Nginx, MySQL, and PHP][lemp]
    1. [Setup a new nginx vhost][vhost]
    1. [Create a new nginx vhost][vhost]
    1. [Setup Let's Encrypt SSL certificates][ssl]
    1. [Setup SFTP][sftp]
    1. [Install and Configure phpMyAdmin][pma]
    1. [Setup SFTP server][sftp]
    1. [Download and Configure phpMyAdmin][pma]

    These instructions assume you have:

    2 changes: 1 addition & 1 deletion 1_general.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # General Setup

    These are a series of specific commands to configure the Ubuntu server for our environment.
    These are a series of specific commands to configure the Ubuntu server for our environment. You may not need to do these.

    ```console
    $ sudo locale-gen en_GB.UTF-8 # fix locales
    4 changes: 3 additions & 1 deletion 3_install-lemp.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,6 @@
    # Install LEMP
    # Install Linux, Nginx, MySQL, and PHP

    There are three steps to install the LEMP server and then there are some configuration changes which you need to do.

    ## Step 1 - Install Nginx

    2 changes: 1 addition & 1 deletion 4_new-vhost.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Setup a new nginx vhost
    # Create a new nginx vhost

    ```console
    $ sudo nano /etc/nginx/sites-available/example.com
    2 changes: 1 addition & 1 deletion 5_setup-ssl.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Setup Let's Encrypt
    # Setup Let's Encrypt SSL certificates

    ```console
    $ sudo add-apt-repository ppa:certbot/certbot
    2 changes: 1 addition & 1 deletion 6_sftp-setup.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Setup SFTP
    # Setup SFTP server

    This uses public/private SSH key for authentication. Your user will only be able to write files in /var/www.

    2 changes: 1 addition & 1 deletion 7_phpmyadmin.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Install and Configure phpMyAdmin
    # Download and Configure phpMyAdmin

    ```console
    $ cd /var/www/html
  4. justinhartman revised this gist Aug 17, 2020. 2 changed files with 42 additions and 1 deletion.
    38 changes: 38 additions & 0 deletions 0_introduction.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    # How To Install Linux, Nginx, MySQL, PHP on an Ubuntu Azure Virtual Machine

    This series of documents will configure and setup a Linux, Nginx, MySQL, and
    PHP (LEMP) server on a basic `Standard B1s (1 vcpus, 1 GiB memory)` Ubuntu
    16.04 or 18.04 LTS Virtual Machine on Microsoft Azure.

    The `B1s` is Azure's entry level Linux VM and only comes with 1 GiB memory so
    you need to optimise the install and configuration to maximise the server to
    your advantage.

    These documents take you through each step of the configuration from:

    1. [General Setup][gen]
    1. [Creating swap on Azure Ubuntu VM][swap]
    1. [Install Linux, Nginx, MySQL, and PHP][lemp]
    1. [Setup a new nginx vhost][vhost]
    1. [Setup Let's Encrypt SSL certificates][ssl]
    1. [Setup SFTP][sftp]
    1. [Install and Configure phpMyAdmin][pma]

    These instructions assume you have:

    1. Created a VM instance on Azure [by going to this link][add-vm].
    1. Selected either `Ubuntu Server 18.04 LTS - Gen 1` or
    `Ubuntu Server 16.04 LTS - Gen 1` for your server **Image**.
    1. Selected a `Standard_B1s` (or higher) **Size** for your VM.
    1. Used `SSH public key` for your authentication method to the VM.
    1. Enabled ports `22`, `80`, and `443` under the **Select inbound ports**
    setting.

    [gen]: #file-1_general-md
    [swap]: #file-2_azure-ubuntu-vm-swap-md
    [lemp]: #file-3_install-lemp-md
    [vhost]: #file-4_new-vhost-md
    [ssl]: #file-5_setup-ssl-md
    [sftp]: #file-6_sftp-setup-md
    [pma]: #file-7_phpmyadmin-md
    [add-vm]: https://portal.azure.com/#create/Microsoft.VirtualMachine
    5 changes: 4 additions & 1 deletion 6_sftp-setup.md
    Original file line number Diff line number Diff line change
    @@ -16,13 +16,16 @@ $ sudo chown -R FTPUSER:sftp /home/FTPUSER/.ssh
    $ sudo nano /etc/ssh/sshd_config
    ```

    ```config
    ```conf
    PubkeyAuthentication yes
    Match group sftp
    X11Forwarding no
    AllowAgentForwarding no
    AllowTcpForwarding no
    ForceCommand internal-sftp
    ```

    ```console
    $ sudo service ssh restart
    ```

  5. justinhartman revised this gist Aug 17, 2020. 1 changed file with 70 additions and 0 deletions.
    70 changes: 70 additions & 0 deletions 7_phpmyadmin.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,70 @@
    # Install and Configure phpMyAdmin

    ```console
    $ cd /var/www/html
    $ sudo -u www-data mkdir phpmyadmin
    $ sudo -u www-data wget https://files.phpmyadmin.net/phpMyAdmin/4.9.5/phpMyAdmin-4.9.5-english.tar.gz
    $ sudo -u www-data tar -zxf phpMyAdmin-4.9.5-english.tar.gz -C phpmyadmin --strip-components 1
    $ sudo -u www-data rm phpMyAdmin-4.9.5-english.tar.gz
    ```

    1. Open phpMyAdmin in a browser and log in as root.
    1. Create a database called `phpmyadmin`
    1. Create a user called `pma` and set the *host* to `localhost`.
    1. Open the SQL dump file in `/var/www/html/phpmyadmin/create_tables.sql`.
    1. In phpMyAdmin, select the `phpmyadmin` database and click on the *SQL* tab.
    1. Copy/paste the entire text from `create_tables.sql` into the text box, and run the query.
    1. Open the `config.inc.php` file in the phpMyAdmin install directory, and add the following.

    ```php
    /* Blowfish needed for cookie based authentication. MUST to be 32 chars long. */
    $cfg['blowfish_secret'] = '12345678901234567890123456789012';
    $cfg['DefaultConnectionCollation'] = 'utf8mb4_unicode_ci';
    /* Servers configuration */
    $i = 0;
    /* First server */
    $i++;
    /* Authentication type */
    $cfg['Servers'][$i]['auth_type'] = 'cookie';
    /* Server parameters */
    $cfg['Servers'][$i]['host'] = 'localhost';
    $cfg['Servers'][$i]['compress'] = false;
    $cfg['Servers'][$i]['AllowNoPassword'] = false;
    /* Hide system dbs */
    $cfg['Servers'][$i]['hide_db'] = '^(information_schema|mysql|performance_schema|sys)$';
    /* phpMyAdmin configuration storage settings. */
    $cfg['Servers'][$i]['controluser'] = 'phpmyadmin';
    $cfg['Servers'][$i]['controlpass'] = 'ADD_DB_PASSWORD';
    /* phpMyAdmin storage database and tables */
    $cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
    $cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark';
    $cfg['Servers'][$i]['relation'] = 'pma__relation';
    $cfg['Servers'][$i]['table_info'] = 'pma__table_info';
    $cfg['Servers'][$i]['table_coords'] = 'pma__table_coords';
    $cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages';
    $cfg['Servers'][$i]['column_info'] = 'pma__column_info';
    $cfg['Servers'][$i]['history'] = 'pma__history';
    $cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs';
    $cfg['Servers'][$i]['tracking'] = 'pma__tracking';
    $cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
    $cfg['Servers'][$i]['recent'] = 'pma__recent';
    $cfg['Servers'][$i]['favorite'] = 'pma__favorite';
    $cfg['Servers'][$i]['users'] = 'pma__users';
    $cfg['Servers'][$i]['usergroups'] = 'pma__usergroups';
    $cfg['Servers'][$i]['navigationhiding'] = 'pma__navigationhiding';
    $cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
    $cfg['Servers'][$i]['central_columns'] = 'pma__central_columns';
    $cfg['Servers'][$i]['designer_settings'] = 'pma__designer_settings';
    $cfg['Servers'][$i]['export_templates'] = 'pma__export_templates';
    /* Directories for saving/loading files from server */
    $cfg['UploadDir'] = '';
    $cfg['SaveDir'] = '';
    /* General config */
    $cfg['RowActionType'] = 'icons';
    $cfg['ShowAll'] = true;
    $cfg['MaxRows'] = 50;
    $cfg['QueryHistoryDB'] = true;
    $cfg['QueryHistoryMax'] = 100;
    $cfg['SendErrorReports'] = 'never';
    $cfg['Console']['DarkTheme'] = true;
    ```
  6. justinhartman revised this gist Aug 17, 2020. 2 changed files with 4 additions and 4 deletions.
    6 changes: 3 additions & 3 deletions 3_install-lemp.md
    Original file line number Diff line number Diff line change
    @@ -52,9 +52,9 @@ Change these values:

    ```ini
    cgi.fix_pathinfo=0
    post_max_size = 128M
    upload_max_filesize = 128M
    date.timezone = Africa/Johannesburg
    post_max_size=128M
    upload_max_filesize=128M
    date.timezone=Africa/Johannesburg
    # Add this for opcache support
    opcache.enable=1
    opcache.memory_consumption=128
    2 changes: 1 addition & 1 deletion 6_sftp-setup.md
    Original file line number Diff line number Diff line change
    @@ -16,7 +16,7 @@ $ sudo chown -R FTPUSER:sftp /home/FTPUSER/.ssh
    $ sudo nano /etc/ssh/sshd_config
    ```

    ```ssh
    ```config
    PubkeyAuthentication yes
    Match group sftp
    X11Forwarding no
  7. justinhartman revised this gist Aug 17, 2020. 6 changed files with 25 additions and 37 deletions.
    4 changes: 0 additions & 4 deletions 0_general.md → 1_general.md
    Original file line number Diff line number Diff line change
    @@ -13,7 +13,3 @@ $ sudo cp /usr/share/zoneinfo/Africa/Johannesburg /etc/localtime # set time
    $ sudo adduser $(whoami) www-data # add yourself so you can SFTP to overwrite files in /var/www
    $ sudo chmod -R g+w /var/www # ensure group can write to www
    ```

    ### Optional

    If you use public/private keys for SSH authentication
    16 changes: 9 additions & 7 deletions 2_install-lemp.md → 3_install-lemp.md
    Original file line number Diff line number Diff line change
    @@ -33,11 +33,11 @@ mysql> exit
    ## Step 3 - Install PHP-FPM

    ```console
    sudo apt-get update
    sudo apt -y install software-properties-common
    sudo add-apt-repository ppa:ondrej/php
    sudo apt-get update
    sudo apt-get install -y php7.4-{fpm,cli,apc,bcmath,bz2,curl,gd,imagick,intl,mbstring,mysql,zip}
    $ sudo apt-get update
    $ sudo apt -y install software-properties-common
    $ sudo add-apt-repository ppa:ondrej/php
    $ sudo apt-get update
    $ sudo apt-get install php7.4-{fpm,cli,apc,bcmath,bz2,curl,gd,imagick,intl,mbstring,mysql,zip}
    $ sudo systemctl start php7.4-fpm
    $ sudo systemctl enable php7.4-fpm
    ```
    @@ -76,7 +76,7 @@ $ sudo nano /etc/nginx/nginx.conf

    Change these values:

    ```conf
    ```nginx
    client_max_body_size 128M;
    keepalive_timeout 2;
    server_tokens off;
    @@ -90,7 +90,7 @@ $ sudo nano /etc/nginx/sites-available/default

    Change these values:

    ```conf
    ```nginx
    index index.php index.html index.htm index.nginx-debian.html;
    location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    @@ -102,5 +102,7 @@ Test the output and reload.

    ```console
    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    $ sudo systemctl reload nginx
    ```
    24 changes: 0 additions & 24 deletions 3_phpmyadmin.md
    Original file line number Diff line number Diff line change
    @@ -1,24 +0,0 @@
    # Install phpMyAdmin server wide

    ```console
    $ sudo apt install phpmyadmin # choose none for web server configuration.
    $ sudo nano /etc/nginx/sites-available/default
    location /phpmyadmin {
    root /usr/share/;
    index index.php;
    try_files $uri $uri/ =404;

    location ~ ^/phpmyadmin/(doc|sql|setup)/ {
    deny all;
    }

    location ~ /phpmyadmin/(.+\.php)$ {
    fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    include snippets/fastcgi-php.conf;
    }
    }
    $ sudo nginx -t
    $ sudo systemctl reload nginx
    ```
    8 changes: 8 additions & 0 deletions 4_new-vhost.md
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,9 @@

    ```console
    $ sudo nano /etc/nginx/sites-available/example.com
    ```

    ```nginx
    server {
    listen 80;
    root /var/www/example.com;
    @@ -21,10 +24,15 @@ server {
    deny all;
    }
    }
    ```

    ```console
    $ sudo mkdir -p /var/www/example.com
    $ sudo chown -R www-data:www-data /var/www/example.com
    $ sudo chmod -R g+w /var/www/example.com
    $ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    $ sudo systemctl reload nginx
    ```
    10 changes: 8 additions & 2 deletions 6_sftp-setup.md
    Original file line number Diff line number Diff line change
    @@ -1,18 +1,22 @@
    # Setup SFTP

    I personally don't use this because we use public/private keys to authenticate users via SFTP but if you don't then this shows you how to setup a user to SFTP to the server.
    This uses public/private SSH key for authentication. Your user will only be able to write files in /var/www.

    ```console
    $ sudo apt install ssh
    $ sudo addgroup sftp
    $ sudo useradd -m FTPUSER -g sftp
    $ sudo passwd FTPUSER
    $ sudo adduser FTPUSER www-data # add user to group they can write to www folder
    $ sudo chmod -R g+w /var/www # set group write permissions
    $ sudo mkdir -p /home/FTPUSER/.ssh
    $ sudo nano /home/FTPUSER/.ssh/authorized_keys # copy public key from computer and paste here
    $ sudo chmod -R go= /home/FTPUSER/.ssh
    $ sudo chown -R FTPUSER:sftp /home/FTPUSER/.ssh
    $ sudo nano /etc/ssh/sshd_config
    ```

    ```ssh
    PubkeyAuthentication yes
    Match group sftp
    X11Forwarding no
    @@ -28,4 +32,6 @@ Test it out using your private key.
    $ sftp -i ~/.ssh/id_rsa [email protected]
    Connected to 40.88.136.129.
    sftp> exit
    ```
    ```

    > **TODO**: figure out why `ChrootDirectory /var/www/` in `/etc/ssh/sshd_config` creates a broken_pipe issue when connecting to the SFTP server. This has been disabled until I can solve this! :scream_cat:
  8. justinhartman created this gist Aug 17, 2020.
    19 changes: 19 additions & 0 deletions 0_general.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    # General Setup

    These are a series of specific commands to configure the Ubuntu server for our environment.

    ```console
    $ sudo locale-gen en_GB.UTF-8 # fix locales
    $ sudo cp /usr/share/zoneinfo/Africa/Johannesburg /etc/localtime # set time
    ```

    ## SFTP

    ```console
    $ sudo adduser $(whoami) www-data # add yourself so you can SFTP to overwrite files in /var/www
    $ sudo chmod -R g+w /var/www # ensure group can write to www
    ```

    ### Optional

    If you use public/private keys for SSH authentication
    31 changes: 31 additions & 0 deletions 1_azure-ubuntu-vm-swap.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,31 @@
    # Creating swap on Azure Ubuntu VM

    Run these commands to create a 3GB swap on an Azure Ubuntu VM.

    ```console
    $ sudo swapon --show # must output nothing so the below can work
    $ sudo fallocate -l 3G /swapfile
    $ sudo dd if=/dev/zero of=/swapfile bs=1024 count=3145728
    $ sudo chmod 600 /swapfile
    $ sudo mkswap /swapfile
    $ sudo swapon /swapfile
    $ sudo nano /etc/fstab
    ```

    Add this to `/etc/fstab`.

    ```text
    /swapfile swap swap defaults 0 0
    ```

    Check the swap has been added.

    ```console
    $ sudo swapon --show
    NAME TYPE SIZE USED PRIO
    /swapfile file 3G 0M -2
    $ sudo free -h
    total used free shared buff/cache available
    Mem: 889M 425M 75M 74M 389M 241M
    Swap: 3.0G 0M 3.0G
    ```
    106 changes: 106 additions & 0 deletions 2_install-lemp.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,106 @@
    # Install LEMP

    ## Step 1 - Install Nginx

    ```
    $ sudo apt update
    $ sudo apt install nginx
    $ sudo systemctl start nginx
    $ sudo systemctl enable nginx
    $ sudo chown -R www-data:www-data /usr/share/nginx/html
    ```

    ## Step 2 - Install MySQL

    ```console
    $ sudo apt install mysql-server mysql-client
    $ sudo systemctl start mysql
    $ sudo systemctl enable mysql
    $ sudo mysql_secure_installation # answer N to validate password plugin
    $ sudo mysql
    ```

    ### Configure MySQL users

    ```mysql
    mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;
    mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
    mysql> FLUSH PRIVILEGES;
    mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;
    mysql> exit
    ```

    ## Step 3 - Install PHP-FPM

    ```console
    sudo apt-get update
    sudo apt -y install software-properties-common
    sudo add-apt-repository ppa:ondrej/php
    sudo apt-get update
    sudo apt-get install -y php7.4-{fpm,cli,apc,bcmath,bz2,curl,gd,imagick,intl,mbstring,mysql,zip}
    $ sudo systemctl start php7.4-fpm
    $ sudo systemctl enable php7.4-fpm
    ```

    ### Configure php.ini

    ```console
    $ sudo nano /etc/php/7.4/fpm/php.ini
    ```

    Change these values:

    ```ini
    cgi.fix_pathinfo=0
    post_max_size = 128M
    upload_max_filesize = 128M
    date.timezone = Africa/Johannesburg
    # Add this for opcache support
    opcache.enable=1
    opcache.memory_consumption=128
    opcache.max_accelerated_files=10000
    opcache_revalidate_freq=100
    opcache.error_log=/var/log/opcache-errors.log
    ```

    ```console
    $ sudo systemctl reload php7.4-fpm
    $ sudo systemctl reload nginx
    ```

    ### Configure nginx

    ```console
    $ sudo nano /etc/nginx/nginx.conf
    ```

    Change these values:

    ```conf
    client_max_body_size 128M;
    keepalive_timeout 2;
    server_tokens off;
    ```

    Edit default host to enable PHP-FPM.

    ```console
    $ sudo nano /etc/nginx/sites-available/default
    ```

    Change these values:

    ```conf
    index index.php index.html index.htm index.nginx-debian.html;
    location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    }
    ```

    Test the output and reload.

    ```console
    $ sudo nginx -t
    $ sudo systemctl reload nginx
    ```
    24 changes: 24 additions & 0 deletions 3_phpmyadmin.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    # Install phpMyAdmin server wide

    ```console
    $ sudo apt install phpmyadmin # choose none for web server configuration.
    $ sudo nano /etc/nginx/sites-available/default
    location /phpmyadmin {
    root /usr/share/;
    index index.php;
    try_files $uri $uri/ =404;

    location ~ ^/phpmyadmin/(doc|sql|setup)/ {
    deny all;
    }

    location ~ /phpmyadmin/(.+\.php)$ {
    fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    include snippets/fastcgi-php.conf;
    }
    }
    $ sudo nginx -t
    $ sudo systemctl reload nginx
    ```
    30 changes: 30 additions & 0 deletions 4_new-vhost.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,30 @@
    # Setup a new nginx vhost

    ```console
    $ sudo nano /etc/nginx/sites-available/example.com
    server {
    listen 80;
    root /var/www/example.com;
    index index.php index.html index.htm index.nginx-debian.html;
    server_name example.com www.example.com;

    location / {
    try_files $uri $uri/ =404;
    }

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

    location ~ /\.ht {
    deny all;
    }
    }
    $ sudo mkdir -p /var/www/example.com
    $ sudo chown -R www-data:www-data /var/www/example.com
    $ sudo chmod -R g+w /var/www/example.com
    $ sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
    $ sudo nginx -t
    $ sudo systemctl reload nginx
    ```
    15 changes: 15 additions & 0 deletions 5_setup-ssl.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    # Setup Let's Encrypt

    ```console
    $ sudo add-apt-repository ppa:certbot/certbot
    $ sudo apt-get update
    $ sudo apt-get install python-certbot-nginx
    $ sudo certbot --nginx -d example.com -d www.example.com # domains must be added to nginx vhost
    $ sudo certbot renew --dry-run
    ```

    ## Adding new domains

    ```console
    $ sudo certbot --nginx -d example-two.com -d www.example-two.com
    ```
    31 changes: 31 additions & 0 deletions 6_sftp-setup.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,31 @@
    # Setup SFTP

    I personally don't use this because we use public/private keys to authenticate users via SFTP but if you don't then this shows you how to setup a user to SFTP to the server.

    ```console
    $ sudo apt install ssh
    $ sudo addgroup sftp
    $ sudo useradd -m FTPUSER -g sftp
    $ sudo passwd FTPUSER
    $ sudo adduser FTPUSER www-data # add user to group they can write to www folder
    $ sudo mkdir -p /home/FTPUSER/.ssh
    $ sudo nano /home/FTPUSER/.ssh/authorized_keys # copy public key from computer and paste here
    $ sudo chmod -R go= /home/FTPUSER/.ssh
    $ sudo chown -R FTPUSER:sftp /home/FTPUSER/.ssh
    $ sudo nano /etc/ssh/sshd_config
    PubkeyAuthentication yes
    Match group sftp
    X11Forwarding no
    AllowAgentForwarding no
    AllowTcpForwarding no
    ForceCommand internal-sftp
    $ sudo service ssh restart
    ```

    Test it out using your private key.

    ```console
    $ sftp -i ~/.ssh/id_rsa [email protected]
    Connected to 40.88.136.129.
    sftp> exit
    ```