Deploying with Python¶
Keystone-API can be installed directly on a machine using system packages. Doing so requires administrative privileges and assumes you are managing system services via systemd.
Note
When deploying to production, it is strongly recommended to install the application under a dedicated, unprivileged service account.
In the following example, a user account called keystone
is used.
Installing the API¶
The keystone_api
package can be installed using the pip
or pipx
package managers.
pipx install --include-deps keystone-api
pip install keystone-api
If you intend to authenticate users via LDAP credentials, you will need to manually specify LDAP support in the install
command.
This will require the LDAP development binaries to be available on the host machine.
pipx install --include-deps keystone-api[ldap]
pip install keystone-api[ldap]
If the installation was successful, the packaged CLI tool will be available in your working environment.
Use the --help
option to view the available commands.
keystone-api --help
The keystone-api
utility does not support tab autocompletion by default.
To enable autocomplete for the Bash shell, use the enable_autocomplete
command.
keystone-api enable_autocomplete
Deploying Dependencies¶
Keystone-API requires several backend services to support its operation. Specific instructions are provided below on configuring each dependency.
Redis¶
Most Redis server instances will work out of the box so long as the connection and authentication values are set correctly in the API settings.
SMTP¶
The API requires an SMTP server to issue user notifications. No specific requirements are imposed on the server itself, only that the connection and authentication values are set correctly in the API settings.
PostgreSQL¶
Using PostgreSQL for the application database is strongly recommended. After deploying a PostgreSQL server, you will need to create a dedicated database and user account. Start by launching a new SQL session with admin permissions.
sudo -u postgres psql
Next, create a database and a keystone
service account.
Make sure to replace the password field with a secure value.
create database keystone;
create user keystone with encrypted password '[PASSWORD]';
grant all privileges on database keystone to keystone;
Celery¶
Celery and Celery Beat are both included when installing the keystone_api
package.
Both applications should be launched using keystone_api.apps.scheduler
as the target application.
celery -A keystone_api.apps.scheduler worker
celery -A keystone_api.apps.scheduler beat --scheduler django_celery_beat.schedulers:DatabaseScheduler
The celery
command executes as a foreground process by default.
The following unit files are provided as a starting point to daemonize the process via the systemd service manager.
Warning
Celery can fill up it's log directory fairly quickly, especially when running multiple workers simultaneously. The Celery log files should be rotated regularly to prevent excessive disk usage.
[Unit]
Description=Celery workers for Keystone
After=network.target
[Service]
Type=forking
User=keystone
Group=keystone
RuntimeDirectory=celery
WorkingDirectory=/home/keystone
EnvironmentFile=/home/keystone/keystone.env
ExecStart=/bin/sh -c '/home/keystone/.local/bin/celery multi start w1 -A keystone_api.apps.scheduler'
ExecStop=/bin/sh -c '/home/keystone/.local/bin/celery multi stopwait w1'
ExecReload=/bin/sh -c '/home/keystone/.local/bin/celery multi restart w1'
[Install]
WantedBy=multi-user.target
[Unit]
Description=Celery Beat scheduler for keystone
After=network.target
[Service]
Type=simple
User=keystone
Group=keystone
RuntimeDirectory=beat
WorkingDirectory=/home/keystone
EnvironmentFile=/home/keystone/keystone.env
ExecStart=/bin/sh -c '/home/keystone/.local/bin/celery -A keystone_api.apps.scheduler beat --scheduler django_celery_beat.schedulers:DatabaseScheduler'
Restart=always
[Install]
WantedBy=multi-user.target
Deploying the Application¶
Before launching the API, migrate the database to the latest schema version and collect any static files. See the Settings page for details on configuring database credentials and the static files location.
keystone-api migrate
keystone-api collectstatic
Gunicorn is the recommended webserver for running the Keystone-API.
When launching the webserver, use the WSGI entrypoint located under keystone_api.main.wsgi:application
.
gunicorn --bind 0.0.0.0:8000 keystone_api.main.wsgi:application
The gunicorn
command executes as a foreground process by default.
The following unit files are provided as a starting point to daemonize the process via the systemd service manager.
[Unit]
Description=Gunicorn server daemon for Keystone
Requires=keystone-server.socket
After=network.target
[Service]
Type=notify
User=keystone
Group=keystone
RuntimeDirectory=gunicorn
WorkingDirectory=/home/keystone
EnvironmentFile=/home/keystone/keystone.env
ExecStart=/home/keystone/.local/bin/gunicorn keystone_api.main.wsgi
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[Unit]
Description=Gunicorn socket for Keystone
[Socket]
ListenStream=/run/gunicorn.sock
SocketUser=nginx
[Install]
WantedBy=sockets.target
Configuring the Proxy¶
Using a web proxy in front of the API server is recommended to improve load balancing, security, and static file handling. Nginx is recommended, but administrators are welcome to use a proxy of their choice. A starter Nginx configuration file is provided below for convenience.
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/pki/tls/certs/keystone.crt;
ssl_certificate_key /etc/pki/tls/private/keystone.key;
location / {
proxy_pass http://unix:/run/gunicorn.sock;
}
location /uploads { # (1)!
alias /var/keystone-api/upload_files;
}
}
- The
/uploads
directory is used to host user files and should match theCONFIG_UPLOAD_DIR
in application settings.
Upgrading Application Versions¶
Software updates are handled by the Python package manager. System services should be taken offline before upgrading to a new version.
Danger
Application upgrades may involve irreversible database migrations. Always ensure the application database is backed up before applying updates.
Note
The systemd configurations outlined above are designed to automatically start the keystone-server
service in response to incoming traffic.
When performing upgrades, it is best to prevent inadvertent restarts by stopping incoming traffic from the upstream proxy.
This is achievable by taking the proxy offline or by modifying the proxy config and restarting the proxy service.
systemctl stop nginx
systemctl stop keystone-server
systemctl stop keystone-beat
systemctl stop keystone-worker
# Pause here to backup the application database
pipx upgrade keystone-api
keystone-api migrate
keystone-api collectstatic
systemctl start keystone-worker
systemctl start keystone-beat
systemctl start keystone-server
systemctl start nginx
systemctl stop nginx
systemctl stop keystone-server
systemctl stop keystone-beat
systemctl stop keystone-worker
# Pause here to backup the application database
pip install --upgrade keystone-api
keystone-api migrate
keystone-api collectstatic
systemctl start keystone-worker
systemctl start keystone-beat
systemctl start keystone-server
systemctl start nginx