Compile & Install Sakai LMS v20.1 with Nginx

abc101
6 min readOct 14, 2020

--

Sakai is a LMS, Learning Management System developed by Java. Let’s install it on a linux server.

Requirements

  1. Install Git
$ sudo apt install git

2. Download, extract, and put Java, Maven, and Tomcat on the “/opt”, “/usr/share”, or any other directory which you want. I prefer the “/opt”.

$ cd /opt
$ sudo apt install tree
...
$ tree -L 2
.
├── jvm
│ └── jdk1.8.0_261
├── maven
│ └── 3.5.4
└── tomcat
└── 9.0.38

3. Set those path on the “.bashrc”, “.bash_profile”, or “.zshrc”.

# Java env for Sakai
export JAVA_HOME=/opt/jvm/jdk1.8.0_261/
export MAVEN_HOME=/opt/maven/3.5.4/
export CATALINA_HOME=/opt/tomcat/9.0.38/
export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$CATALINA_HOME/bin:$PATHexport MAVEN_OPTS='-Xms512m -Xmx1024m'

4. Reload term(or close and open a term again to read the new “.bashrc”.

$ source ~/.bashrc

5. Clone the Sakai project from github.com and checkout the latest stable version.

$ cd
$ git clone https://github.com/sakaiproject/sakai.git
$ cd sakai
$ git checkout 20.1

6. Change “tomcat” directory ownership and create the “sakai” directory on the “/opt/tomcat/9.0.38”.

$ cd /opt
$ sudo chown -R $USER:$USER tomcat
$ cd tomcat/9.0.38
$ mkdir sakai

7. Create “setenv.sh” under the “/opt/tomcat/9.0.28/bin”.

$ vi bin/setenv.sh

and

export JAVA_OPTS="-server -d64 -Xms1g -Xmx2g -Djava.awt.headless=true -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC"
JAVA_OPTS="$JAVA_OPTS -Dhttp.agent=Sakai"
JAVA_OPTS="$JAVA_OPTS -Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false"
JAVA_OPTS="$JAVA_OPTS -Dsakai.security=$CATALINA_HOME/sakai/"
JAVA_OPTS="$JAVA_OPTS -Duser.timezone=US/Eastern"
JAVA_OPTS="$JAVA_OPTS -Dsakai.cookieName=SAKAI2SESSIONID"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8089 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"

if you want to create a Sakai “demo” project, then add below the end of the “setenv.sh”.

JAVA_OPTS="$JAVA_OPTS -Dsakai.demo=true"

and give “exec” permit to the “setenv.sh”.

$ chmod +x bin/setenv.sh

8. Edit “conf/conext.xml”,

$ vi conf/context.xml

and add below in the <Context> block.

<JarScanner>
<!-- This is to speedup startup so that tomcat doesn't scan as much -->
<JarScanFilter defaultPluggabilityScan="false" />
</JarScanner>

9. Copy the “default.sakai.properties” to “tomcat/9.0.38/sakai/sakai.properties”.

$ cd
$ cd git
$ cp config/configuration/bundles/src/bundle/org/sakaiproject/config/bundle/default.sakai.properties /opt/tomcat/9.0.38/sakai/sakai.properties

(If you’d like to setup your own properties, then copy the “sakai.properties” to “local.properties” in the “/opt/tomcat/9.0.38/sakai/”. The “local.properties” will override the “sakai.properties”.)

10. Set the Database information in the “sakai.properties” or “local.properties”. I selected MariaDB.

username@javax.sql.BaseDataSource=sakaiuser
password@javax.sql.BaseDataSource=sakaipassword
## MySQL settings
vendor@org.sakaiproject.db.api.SqlService=mysql
#driverClassName@javax.sql.BaseDataSource=com.mysql.jdbc.Driver
driverClassName@javax.sql.BaseDataSource=org.mariadb.jdbc.Driver
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
url@javax.sql.BaseDataSource=jdbc:mysql://127.0.0.1:3306/sakaidatabase?useUnicode=true&characterEncoding=UTF-8
validationQuery@javax.sql.BaseDataSource=
defaultTransactionIsolationString@javax.sql.BaseDataSource=TRANSACTION_READ_COMMITTED

11. Create a database for Sakai.

$ sudo mysql -u root
[sudo] password for $USER:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 1145
Server version: 10.3.23-MariaDB-0+deb10u1 Debian 10
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MariaDB [(none)]> create database sakaidatabase default character set utf8;
Query OK, 1 row affected (0.00 sec)

mysql> grant all on sakaidatabase.* to sakaiuser@'localhost' identified by 'sakaipassword';
Query OK, 0 rows affected (0.00 sec

mysql> grant all on sakaidatabase.* to sakaiuser@'127.0.0.1' identified by 'sakaipassword';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> quit

12. Build Sakai.

$ cd ~/sakai/
$ cd master
$ mvn -version
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-17T08:33:14-10:00)
Maven home: /opt/maven/3.5.4
Java version: 1.8.0_265, vendor: Debian, runtime: /opt/jvm/java-8-openjdk-amd64/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.19.0-11-amd64", arch: "amd64", family: "unix"

$ mvn clean install
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< org.sakaiproject:master >-----------------------
[INFO] Building Sakai Master 20.1
[INFO] --------------------------------[ pom ]---------------------------------
...
$ cd ..
$ mvn clean install sakai:deploy -Dmaven.tomcat.home=$CATALINA_HOME

13. It will take around 25 mins depends on your system performance.

14. Start Sakai.

$ startup.sh && tail -f $CATALINA_HOME/logs/catalina.out

It will create database tables at the first run. Be patient…

15. After a long long logs, you’ll get this.

13-Oct-2020 18:06:46.638 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
13-Oct-2020 18:06:46.648 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [46700] milliseconds

16. Open a web browser, and go to the “localhost:8080/portal”.

  • User Id: admin
  • Password: admin

“mercury site” is the “demo” site.

17. Stop the Sakai.

$ shutdown.sh

18. Install “nginx”.

$ sudo apt install nginx

19. Create a config for sakai under “/etc/nginx/sites-available/”,

$ cd /etc/nginx/sites-available
$ vi sakai.conf

and write below

server {
server_name yourdomain.tld;
access_log /var/log/nginx/tomcat-access.log;
error_log /var/log/nginx/tomcat-error.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}
}

20. Create a link from sites-available to sites-enabled.

$ cd ..
$ cd sites-enabled
$ ln -s /etc/nginx/sites-available/sakai.conf .

21. Edit “/opt/tomcat/9.0.38/conf/server.xml” from

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

to

<Connector port="8080" protocol="HTTP/1.1"
proxyName="yourdomain.tld"
proxyPort="443"
scheme="https"
connectionTimeout="20000"
redirectPort="8443" />

22. Restart nginx.

$ 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 restart

23. Start Sakai.

$ startup.sh

24. Open a web browser and go to the yourdomain.tld/portal.

25. Create your own system daemon.

a. Create “tomcat” user and group.

$ sudo useradd -m -U -d /opt/tomcat/9.0.38 -s /bin/false tomcat

b. Change directory ownership.

$ sudo chown -R tomcat:tomcat /opt/tomcat/9.0.38

c. Create service file in the “/etc/systemd/system”.

$ sudo vi /etc/systemd/system/sakai.tomcat.service

d. Add service information.

[Unit]
Description=Tomcat 9 servlet container for Sakai
After=network.target
[Service]
Type=forking
User=tomcat
Group=tomcat
Environment="JAVA_HOME=/opt/jvm/jdk1.8.0_261"
Environment="JRE_HOME=/opt/jvm/jdk1.8.0_261"
Environment="CATALINA_BASE=/opt/tomcat/9.0.38"
Environment="CATALINA_HOME=/opt/tomcat/9.0.38"
Environment="CATALINA_PID=/opt/tomcat/9.0.38/temp/tomcat.pid"
Environment="CATALINA_OPTS=-Xms512M -Xmx1024M"
ExecStart=/opt/tomcat/9.0.38/bin/startup.sh
ExecStop=/opt/tomcat/9.0.38/bin/shutdown.sh
[Install]
WantedBy=multi-user.target

e. Reload system daemon.

$ sudo systemctl daemon-reload

f. Start the service.

$ sudo systemctl start sakai.tomcat.service

g. Check the status. (Error check)

$ sudo systemctl status sakai.tomcat.service● sakai.tomcat.service - Tomcat 9 servlet container for Sakai
Loaded: loaded (/etc/systemd/system/sakai.tomcat.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2020-10-18 11:10:09 HST; 10min ago
Process: 20172 ExecStart=/opt/apache/tomcat/9.0.38/bin/startup.sh (code=exited, status=0/SUCCESS)
...

h. Stop the service.

$ sudo systemctl stop sakai.tomcat.service

i. Check the status. (Error check)

$ sudo systemctl status sakai.tomcat.service● sakai.tomcat.service - Tomcat 9 servlet container for Sakai
Loaded: loaded (/etc/systemd/system/sakai.tomcat.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Sun 2020-10-18 11:21:21 HST; 6s ago
...

j. If there is no error, then enable the service for boot time load.

$ sudo systemctl enable sakai.tomcat.service

k. Start the service.(or reboot)

$ sudo systemctl start sakai.tomcat.service
  • Extra: Make a portal as the domain root

Sakai uses ‘/portal’ for its portal root. So, when you visit your domain root ‘/’, then you can see 404 page error, or Tomcat manager site (if you’ve installed the Tomcat default manager app).

To make the ‘/portal’ as domain root, I set ‘porxy_pass’ to ‘/portal’, then Sakai does not read other static files because Sakai read static files from ‘/’.

server {
server_name yourdomain.tld;
access_log /var/log/nginx/tomcat-access.log;
error_log /var/log/nginx/tomcat-error.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080/portal;
}
}

So, I set two locations, one is for ‘/’ that will redirect to ‘/portal’, the other is for ‘/[something]’ that will redirect to ‘proxy_pass’.

server {
server_name yourdomain.tld;
location = / {
return 301 http://yourdomain.tld/portal;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}
}

It works great!

Reference link:

https://confluence.sakaiproject.org/

--

--