Installation¶
To install this software, you can use a container-based setup, or run it directly in a Python environment. As there are many ways (and opinions!) how to configure a web server and deploy a Python WSGI application, only some details are outlined here and the reader is expected to be familiar with at least web server administration.
See also the Flask documentation on production deployment.
Container setup (Podman, Kubernetes, …)¶
Pull the container image (or build it yourself using the provided
Containerfile):
% podman pull registry.git.fsmpi.rwth-aachen.de/schilder/schilder2000:{{TAG}}
Config and data is expected in /usr/local/var/schilder2000-instance/. For
starters, you can use the examples/ directory in the source repository,
which is also included in the container image. To create a volume based on it:
% [[ $(id -u) -eq 0 ]] || podman unshare
# pushd $(podman image mount registry.git.fsmpi.rwth-aachen.de/schilder/schilder2000:{{TAG}})
# cd usr/local/var/schilder2000-instance
# tar cf - . | podman volume import schilder2000-instance
# popd
# podman image unmount registry.git.fsmpi.rwth-aachen.de/schilder/schilder2000:{{TAG}}
You can also use a volume just for /usr/local/var/schilder2000-instance/data
and mount /usr/local/var/schilder2000-instance/config/config.py separately.
Continue with Configuration and Database migration before starting the container.
Configure your inbound proxy to pass HTTP to port 8080, and your container management to launch the container as required. For example, as plain invocation:
% podman run --rm --detach --publish-all \
--volume schilder2000-instance:/usr/local/var/schilder2000-instance \
registry.git.fsmpi.rwth-aachen.de/schilder/schilder2000:{{TAG}}
Without container¶
You can use our pre-built Python package (wheel) or build it yourself.
Dependencies¶
You need Python 3.9 or later and the dependencies specified in
pyproject.toml. It is suggested to use a virtualenv, as distribution
packages are often missing or outdated.
Some optional dependencies need additional native libraries, namely MySQL/MariaDB Connector/C for MySQL/MariaDB support (both should work with either database), and OpenLDAP and Cyrus SASL for LDAP authentication. If binary wheels for those are not available, you need the development versions of those as well as C compiler and Python development infrastructure. Additionally, Git is required to get the sources of some dependencies.
# apt-get install python3-dev pkg-config gcc libmariadb-dev libldap-dev libsasl2-dev git
# dnf install python3-devel gcc 'pkgconfig(libmariadb)' 'pkgconfig(ldap)' git-core
# apk add -t .schilder2000 python3 mariadb-connector-c libldap # Runtime
# apk add -t .schilder2000-build build-base git mariadb-connector-c-dev \
openldap-dev python3-dev # Build only, can be removed later
To use OS packages as much as possible (note that the versions your distribution provides may be too outdated and you may need to install the development dependencies from above anyway):
# apt-get install python3 weasyprint python3-jinja2 python3-flask \
python3-asgiref python3-flask-sqlalchemy python3-flaskext.wtf alembic \
python3-qrcode python3-ldap python3-authlib python3-psycopg \
python3-mysqldb git
# dnf install python3 \
python3dist\({weasyprint,jinja2,flask\\[async\\],flask-sqlalchemy,flask-wtf,alembic,qrcode}\) \
python3dist\({python-ldap,python3-saml,authlib,psycopg,mysqlclient}\)
# apk add -t .schilder2000 python3 weasyprint py3-jinja2 py3-flask \
py3-asgiref py3-flask-sqlalchemy py3-flask-wtf py3-alembic py3-ldap \
py3-python3-saml py3-authlib py3-psycopg py3-mysqlclient git
If you are not using the pre-built Python package (wheel), you also need Node.js and npm to build the frontend:
# apt-get install npm
# dnf install nodejs-npm
# apk add npm
You will also likely want a WSGI server. If in doubt, choose Gunicorn:
(venv) % pip install gunicorn
# apt-get install gunicorn
# dnf install python3-gunicorn
# apk add py3-gunicorn
Pre-built package¶
In your chosen deployment location (e. g., virtualenv), install the package with
your desired optional extras. These are auth-ldap, auth-saml,
auth-oauth, all-auth, db-postgres, db-mysql, all-db,
all. For example, to install with support for SAML login and Postgres
database:
(venv) % pip install "schilder2000[auth-saml,db-postgres]" \
--index-url https://git.fsmpi.rwth-aachen.de/api/v4/projects/305/packages/pypi/simple
Continue with Configuration.
Building from source¶
This package follows PEP 517 conventions. You can use build to generate
SDist and wheel packages, or run pip install . in your local source tree, …
if you are at this point, you probably know your choices anyway.
The default build process will automatically invoke Node.js/npm to build the
frontend. To disable this behaviour, pass without-npm as build config
setting. This requires the files to already exist. For example:
% npm run build
% python -m build --config-setting without-npm
Configuration¶
Configuration and runtime data is stored in the instance directory. For
container installs, this is /usr/local/var/schilder2000-instance/. For
package installs, this defaults to {{ python prefix
}}/var/schilder2000-instance; if in doubt, try to run flask -A
schilder2000, the error should tell you where it expects the instance
directory. To override, specify an absolute path in the
SCHILDER2000_INSTANCE_PATH environment variable.
Example config and data is located in the examples directory. The templates
there get their footer text and logo from the application config and should also
be useful as an example to write your own templates.
The main application config is located in config/config.py. Available
options:
- SQLALCHEMY_DATABASE_URI: str¶
Required. Database connection URI. See
Flask-SQLAlchemy documentationfor details and additional options. Note that thedb-postgresoptional dependency install thepsycopgdriver (i. e., version 3), notpsycopg2.
- SECRET_KEY: str | bytes¶
Required. Secret key for signing cookies and other security related needs. See
Flask documentationfor details.
- SCHILD_FOOTER: str¶
Footer text used by the templates shipped in
examples/.
- SCHILD_LOGO: str¶
Logo used by the templates shipped in
examples/. Expects a file relative to{{ instance path }}/data/static.
- TEMPLATES_AUTO_RELOAD: bool¶
Reload templates when they are changed. See
Flask documentationfor details.
- PRINTERS: dict[str, str]¶
Required. Available printers. Maps display names to IPP(S) URLs.
- REQUIRE_LOGIN: bool¶
Required. Whether authentication is required to access the service. If enabled, requires additional configuration for Flask-Multipass.
- MULTIPASS_AUTH_PROVIDERS: dict[str, dict]¶
- MULTIPASS_IDENTITY_PROVIDERS: dict[str, dict]¶
- MULTIPASS_PROVIDER_MAP: dict[str, str]¶
See Flask-Multipass documentation for details.
- MULTIPASS_IDENTITY_INFO_KEYS: list¶
Required by Flask-Multipass, but can be empty, as identity information is not used.
See also Flask documentation for additional options and information.
Database migration¶
Unless you use SQLite, create the database in your database server. In all cases, run the migrations:
% flask -A schilder2000 alembic upgrade head # without container
% podman run --rm --volume <...> <image> flask alembic upgrade head # with container
WSGI and webserver setup¶
An example config for Gunicorn is provided in gunicorn.conf.py. This
will listen on [::]:8080 (port 8080, all interfaces), and write the access
log to stdout.
See Flask documentation on Gunicorn and for further information.
If you want to use another WSGI server, configure it to use
schilder2000:create_app() as application object. Note that this is a
factory function that returns the application callable, you have to call it!
To use your webserver to directly serve static files, route /static to {{
python packages directory }}/schilder2000/static and /instance/static to
{{ instance path }}/data/static.