Skip to content

Commit

Permalink
doc: split installation page
Browse files Browse the repository at this point in the history
  • Loading branch information
azmeuk committed Dec 24, 2023
1 parent 6dac4a1 commit c362f02
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 168 deletions.
5 changes: 3 additions & 2 deletions doc/backends.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
Backends
#############

Canaille can read and save data in different databases.
This page presents the different database backends and their specificities:

.. contents::
:local:

Canaille can read and save data in different databases:

Memory
======

Expand Down
10 changes: 10 additions & 0 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __getattr__(cls, name):

extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.autosectionlabel",
"sphinx.ext.doctest",
"sphinx.ext.graphviz",
"sphinx.ext.intersphinx",
Expand All @@ -52,6 +53,10 @@ def __getattr__(cls, name):

intersphinx_mapping = {
"python": ("https://docs.python.org/3", None),
"authlib": ("https://docs.authlib.org/en/latest", None),
"flask": ("https://flask.palletsprojects.com", None),
"flask-babel": ("https://python-babel.github.io/flask-babel", None),
"flask-wtf": ("https://flask-wtf.readthedocs.io", None),
}

issues_uri = "https://gitlab.com/yaal/canaille/-/issues/{issue}"
Expand Down Expand Up @@ -94,3 +99,8 @@ def __getattr__(cls, name):
"Miscellaneous",
)
]

# -- Options for autosectionlabel -----------------------------------------

autosectionlabel_prefix_document = True
autosectionlabel_maxdepth = 2
165 changes: 165 additions & 0 deletions doc/deployment.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
Deployment
##########

Application service
===================

After having finished Canaille installation you have to run it in a WSGI application server.
Here are some WSGI server configuration examples you can pick. Do not forget to update the paths.

gunicorn
--------

TBD

uwsgi
-----

.. code-block:: ini
[uwsgi]
virtualenv=/opt/canaille/env
socket=/etc/canaille/uwsgi.sock
plugin=python3
module=canaille:create_app()
lazy-apps=true
master=true
processes=1
threads=10
need-app=true
thunder-lock=true
touch-chain-reload=/etc/canaille/uwsgi-reload.fifo
enable-threads=true
reload-on-rss=1024
worker-reload-mercy=600
buffer-size=65535
disable-write-exception = true
env = CONFIG=/etc/canaille/config.toml
Webserver
=========

Now you have to plug your WSGI application server to your webserver so it is accessible on the internet.
Here are some webserver configuration examples you can pick:

Nginx
-----

.. code-block:: nginx
server {
listen 80;
listen [::]:80;
server_name auth.mydomain.tld;
return 301 https://$server_name$request_uri;
}
server {
server_name auth.mydomain.tld;
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/letsencrypt/live/moncompte.nubla.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/moncompte.nubla.fr/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_stapling on;
ssl_stapling_verify on;
index index.html index.php;
charset utf-8;
client_max_body_size 10M;
access_log /opt/canaille/logs/nginx.access.log;
error_log /opt/canaille/logs/nginx.error.log;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "same-origin" always;
location /static {
root /opt/canaille/src/canaille;
location ~* ^.+\.(?:css|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|woff2|svg)$ {
access_log off;
expires 30d;
add_header Cache-Control public;
}
}
location / {
include uwsgi_params;
uwsgi_pass unix:/etc/canaille/uwsgi.sock;
}
}
Apache
------

TBD

Recurrent jobs
==============

You might want to clean up your database to avoid it growing too much. You can regularly delete
expired tokens and authorization codes with:

.. code-block:: bash
env CONFIG="$CANAILLE_CONF_DIR/config.toml" FLASK_APP=canaille "$CANAILLE_INSTALL_DIR/env/bin/canaille" clean
Webfinger
=========

You may want to configure a `WebFinger`_ endpoint on your main website to allow the automatic discovery of your Canaille installation based on the account name of one of your users. For instance, suppose your domain is ``mydomain.tld`` and your Canaille domain is ``auth.mydomain.tld`` and there is a user ``john.doe``. A third-party application could require to authenticate the user and ask them for a user account. The user would give their account ``[email protected]``, then the application would perform a WebFinger request at ``https://mydomain.tld/.well-known/webfinger`` and the response would contain the address of the authentication server ``https://auth.mydomain.tld``. With this information the third party application can redirect the user to the Canaille authentication page.

The difficulty here is that the WebFinger endpoint must be hosted at the top-level domain (i.e. ``mydomain.tld``) while the authentication server might be hosted on a sublevel (i.e. ``auth.mydomain.tld``). Canaille provides a WebFinger endpoint, but if it is not hosted at the top-level domain, a web redirection is required on the ``/.well-known/webfinger`` path.

Nginx
-----

.. code-block:: nginx
server {
listen 443;
server_name mydomain.tld;
rewrite ^/.well-known/webfinger https://auth.mydomain.tld/.well-known/webfinger permanent;
}
Apache
------

.. code-block:: apache
<VirtualHost *:443>
ServerName mydomain.tld
RewriteEngine on
RewriteRule "^/.well-know/webfinger" "https://auth.mydomain.tld/.well-known/webfinger" [R,L]
</VirtualHost>
Create your first user
======================

Once canaille is installed, you have several ways to populate the database. The obvious one is by adding
directly users and group into your LDAP directory. You might also want to temporarily enable then
``ENABLE_REGISTRATION`` configuration parameter to allow you to create your first users. Then, if you
have configured your ACLs properly then you will be able to manage users and groups through the Canaille
interface.

.. _WebFinger: https://www.rfc-editor.org/rfc/rfc7033.html
1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Table of contents
:maxdepth: 2

install
deployment
backends
configuration
troubleshooting
Expand Down
169 changes: 3 additions & 166 deletions doc/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ Choose a path where to store your configuration file. You can pass any configura
sudo mkdir --parents "$CANAILLE_CONF_DIR"
sudo cp $CANAILLE_INSTALL_DIR/env/lib/python*/site-packages/canaille/config.sample.toml "$CANAILLE_CONF_DIR/config.toml"
You should then edit your configuration file to adapt the values to your needs.
You should then edit your configuration file to adapt the values to your needs. Look at the configuration details in the :doc:`configuration` page.

Installation
============
Install and check
=================

Automatic schemas installation
------------------------------
Expand Down Expand Up @@ -112,166 +112,3 @@ After a manual installation, you can check your configuration file with the foll
.. code-block:: bash
env CONFIG="$CANAILLE_CONF_DIR/config.toml" "$CANAILLE_INSTALL_DIR/env/bin/canaille" check
Application service
===================

Finally you have to run canaille in a WSGI application server.
Here are some WSGI server configuration examples you can pick. Do not forget to update the paths.

gunicorn
--------

TBD

uwsgi
-----

.. code-block:: ini
[uwsgi]
virtualenv=/opt/canaille/env
socket=/etc/canaille/uwsgi.sock
plugin=python3
module=canaille:create_app()
lazy-apps=true
master=true
processes=1
threads=10
need-app=true
thunder-lock=true
touch-chain-reload=/etc/canaille/uwsgi-reload.fifo
enable-threads=true
reload-on-rss=1024
worker-reload-mercy=600
buffer-size=65535
disable-write-exception = true
env = CONFIG=/etc/canaille/config.toml
Webserver
=========

Now you have to plug your WSGI application server to your webserver so it is accessible on the internet.
Here are some webserver configuration examples you can pick:

Nginx
-----

.. code-block:: nginx
server {
listen 80;
listen [::]:80;
server_name auth.mydomain.tld;
return 301 https://$server_name$request_uri;
}
server {
server_name auth.mydomain.tld;
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/letsencrypt/live/moncompte.nubla.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/moncompte.nubla.fr/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_stapling on;
ssl_stapling_verify on;
index index.html index.php;
charset utf-8;
client_max_body_size 10M;
access_log /opt/canaille/logs/nginx.access.log;
error_log /opt/canaille/logs/nginx.error.log;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "same-origin" always;
location /static {
root /opt/canaille/src/canaille;
location ~* ^.+\.(?:css|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|woff2|svg)$ {
access_log off;
expires 30d;
add_header Cache-Control public;
}
}
location / {
include uwsgi_params;
uwsgi_pass unix:/etc/canaille/uwsgi.sock;
}
}
Apache
------

TBD

Recurrent jobs
==============

You might want to clean up your database to avoid it growing too much. You can regularly delete
expired tokens and authorization codes with:

.. code-block:: bash
env CONFIG="$CANAILLE_CONF_DIR/config.toml" FLASK_APP=canaille "$CANAILLE_INSTALL_DIR/env/bin/canaille" clean
Webfinger
=========

You may want to configure a `WebFinger`_ endpoint on your main website to allow the automatic discovery of your Canaille installation based on the account name of one of your users. For instance, suppose your domain is ``mydomain.tld`` and your Canaille domain is ``auth.mydomain.tld`` and there is a user ``john.doe``. A third-party application could require to authenticate the user and ask them for a user account. The user would give their account ``[email protected]``, then the application would perform a WebFinger request at ``https://mydomain.tld/.well-known/webfinger`` and the response would contain the address of the authentication server ``https://auth.mydomain.tld``. With this information the third party application can redirect the user to the Canaille authentication page.

The difficulty here is that the WebFinger endpoint must be hosted at the top-level domain (i.e. ``mydomain.tld``) while the authentication server might be hosted on a sublevel (i.e. ``auth.mydomain.tld``). Canaille provides a WebFinger endpoint, but if it is not hosted at the top-level domain, a web redirection is required on the ``/.well-known/webfinger`` path.

Nginx
-----

.. code-block:: nginx
server {
listen 443;
server_name mydomain.tld;
rewrite ^/.well-known/webfinger https://auth.mydomain.tld/.well-known/webfinger permanent;
}
Apache
------

.. code-block:: apache
<VirtualHost *:443>
ServerName mydomain.tld
RewriteEngine on
RewriteRule "^/.well-know/webfinger" "https://auth.mydomain.tld/.well-known/webfinger" [R,L]
</VirtualHost>
Create your first user
======================

Once canaille is installed, you have several ways to populate the database. The obvious one is by adding
directly users and group into your LDAP directory. You might also want to temporarily enable then
``ENABLE_REGISTRATION`` configuration parameter to allow you to create your first users. Then, if you
have configured your ACLs properly then you will be able to manage users and groups through the Canaille
interface.

.. _WebFinger: https://www.rfc-editor.org/rfc/rfc7033.html

0 comments on commit c362f02

Please sign in to comment.