# Publ: Self-hosting Publ

Last updated:

This assumes that you have your own webserver where you can run your site. There are two parts to this: running the Publ service, and routing public traffic from the fronting webserver (Apache, nginx, fhttpd, etc.) to it.

This list is not exhaustive; if there is a mechanism that you’d like to see supported, feel free to open an issue or, better yet, pull request with details!

## Running the Publ service

### Prerequisites

You will need Python 3. The most reliable way to install this is via pyenv, but any system-provided Python 3 will do, as long as it meets the minimum system requirements.

The easiest way to manage your package dependencies is with poetry; you can see their installation instructions for more information. pipenv and virtualenv also work but these instructions will focus on the use of poetry.

Your Publ environment needs to have a WSGI server available. gunicorn is a good choice for this. The ideal means of installing gunicorn is directly into your site’s environment. If you’re using poetry then that’s done with:

It will also be helpful to know the full path to the poetry command. You can usually find this with

### Basic approach

Anything that runs the application server should change into the site’s working directory, and then start the gunicorn process with

which will use the app object declared in app.py (per the getting started guide) and listen on a socket file named gunicorn.sock. The presence of that socket file will also indicate whether the site is up and running.

Note that you don’t have to put gunicorn.sock in the same directory as the application – it can go anywhere that the web server has access. For example, it’s nice to make a \$HOME/.vhosts directory to keep your socket files, named with the site name:

This way you can also set the directory permissions on your site files with chmod 700 which prevents other users of the server from peeking into them.

### systemd

If you’re on a UNIX that uses systemd (for example, recent versions of Ubuntu or CentOS), the preferred approach is to run the site as a user service. Here is an example service file:

Install this file as e.g. ~/.config/systemd/user/example.com.service and then you should be able to start the server with:

and the site should now be up and running on the local port; as long as it’s up there should be a socket file named gunicorn.sock in the site’s directory.

However, this service will only run while the user is logged in; in order to make it run persistently, have an admin set your user to “linger” with e.g.:

Anyway, once you have this service set up, you can use systemctl to do a number of useful things; some example commands:

See the systemctl manual page for more infromation.

### cron

If all else fails, you can use a cron job as a makeshift supervisor; create a file named cron-launcher.sh in your site directory:

and then run crontab -e and add a line like:

### Next steps

You can verify that the site is working with curl; for example:

By default, gunicorn only runs with a small number of render threads. You might want to increase this with the --threads parameter, e.g.:

## Routing traffic

Configuring Publ to work with your web server is a matter of configuring the fronting httpd as a proxy to your Publ instance’s socket. The two most common are Apache and nginx, but there are others as well.

### Apache

To use this with Apache, you’ll need mod_proxy installed and enabled.

Next, you’ll need to configure a vhost to forward your domain’s traffic to the gunicorn socket. Here is a basic Apache configuration (e.g. /etc/apache2/sites-enabled/100-example.com.conf), showing how to configure both http and https:

Note that both connections go over the same socket; you can have arbitrarily many fronting configurations to the same Publ instance, even with different domain names! Publ doesn’t mind at all.

If you use Let’s Encrypt to manage your SSL certificate, the configuration change made by certbot --apache should “just work” although you will want to make sure that it sets X-Forwarded-Protocol or else Publ will still generate http:// URLs for things, which is probably not what you want.

### nginx

Here is an example nginx configuration, e.g. /etc/nginx/sites-available/example.com:

### Others

The basic premise to configuring any arbitrary httpd to work with Publ:

• Reverse proxy from your vhost to the UNIX socket
• On SSL, add X-Forwarded-Protocol ssl
• Try to preserve the incoming Host and set X-Forwarded-For if at all possible