I prepared some learning contents in exelearning that I exported as .zip. I uploaded the contents to a channel on kolibri studio.
On kolibri studio the contents displays fine with all the activities and all other things working fine, but when i use the same contents in instance of kolibri running behind an nginx reverse proxy, it does not display. I get a blank page with “bauchi-edtech.org sent an invalid response” . The OS is Ubuntu server 24.04 LTS.
Using exelearning empowers coaches to create contents fast depending on their curriculum, and I would want to enable this in our local community. But I need help with this…
Kolibri serves ZIP content from a different port, for security reasons. Therefore if you run Kolibri behind a reverse proxy, you must account for this in your nginx and Kolibri configurations.
You’ll need to configure the ZIP_CONTENT_ORIGIN and/or ZIP_CONTENT_PORT options in your Kolibri’s options.ini file.
If you use kolibri-server without SSL, no further configuration is required. Here’s a similar thread where SSL is involved: Studio content invalid response
Hi Blaine,
Thank you for your response. I tested same zip contents in kolibri instance without reverse proxy, and it is fine.
I read the additional information provided on how to adjust for serving zip content under nginx reverse proxy with ssl, but in order not to be dealing with an erroneous information, I want to get you very clear, What do I need to set ZIP_CONTENT_ORIGIN and ZIP_CONTENT_PORT to?
Since the content is uploaded directly into kolibri, and for server install we already have 8081 for serving external contents, will this be adequate setting in nginx, listen on 8081?
Here are the descriptions for those configuration directives:
Description of ZIP_CONTENT_ORIGIN:
When running by default (value blank), Kolibri frontend looks for the zipcontent endpoints on the same domain as Kolibri proper, but uses ZIP_CONTENT_PORT instead of HTTP_PORT. When running behind a proxy, set the value to the port where zipcontent endpoint is served on, and it will be substituted for the port that Kolibri proper is being served on. When zipcontent is being served from a completely separate domain, you can set an absolute origin (full protocol plus domain, e.g. ‘https://myzipcontent.com/’) to be used for all zipcontent origin requests. It is strongly recommended that zipcontent is served from a different origin from the main Kolibri app, either by port or domain, to allow for proper sandboxing.
Description of ZIP_CONTENT_PORT:
Sets the port that Kolibri will serve the alternate origin server on. This is the server that is used to serve all content for the zipcontent endpoint, so as to provide safe IFrame sandboxing but avoiding issues with null origins. This is the alternate origin server equivalent of HTTP_PORT. It is strongly recommended that zipcontent is served from a different origin from the main Kolibri app, either by port or domain, to allow for proper sandboxing.
You’ll need to:
Set ZIP_CONTENT_PORT to a port that isn’t being used and won’t be exposed-- this port will be accessed via the nginx reverse proxy (for example, 8082)
Create a new nginx reverse proxy configuration, which should expose a different port than you’re already using for Kolibri which you said is 8081 (for example, port 8083)
Set the new nginx reverse proxy to proxy to Kolibri via the port configured by ZIP_CONTENT_PORT (for example, 8082)
Set the ZIP_CONTENT_ORIGIN to the nginx reverse proxy’s port (for example, port 8083)
Ensure any firewalls on the devices allow access to the nginx ports (for example, ports 8081 and 8083), and optionally prevent access to ports 8080 and 8082 which are direct-access to Kolibri
The kolbiri-server package does this by default, with the exception of configuring SSL.
It looks like you may have attached screenshots but they didn’t come through.
Regarding the nginx configuration, you’ll need to create a separate server configuration block, such that you have one nginx server configuration for each (2 total) exposed port. The exposed ports are specified by the listen directive within each server { } configuration block. The most straightforward approach may be to duplicate the current server block that you have and change the listen port and the port which it proxies to, which is likely defined in a location {} block.
To properly reverse proxy Kolibri, you must use ZIP_CONTENT_ORIGIN. Please see the quoted comment above about the ZIP_CONTENT_ORIGIN. The screenshot of your nginx configuration does not serve zip content from a different origin, because the proxies exist in the same server block. The origin is essentially the combination of server_name & port. For security reasons, they should be served from separate origins.
For example, with the following configuration, you should configure ZIP_CONTENT_ORIGIN = bauchi-edtech.net:81:
The kolibri-server package configures nginx routing automatically, including for zip content. Although, it does not use an HTTP proxy, but rather UWSGI. It’s meant for performance deployments of Kolibri. Either approach requires manual effort to configure HTTPS.
It looks like your options.ini has a duplicate entry in it. The error there says “Duplicate keyword at line 145” so I would double check your options.ini and make sure no option is specified twice.
I don’t know why I cannot connect to kolibri-server. I have the everything installed on ubuntu server 24.04. My nginx installation for ssl is as attached here with other screenshots.
The warnings shown after running nginx -t do seem to pertinent. Any server block configured in nginx must have either of the following, for a single IP address:
a different server_name if using the same port in listen
a different port specified in listen if using the same server_name
The config you shared prior did have a server_name. It also looks like you’re now using kolibri-server? I would advise you to check for extraneous configurations in the /etc/nginx/conf.d/ and/or /etc/nginx/sites-available. The kolibri-server installation should register a file within /etc/nginx that likely includes an nginx.conf from /etc/kolibri.
Customization of that nginx.conf, like for SSL, should be done in /etc/kolibri/nginx.d/ but I will need to research how that is achieved.
Well… in the meantime, I rolled back everything related to kolibri-server, nginx, certbot etc… and I got the kolibri instance starting and loading fine.
Yes, i would prefer running kolibri-server, but it seems doing this creates many files hidden here and there that makes it difficult to know where to look for configuration problems.
But I wont give up on using kolibri-server, what I have read looks simple, but implementing just got complex from somewhere I don’t know.
Whether serving html5 contents or any other, it seems kolibri-server configures ALL the necessary ports, for example, 8080 for normal, 8081 for zip contents. So, setting up reverse-proxy should have 2 separate location statements with these two ports specified in separate server blocks within the sites-available file? For example;
Certbot addition with listen port on 443 and other certificate statement…
Above is what I thought should have worked, but as it turns out it did not work… i digged further and found that kolibri-server creates other files like /etc/nginx and /etc/kolibri, etc… so the question arise as to which of these files should be used for setting up additional items for serving both html5(zip) and other contents when using kolibri-server?
Installing kolibri-server installs additions like nginx and others, so which configuration files takes precedence?.
Yes that’s correct. Although, in your second location block it has a path /.kolibri which means you would have to also define that in your ZIP_CONTENT_ORIGIN. Otherwise, the location paths should be the same: /
Certbot addition with listen port on 443 and other certificate statement…
Insecure webservers generally use ports like 80 (default), 8080, 8000. The default secure port is 443, and alternatively 8443, so for example, you could use 443 for Kolibri and 8443 for the zip content.
so the question arise as to which of these files should be used for setting up additional items for serving both html5(zip) and other contents when using kolibri-server?
The nginx file that kolibri-server uses should reside in /etc/kolibri/nginx.conf. There’s a bit of misdirection since kolibri-server should also install a file into /etc/nginx (probably /etc/nginx/conf.d) which sources the file in /etc/kolibri/nginx.conf via an nginx include (a way of splitting configuration into separate files and composing them into one file via the include directive).
Nginx will utilize the first configuration it finds for a server-name and port, and it uses the same include directive itself to source configurations, initiated from the core config /etc/nginx/nginx.conf. The core config likely includes configurations from conf.d and sites-available, but the order of which should be evident in /etc/nginx/nginx.conf. It is sometimes common to see config files prefixed with numbers like 00-kolibri.conf to enforce the order in which files are included from a directory. Although, it’s better to remove conflicting config files in this case.
The /etc/kolibri/nginx.d directory is for customization of Kolibri’s nginx config. Any configuration files are included from that directory similarly to /etc/nginx/conf.d. In actuality, kolibri-server writes a file to /etc/nginx/conf.d/kolibri.conf which has the includes for /etc/kolibri/nginx.d.
My apologies I mistakenly read the source code as writing the file to /etc/kolibri/nginx.conf. The kolibri-server service creates the file dynamically to align with Kolibri’s options.ini, but it actually writes the file to the Kolibri home directory.
So if kolibri-server was installed and configured to create a new kolibri user, the location of the file should be something like /var/kolibri/.kolibri/nginx.conf. Note: this again depends on what user was provided when it was installed. For example, if you specified your existing david user during installation, then the home directory would be /home/david/.kolibri by default.
If the nginx.conf file does not exist in your KOLIBRI_HOME, there should be a python script at /usr/share/kolibri-server/kolibri_server_setup.py which can generate the file. You may generate the nginx.conf like so:
sudo su -c '/usr/share/kolibri-server/kolibri_server_setup.py' $(cat /etc/kolibri/username)
The latest error you shared could be related to missing ssl on your listen directive. Could you try updating that to listen 8081 ssl;
So to summarize:
the KOLIBRI_HOME directory depends on the user provided to kolibri-server during installation
/etc/nginx/conf.d/kolibri.conf is created and loads additional configurations from /etc/kolibri/nginx.d/
$KOLIBRI_HOME/nginx.conf is also created when kolibri-server starts up
$KOLIBRI_HOME/nginx.conf can be created manually with /usr/share/kolibri-server/kolibri_server_setup.py
be sure to have ssl on any listen directives if it’s meant to provide secure HTTPS content
Hi Blaine,
I got some good results, and intend to document the process and make it available to the community. I have both kolibri and zip/html5 contents working now. But there is this warning still showing when I check the kolibri-server status; See the attached screenshot, please
What could be responsible for this and what could be the implication on the running instance? I want to clear this out of the way and then do the documentation of the process I used.
That’s great news! Thank you for your time navigating this. There’s surely opportunity for improvement, so we welcome anything you can share.
Regarding the error, I can’t quite tell the cause or outcome of the error. I believe the error should also be documented in the Kolibri logs, which are located in the KOLIBRI_HOME directory at logs/kolibri.txt. If you’re able to locate it there, and if you could share that, it would be helpful to determine the impact.