Setting up Serles with Gunicorn¶
In this document we will describe a production-ready setup of Serles using Gunicorn.
Installation¶
python3 -m venv /opt/serles_venv
. /opt/serles_venv/bin/activate
python3 -m pip install serles-acme
In order to run Serles in production, you will need a WSGI HTTP(s) server. We have chosen gunicorn for this example, which ships with Serles. You do not have to use a virtual environment; all dependencies should also be packaged by your distribution.
Configuration¶
Copy the (fully commented) sample configuration file config.ini.example to
/etc/serles/config.ini and modify it to suit your environment.
The included /bin/serles executable will load gunicorn configuration from
/etc/serles/gunicorn_config.py.
For gunicorn, the APP_MODULE string is serles:create_app().
Please see the gunicorn configuration documentation for TLS and port binding.
Below is an example systemd unit file, that uses its own gunicorn from a virtual environment:
[Unit]
Description=gunicorn daemon for Serles
After=network.target
[Service]
PIDFile=/run/acmeproxy/pid
RuntimeDirectory=acmeproxy
Environment="PATH=/opt/serles_venv/bin:/usr/bin"
ExecStart=/opt/serles_venv/bin/gunicorn -c /etc/serles/gunicorn_config.py "serles:create_app()"
ExecReload=/bin/kill -HUP $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Note that the selected backend will have to be configured as well; for the included EJBCA backend see for example EJBCA Dev Environment Quickstart.
Database¶
Serles requires a relational database for storing registered accounts and for
holding the state of orders between HTTP requests. Some clients (notably
certbot) assume that after they registered with an ACME server once, their
public key will be known to that service in perpetuity - and get very upset
when Serles forgets about them. For this reason, this database must be
persistent, and the Account table may not get truncated. All other data can
be ephemeral, and is in fact purged by Serles automatically on a regular
schedule.
For most deployments, an SQLite database is sufficient. If you are expecting multiple simultaneous requests to occur regularly, you should consider configuring Serles to use a client-server database like MySQL/MariaDB instead.
In principle, all databases supported by SQLAlchemy should be supported.