Skip to content

Instantly share code, notes, and snippets.

@hmt
Forked from burningTyger/moodle_on_do.md
Created June 4, 2023 12:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hmt/1c9ea16c6b5daefd331f62e70832403e to your computer and use it in GitHub Desktop.
Save hmt/1c9ea16c6b5daefd331f62e70832403e to your computer and use it in GitHub Desktop.
How To Install Moodle via git with Postgres, Nginx and PHP on an Ubuntu 16.04 VPS

How To Install Moodle via git with Postgres, Nginx and PHP on an Ubuntu 16.04 VPS

Introduction

Moodle is a common online learning platform used in many educational settings around the world. This tutorial aims at giving admins a solid and speedy foundation for serving moodle to a small to medium sized institution. The setup focuses on simple maintenance and fast updates.

Prerequisites

  • Create a small droplet with Ubuntu 16.04 (64Bit is great)
  • Follow the tutorial on setting up Ubuntu 16.04
  • git should be installed by default

From here on we can just follow this tutorial. It assumes that you have a user with root privileges which means you need to type sudo before any other command.

Step 1: Getting the packages

In order to run moodle some packages have to be installed first. Make sure to have up to date sources:

sudo apt-get update

Install Nginx:

Moodle works extremely well with Nginx as it offers a simple setup and serves static files blazingly fast. Even though moodle is a huge PHP application it has advanced caching features. So Nginx is our choice:

sudo apt-get install nginx

There's also a tutorial about Nginx with more details.

Install postgresql:

Postgres is a very reliable database. Technically MariaDB or MySQL should do to but we're focusing on speed:

sudo apt-get install postgresql postgresql-contrib

For additional guidance see the tutorial on Postgresql.

Install PHP and its dependencies:

This rather long command will install all the necessary and recommended packages to run moodle on PHP 7:

sudo apt-get install php-fpm php-curl php-gd php-xmlrpc php-intl php-xml php-zip php-mbstring php-soap php-pgsql

Step 2: Installing moodle

Nginx has decided that wwwroot is under /usr/share/nginx/html which is fine for us. We will now install moodle there:

cd /usr/share/nginx

The directory is not ready to be accessed by anybody but root, so we will enable our user to have access to it; moodle won't write into this directory, it will use the moodledata directory which we will setup at a later stage:

sudo chown -R $USER:$USER html

Now enter the newly aquired directory and clone moodle:

cd html
git clone https://github.com/moodle/moodle.git

This will clone the github moodle repository in a directory called moodle. Now you can do many things a lot easier. For example, if you moved from another hosting provider to DigitalOcean, you can just "check out" the version you last used and then check out the latest version. Or you can just stick with stable releases. There is a whole world of simple code management open for you. For this tutorial, we will simply check out the latest stable version which moodle always keeps in its own branch. To find out which version is latest for you, do this:

cd moodle
git remote show origin

Currently the latest stable Version is MOODLE_38_STABLE so this is the one we're going to check out for this tutorial:

git checkout MOODLE_38_STABLE

While Moodle also tags its releases, following a branch has the advantage that you can easily update following the weekly releases to the stable branches without following the current tags.

To update moodle a simple git pull will suffice to get the latest weekly release for the current branch. Once a new major release becomes available you will have to switch branches and set this branch to follow. So as soon as Moodle 3.2 becomes available you might want to run this command:

git checkout MOODLE_39_Stable

Adjustments

In your moodle directory there is a file called config-dist.php. Open and edit it:

nano config-dist.php

There are a few values that need to be changed in order to work on your server (comments are stripped out for simplicity's sake):

<?PHP
unset($CFG);
global $CFG;
$CFG = new stdClass();
$CFG->dbtype    = 'pgsql';
$CFG->dblibrary = 'native';
$CFG->dbhost    = 'localhost';
$CFG->dbname    = 'moodle';
$CFG->dbuser    = 'moodle';
$CFG->dbpass    = '<^>password<^>';
$CFG->prefix    = 'mdl_';
$CFG->dboptions = array(
    'dbpersist' => false,
    'dbsocket'  => false,
    'dbport'    => '',   
);
$CFG->wwwroot   = 'https://<^>example.com<^>';
$CFG->dataroot  = '/usr/local/moodledata';
$CFG->directorypermissions = 02777;
$CFG->admin = 'admin';
require_once(dirname(__FILE__) . '/lib/setup.php');

This is a complete config file. After you have changed the values, you save it as config.php to your moodle directory (make sure to use your own password and your own wwwroot). Also Note that wwwroot has been set to an https address. Unless you set up an SSL host file later on you should use http.

Further Steps

The changes just performed set the pace for these next steps. You need to set up a moodle data directory and a cache directory:

sudo mkdir /usr/local/moodledata
sudo mkdir /var/cache/moodle

Make them belong to the www-data user, which is in short Nginx:

sudo chown www-data:www-data /usr/local/moodledata    
sudo chown www-data:www-data /var/cache/moodle

The first one is to store user uploads, session data and other things only moodle needs access to and which shouldn't be accessible from the web. The cache store helps to preserve files for faster caching.

Step 3: Setting up the database

Now it's time to set up the database for moodle. To do so use the postgres user to create a new role called moodle which then will be able to handle the moodle database you are about to create:

sudo su - postgres
psql

This will start a new postgres console:

CREATE USER moodle WITH PASSWORD 'password';
CREATE DATABASE moodle;
GRANT ALL PRIVILEGES ON DATABASE moodle to moodle;
\q

With these commands, you've created a new database user called "moodle" that you granted all the necessary rights to administer the moodle database which you also created. To return to the shell use the \q command.

Exit user postgres and move to the next step:

exit

Step 4: Setting up Nginx

In a last step, tell Nginx how to serve your files. To do so create an Nginx host file:

sudo nano /etc/nginx/sites-available/moodle

Add some basic config to the file so that you have unencrypted access to the site. You should then get a certificate for always encrypted traffic to your site:

server {
    server_name <^>example.com<^>;
    listen 80;
}

Save and link your new site to sites-enabled so that nginx picks up the config:

ln -s /etc/nginx/sites-available/moodle /etc/nginx/sites-enabled/

Then restart your server via:

sudo systemctl restart nginx

This will enable your moodle site on nginx.

You really should have SSL enabled as you and your users will send passwords to the server. How to get a free certificate from Let's encrypt can be found in this fine tutorial. Once you have your certificate the Nginx host file should look like this:

server {
        server_name          <^>example.com<^>;
        ssl  on;
        ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GC
                M-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-
SHA128:ECDHE-RSA
                -AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES
-CBC3-SHA:EDH-RS
                A-DES-CBC3-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!e
NULL:!EXPORT:!DE
                S:!MD5:!PSK:!RC4";
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;
        ssl_session_tickets off;
        ssl_stapling on;
        ssl_stapling_verify on;
        resolver_timeout 5s;
        ssl_certificate /etc/letsencrypt/live/<^>example.com<^>/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/<^>example.com<^>/privkey.pem;
        listen               *:443 ssl http2;
        listen               [::]:443 ssl http2;

        root /usr/share/nginx/html/moodle;
        rewrite ^/(.*\.php)(/)(.*)$ /$1?file=/$3 last;

        location ^~ / {
                try_files $uri $uri/ /index.php?q=$request_uri;
                index index.php index.html index.htm;

                location ~ \.php$ {
                        include snippets/fastcgi-php.conf;
                        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
                }
        }
}
server {
    if ($host = <^>example.com<^>) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        server_name <^>example.com<^>;
    listen 80;
    return 404; # managed by Certbot


}

Note, some of these settings are added to the config via let's encrypt. Some are your settings. Compare the output you get from let's encrypt.

Make sure to replace the <^>example.com<^> entries with your domain. Also note that this will make your moodle site only accessible through https. If you want redirects please read the aforementioned tutorial.

Just in case you don't want to enable SSL, either because you don't have a domain yet or you just want to see moodle in action without any user you can also use this host file. Just make sure to use only one or the other as redirects will not happen.

server {
    server_name          <^>example.com<^>;
    listen 80;
        root /usr/share/nginx/html/moodle;
        rewrite ^/(.*\.php)(/)(.*)$ /$1?file=/$3 last;

        location ^~ / {
                try_files $uri $uri/ /index.php?q=$request_uri;
                index index.php index.html index.htm;

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

Now enable your moodle site:

sudo ln -s /etc/nginx/sites-available/moodle /etc/nginx/sites-enabled/moodle

And restart up your nginx server:

sudo service nginx restart

After this last step you can test your new moodle platform. Point your browser to your domain or your server's IP address.

Moodle will ask you a few questions while it installs.

Step 5: Fine Tuning Your Virtual Server

Finally, you will want to fine tune a couple more things.

Cronjobs are very important for moodle and running them offsite is not as effective as running them locally. You can add a short command to your www-data user's cron tab:

sudo crontab -u www-data -e

This will open an editor. Add the following line, which will run the cron script every ten minutes for you:

*/10 * * * * php -q -f /usr/share/nginx/www/moodle/admin/cli/cron.php

Save and return to your own shell by typing exit

To profit from our git based moodle install we can use a simple script to update the codebase and the database in one go:

# File name: update_moodle.sh
# 
# switch to moodle source directory
cd /usr/share/nginx/html/moodle;
# put moodle into maintenance mode
sudo -u www-data php /usr/share/nginx/html/moodle/admin/cli/maintenance.php --enable;
# pull changes
git pull;
# run the moodle upgrade script to which you will have to answer: y
sudo -u www-data php /usr/share/nginx/html/moodle/admin/cli/upgrade.php;
# Put moodle into regular mode again
sudo -u www-data php /usr/share/nginx/html/moodle/admin/cli/maintenance.php --disable;
# run the cron script to clean up
sudo -u www-data php /usr/share/nginx/html/moodle/admin/cli/cron.php;
# and switch back to your original directory
cd -;

You can store this script somewhere and run it every once in a while – moodle is usually updated on fridays.

Before you can use it make it execuatable and run it:

chmod +x update_moodle.sh
./update_moodle.sh

Every once in a while there will be a new major release but git doesn't automatically upgrades to that. To do that do as earlier in your moodle directory:

git checkout MOODLE_39_STABLE # or whichever version is the current stable release

This is the end of the tutorial. Your moodle platform should now be blazingly fast. Enjoy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment