2023-12-24 14:59:39 +00:00
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
--------
2024-05-13 14:44:02 +00:00
.. todo ::
Write a gunicorn configuration sample file.
2023-12-24 14:59:39 +00:00
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;
2024-11-20 13:18:48 +00:00
server_name auth.mydomain.example;
2023-12-24 14:59:39 +00:00
return 301 https://$server_name$request_uri;
}
server {
2024-11-20 13:18:48 +00:00
server_name auth.mydomain.example;
2023-12-24 14:59:39 +00:00
listen 443 ssl http2;
listen [::]:443 ssl http2;
2024-11-20 13:18:48 +00:00
ssl_certificate /etc/letsencrypt/live/auth.mydomain.example/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/auth.mydomain.example/privkey.pem;
2023-12-24 14:59:39 +00:00
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;
2024-08-07 12:17:23 +00:00
more_set_headers Cache-Control public;
2023-12-24 14:59:39 +00:00
}
}
location / {
include uwsgi_params;
uwsgi_pass unix:/etc/canaille/uwsgi.sock;
}
}
Apache
------
2024-08-16 07:41:05 +00:00
.. code-block :: apache
<VirtualHost *:80>
2024-11-20 13:18:48 +00:00
ServerName auth.mydomain.example
ServerAdmin admin@mydomain.example
2024-08-16 07:41:05 +00:00
CustomLog /opt/canaille/logs/apache-http-access.log combined
ErrorLog /opt/canaille/logs/apache-http-error.log
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L] </VirtualHost>
</VirtualHost>
<VirtualHost *:443>
2024-11-20 13:18:48 +00:00
ServerName auth.mydomain.example
ServerAdmin admin@mydomain.example
2024-08-16 07:41:05 +00:00
Protocols h2 http/1.1
CustomLog /opt/canaille/logs/apache-https-access.log combined
ErrorLog /opt/canaille/logs/apache-https-error.log
SSLEngine On
2024-11-20 13:18:48 +00:00
SSLCertificateFile /etc/letsencrypt/live/auth.mydomain.example/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/auth.mydomain.example/privkey.pem
2024-08-16 07:41:05 +00:00
Include /etc/letsencrypt/options-ssl-apache.conf
ProxyPreserveHost On
ProxyPass /static/ !
ProxyPass / unix:/etc/canaille/uwsgi.sock
ProxyPassReverse / unix:/etc/canaille/uwsgi.sock
2024-05-13 14:44:02 +00:00
2024-08-16 07:41:05 +00:00
RequestHeader set X-FORWARDED-PROTOCOL ssl
RequestHeader set X-FORWARDED-SSL on
</VirtualHost>
2023-12-24 14:59:39 +00:00
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
=========
2024-11-20 13:18:48 +00:00
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.example `` and your Canaille domain is `` auth.mydomain.example `` 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 `` john.doe@mydomain.example `` , then the application would perform a WebFinger request at `` https://mydomain.example/.well-known/webfinger `` and the response would contain the address of the authentication server `` https://auth.mydomain.example `` . With this information the third party application can redirect the user to the Canaille authentication page.
2023-12-24 14:59:39 +00:00
2024-11-20 13:18:48 +00:00
The difficulty here is that the WebFinger endpoint must be hosted at the top-level domain (i.e. `` mydomain.example `` ) while the authentication server might be hosted on a sublevel (i.e. `` auth.mydomain.example `` ). 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.
2023-12-24 14:59:39 +00:00
2024-05-13 14:44:02 +00:00
Here are configuration examples for Nginx or Apache:
2023-12-24 14:59:39 +00:00
.. code-block :: nginx
2024-05-13 14:44:02 +00:00
:caption: Nginx webfinger configuration for a top level domain
2023-12-24 14:59:39 +00:00
server {
listen 443;
2024-11-20 13:18:48 +00:00
server_name mydomain.example;
rewrite ^/.well-known/webfinger https://auth.mydomain.example/.well-known/webfinger permanent;
2023-12-24 14:59:39 +00:00
}
.. code-block :: apache
2024-05-13 14:44:02 +00:00
:caption: Apache webfinger configuration for a top level domain
2023-12-24 14:59:39 +00:00
<VirtualHost *:443>
2024-11-20 13:18:48 +00:00
ServerName mydomain.example
2023-12-24 14:59:39 +00:00
RewriteEngine on
2024-11-20 13:18:48 +00:00
RewriteRule "^/.well-know/webfinger" "https://auth.mydomain.example/.well-known/webfinger" [R,L]
2023-12-24 14:59:39 +00:00
</VirtualHost>
2023-12-18 17:06:03 +00:00
Create the first user
=====================
2023-12-24 14:59:39 +00:00
2024-05-13 14:44:02 +00:00
Once canaille is installed, soon enough you will need to add users.
To create your first user you can use the :ref: `canaille create <cli_create>` CLI.
.. code-block :: bash
2024-08-15 14:23:01 +00:00
canaille create user --user-name admin --password admin --emails admin@mydomain.example --given-name George --family-name Abitbol
2023-12-24 14:59:39 +00:00
.. _WebFinger: https://www.rfc-editor.org/rfc/rfc7033.html