INGInious
INGInious copied to clipboard
Installation guide: recommended installation for 100s simultaneous submissions
In the installation guide, it is not entirely clear what configuration is recommended when it is expected that 100-200 students submit their solution in the same time.
From my experience, the simple Python web server cannot handle so many submissions. Indeed, the documentation says "In production environments, you can use lighttpd in replacement of the built-in Python server", but not everyone understands what "production environment" means.
Also, in the beginning it is written "You may want to enable the LDAP/SAML2 plugin or use FCGI/UWSGI instead of the web.py default webserver" - not everyone understands that "FCGI" the same as "fast CGI" and that "UWSGI" the same as "wsgi".
I suggest to clarify the documentation as follows.
If you intend to use INGInious with many simultaneous submissions, you should use a professional web-server, such as Lighttpd or Apache. To use Lighttpd, install the fast CGI module:
$ pip3 install --upgrade git+https://github.com/UCL-INGI/[email protected]#egg=INGInious[cgi]
To use Apache, install the UWCGI module:
$ pip3 install --upgrade git+https://github.com/UCL-INGI/[email protected]#egg=INGInious[uwgsi]
Then, proceed with configuring Lighttpd or Apache as explained below
Thank you for these suggestions. This part has remained untouched for a while now. I think it's also worth adding some hints on how to scale the components correctly depending on the expected load.
Indeed! Our locally-developed auto-grader worked perfectly before the start of term, but in the first submission to the public server, 100 students tried to submit simultaneously and it crashed miserably... We had to move to Apache at once.
QUESTION: what is "uwgsi" in the installation guide? Should it be "uwsgi"?
ANOTHER QUESTION: After I install and configure Apache2 as explained in that page, how can I check my installation? I tried to open http://<my-ip-address>/static
but got an error "Unable to connect".
- Yes, it is
uwsgi
You'll need it if you want to perform an nginx deployment. However, if your Linux distribution provides uwsgi, it's better and simpler to install it with their own packages. You do not need it with Apache, uwsgi is a specific service on top of WSGI. - Apache is quite verbose, I think you can find all the debug information into the logs (especially the error log, which would be located somewhere in
/var/log/{httpd|apache2}
). You can also ensure the LogLevel is high enough in the Apache configuration file.
To avoid clashes with other listening processes, I moved the two modules to ports 8081 and 8082 respectively, and reloaded Apache2. My configuration looks like this:
<VirtualHost *:8081>
LoadModule wsgi_module /usr/local/lib/python3.6/dist-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so
WSGIScriptAlias / "/usr/local/bin/inginious-webapp"
WSGIScriptReloading On
Alias /static /usr/local/lib/python3.6/dist-packages/inginious/frontend/static
<Directory "/usr/local/bin">
<Files "inginious-webapp">
Require all granted
</Files>
</Directory>
<DirectoryMatch "/usr/local/lib/python3.6/dist-packages/inginious/frontend/static">
Require all granted
</DirectoryMatch>
ServerAdmin [email protected]
DocumentRoot /var/www/inginious
</VirtualHost>
<VirtualHost *:8082>
LoadModule wsgi_module /usr/local/lib/python3.6/dist-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so
WSGIScriptAlias / "/usr/local/bin/inginious-webdav"
WSGIScriptReloading On
<Directory "/usr/local/bin">
<Files "inginious-webdav">
Require all granted
</Files>
</Directory>
</VirtualHost>
Now, apache2 -M
shows, among others,
wsgi_module (shared)
and apache2 -S
shows, among others,
*:8081 104.248.40.179 (/etc/apache2/sites-enabled/inginious.conf:1)
*:8082 104.248.40.179 (/etc/apache2/sites-enabled/inginious.conf:22)
which shows that Apache2 does read the wsgi configuration from the files. However, I still cannot connect to http://localhost:8081 or http://localhost:8082. What is the problem?
These config files look good at the first sight. Have a look to the error logs to see if the wsgi module or apache prints anything bad.
Here is the file error.log just after reloading Apache2:
[Thu Feb 18 18:57:46.994117 2021] [socache_shmcb:info] [pid 12632] AH00830: Shared memory socache initialised
[Thu Feb 18 18:57:46.994139 2021] [ssl:info] [pid 12632] AH01887: Init: Initializing (virtual) servers for SSL
[Thu Feb 18 18:57:46.994146 2021] [ssl:info] [pid 12632] AH01876: mod_ssl/2.4.29 compiled against Server: Apache/2.4.29, Library: OpenSSL/1.1.1
[Thu Feb 18 18:57:46.994214 2021] [mpm_prefork:notice] [pid 12632] AH00163: Apache/2.4.29 (Ubuntu) OpenSSL/1.1.1 mod_wsgi/4.5.17 Python/3.6 configured -- resuming normal operations
[Thu Feb 18 18:57:46.994219 2021] [mpm_prefork:info] [pid 12632] AH00164: Server built: 2020-08-12T21:33:25
[Thu Feb 18 18:57:46.994222 2021] [core:notice] [pid 12632] AH00094: Command line: '/usr/sbin/apache2'
[Thu Feb 18 18:57:47.997715 2021] [wsgi:info] [pid 16827] mod_wsgi (pid=16827): Initializing Python.
[Thu Feb 18 18:57:48.000974 2021] [wsgi:info] [pid 16831] mod_wsgi (pid=16831): Initializing Python.
[Thu Feb 18 18:57:48.004725 2021] [wsgi:info] [pid 16830] mod_wsgi (pid=16830): Initializing Python.
[Thu Feb 18 18:57:48.006544 2021] [wsgi:info] [pid 16829] mod_wsgi (pid=16829): Initializing Python.
[Thu Feb 18 18:57:48.011627 2021] [wsgi:info] [pid 16828] mod_wsgi (pid=16828): Initializing Python.
[Thu Feb 18 18:57:48.063143 2021] [wsgi:info] [pid 16831] mod_wsgi (pid=16831): Attach interpreter ''.
[Thu Feb 18 18:57:48.067184 2021] [wsgi:info] [pid 16830] mod_wsgi (pid=16830): Attach interpreter ''.
[Thu Feb 18 18:57:48.072145 2021] [wsgi:info] [pid 16831] mod_wsgi (pid=16831): Imported 'mod_wsgi'.
[Thu Feb 18 18:57:48.072434 2021] [wsgi:info] [pid 16827] mod_wsgi (pid=16827): Attach interpreter ''.
[Thu Feb 18 18:57:48.073417 2021] [wsgi:info] [pid 16830] mod_wsgi (pid=16830): Imported 'mod_wsgi'.
[Thu Feb 18 18:57:48.080393 2021] [wsgi:info] [pid 16829] mod_wsgi (pid=16829): Attach interpreter ''.
[Thu Feb 18 18:57:48.083918 2021] [wsgi:info] [pid 16829] mod_wsgi (pid=16829): Imported 'mod_wsgi'.
[Thu Feb 18 18:57:48.084460 2021] [wsgi:info] [pid 16827] mod_wsgi (pid=16827): Imported 'mod_wsgi'.
[Thu Feb 18 18:57:48.088675 2021] [wsgi:info] [pid 16828] mod_wsgi (pid=16828): Attach interpreter ''.
[Thu Feb 18 18:57:48.091951 2021] [wsgi:info] [pid 16828] mod_wsgi (pid=16828): Imported 'mod_wsgi'.
It contains only info lines.
I'm almost sure some INGInious logs should be printed there too. Maybe the inginious-webapp
has actually not returned, which would explain why you get unable to connect error messages and why there is no log. This is possible if it tries to run the integrated webserver.
Open your /usr/bin/inginious-webapp
file and comment the blocks:
- From line https://github.com/UCL-INGI/INGInious/blob/v0.6/inginious-webapp#L32 to line https://github.com/UCL-INGI/INGInious/blob/v0.6/inginious-webapp#L43
- From line https://github.com/UCL-INGI/INGInious/blob/v0.6/inginious-webapp#L66
However, that shouldn't prevent you from accessing the static files, that are not served through WSGI, and Apache is supposed to log that, even if there are not found. You may want to have a look to the access_log to ensure this. What kind of HTTP error code are you displayed when you try to connect ?
When I do curl http://localhost:8081
I get curl: (7) Failed to connect to localhost port 8081: Connection refused
similarly when I try port 8082. Nothing appears in access.log.
I thought it might be a firewall problem, but ufw status
shows Status: inactive
.
You can run netstat -pnlt
to see if apache actually binds the correct IP and ports (for listening on every interface it should display 0.0.0.0 or :: for IPv6). If it only binds the public IP, you won't be able to connect localhost.
Indeed, it does not listen on these ports: netstat -pnlt|grep apache
tcp6 0 0 :::443 :::* LISTEN 10382/apache2
tcp6 0 0 :::80 :::* LISTEN 10382/apache2
But it does show the virtual hosts when I do apache2 -S
:
VirtualHost configuration:
*:443 bad-kan.com (/etc/apache2/sites-enabled/badkan2.com-le-ssl.conf:2)
*:80 104.248.40.179 (/etc/apache2/sites-enabled/badkan2.com.conf:1)
*:8081 104.248.40.179 (/etc/apache2/sites-enabled/inginious.conf:1)
*:8082 104.248.40.179 (/etc/apache2/sites-enabled/inginious.conf:22)
At least some progress :-) You may need to add some Listen
directives for those ports in your configuration files. I recommend you to refer to the Apache documentation, I don't know if this would be enough
Hi @erelsgl, How did you solve your issue for apache2 not listening on port 8080. I have the same issue. My users are unable to access webdav via URL generated by inginious. This is the configuraton of apache
apache2 -S
[Tue Jun 15 08:30:45.671752 2021] [so:warn] [pid 3368:tid 140203586923456] AH01574: module wsgi_module is already loaded, skipping
[Tue Jun 15 08:30:45.672188 2021] [so:warn] [pid 3368:tid 140203586923456] AH01574: module wsgi_module is already loaded, skipping
AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/ports.conf:5
VirtualHost configuration:
*:443 inginious.uac.bj (/etc/apache2/sites-enabled/inginious-le-ssl.conf:2)
*:80 is a NameVirtualHost
default server XXX.YYY.bj (/etc/apache2/sites-enabled/000-default.conf:1)
port 80 namevhost XXX.YYY.bj (/etc/apache2/sites-enabled/000-default.conf:1)
port 80 namevhost XXX.YYY.bj (/etc/apache2/sites-enabled/inginious.conf:1)
*:8080 XXX.YYY.bj (/etc/apache2/sites-enabled/inginious.conf:26)
ServerRoot: "/etc/apache2"
Also the result of netstat
sudo netstat -pnlt | grep apache
tcp6 0 0 :::80 :::* LISTEN 344/apache2
tcp6 0 0 :::443 :::* LISTEN 344/apache2
Thanks. Emery.
@akemery this is what worked for me: https://docs.inginious.org/en/v0.7/admin_doc/install_doc/installation.html#using-apache-on-ubuntu-18-04
But it was for the previous version. Currently I am working on other things..
@erelsgl , I followed the guidelines in https://docs.inginious.org/en/v0.7/admin_doc/install_doc/installation.html#using-apache-on-ubuntu-18-04, I am able to connect to webdav using the generated password and my login.
But the connection failed. Displaying the server's errors logs, inginious tell that there is error in configuration.yaml at line 1 and column 1. I am using inginious version v.0.8.dev1+g0c9a010e. I don't know if the error is related to the version I am using.
Maybe @anthonygego or @Drumor are more able to help me on that.
This my configuration.yaml
allow_registration: true
allow_deletion: false
backend: local
backup_directory: /var/www/html/inginious_bkp
local-config:
debug_host: xxxx.yy.bj
tmp_dir: /var/www/html/agent_tmp
mongo_opt:
database: INGInious
host: localhost
plugins: []
superadmins:
- eka
tasks_directory: /var/www/html/inginious_courses
use_minified_js: true
webterm: https://xxx.yyyy.bj:4449
webdav_host: http://xxxx.yyy.bj:4449
log_level: INFO
session_parameters:
timeout: 86400 # 24 * 60 * 60, # 24 hours in seconds
ignore_change_ip: False # change this to True if you want user to keep their session if they change their IP
secure: False # change this to True if you only use https
secret_key: "zzzzzz70ee0319b54eyyyyyyyyy3f2c95442d1147335yyyyy"
This is the error logs parts.
[Tue Jun 15 17:16:48.848254 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] mod_wsgi (pid=15745): Exception occurred processing WSGI script '/usr/local/bin/inginious-webdav'.
[Tue Jun 15 17:16:48.850835 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] Traceback (most recent call last):
[Tue Jun 15 17:16:48.850926 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] File "/usr/local/bin/inginious-webdav", line 53, in <module>
[Tue Jun 15 17:16:48.850936 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] config = load_json_or_yaml(configfile)
[Tue Jun 15 17:16:48.850950 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] File "/usr/local/lib/python3.6/dist-packages/inginious/common/base.py", line 33, in load_json_or_yaml
[Tue Jun 15 17:16:48.850958 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] return inginious.common.custom_yaml.load(f)
[Tue Jun 15 17:16:48.850971 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] File "/usr/local/lib/python3.6/dist-packages/inginious/common/custom_yaml.py", line 37, in load
[Tue Jun 15 17:16:48.850978 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] return original_yaml.load(stream, OrderedLoader)
[Tue Jun 15 17:16:48.850991 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] File "/usr/local/lib/python3.6/dist-packages/yaml/__init__.py", line 114, in load
[Tue Jun 15 17:16:48.850999 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] return loader.get_single_data()
[Tue Jun 15 17:16:48.851010 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] File "/usr/local/lib/python3.6/dist-packages/yaml/constructor.py", line 51, in get_single_data
[Tue Jun 15 17:16:48.851018 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] return self.construct_document(node)
[Tue Jun 15 17:16:48.851030 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] File "/usr/local/lib/python3.6/dist-packages/yaml/constructor.py", line 55, in construct_document
[Tue Jun 15 17:16:48.851037 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] data = self.construct_object(node)
[Tue Jun 15 17:16:48.851079 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] File "/usr/local/lib/python3.6/dist-packages/yaml/constructor.py", line 100, in construct_object
[Tue Jun 15 17:16:48.851087 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] data = constructor(self, node)
[Tue Jun 15 17:16:48.851098 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] File "/usr/local/lib/python3.6/dist-packages/yaml/constructor.py", line 429, in construct_undefined
[Tue Jun 15 17:16:48.851104 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] node.start_mark)
[Tue Jun 15 17:16:48.851129 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] yaml.constructor.ConstructorError: could not determine a constructor for the tag None
[Tue Jun 15 17:16:48.851137 2021] [wsgi:error] [pid 15745:tid 140431740368640] [client 41.85.181.159:57044] in "/var/www/html/configuration.yaml", line 1, column 1
Thanks Emery.
webterm: https://xxx.yyyy.bj:4449 webdav_host: http://xxxx.yyy.bj:4449
You should explicitely use quoting marks here because the colon is part of the YAML syntax