Exécuter une application WSGI avec systemd sous openSUSE

Ce billet est une « mise à jour » du précédent, concernant le déploiement de Mercurial, sous forme d'application WSGI.

Le fait de passer par le script /etc/init.d/after.local, pour lancer une telle application, ne m'a pas entièrement satisfait. C'est pourquoi j'ai décidé de me repencher sur ce point.

À la fin de l'article, j'évoqué, Gunicorn, comme serveur WSGI, en proposant même un exemple de fichier .service. Je me suis donc inspiré de celui-ci pour en créer un.

Le but c'est de pouvoir exécuter le script, hgweb.wsgi au démarrage.

Je vous propose donc, wsgi-hg.service. Il permet de lancer (ou d'arrêter) notre script WSGI. Il n'y a rien de particulier, à part la condition ConditionPathExistsGlob, qui me sert à tester si un fichier .wsgi (en réalité hgweb.wsgi) est présent sur le serveur, si c'est le cas, le service pourra être lancé.

Il faut bien sur, avoir correctement configuré son serveur Web. Par exemple pour Nginx :

[...]

    # Subdomain settings
    #
    # Mercurial
    #
    server {
	listen 80;
	server_name hg.errements.net;

	access_log /var/log/nginx/access-hg.log;

	location / {
		root /srv/www/htdocs/vhosts/hg;
		autoindex	off;

		proxy_path	http://127.0.0.1:8500;
		proxy_set_header	Host	$host;
	}
    }

[...]

Mais on peut aller encore plus loin, actuellement dans notre script wsgi, le socket réseau (le port, et l'adresse IP) sont codés en « dur ». On pourrait les passer en paramètre. Il faut pour cela utiliser le module argparse.

olivier@bornem:~ $ python hgweb-opts.wsgi -h                                 
usage: hgweb-opts.wsgi [-h] host port

positional arguments:
  host        Add IP address
  port        Add port number

optional arguments:
  -h, --help  show this help message and exit
olivier@bornem:~ $ 

On peut voir que deux paramètres sont obligatoires, l'ordre à une importance.

  • host, par exemple 127.0.0.1
  • port, par exemple 8500
olivier@bornem:~ $ python hgweb-opts.wsgi 127.0.0.1 8500                     
serving on http://127.0.0.1:8500

On peut maintenant adapter le fichier wsgi-hg.service, pour pouvoir passer ces paramètres à la ligne ExecStart.

Voici la ligne à copier.

[...]
ExecStart=/usr/bin/python2.7 /srv/www/htdocs/vhosts/hg/hgweb-opts.wsgi 127.0.0.1 8500
[...]

Pour lancer le service, on place ce fichier dans /etc/systemd/system/default.target.wants/ (ou /lib/systemd/system/).

root@bornem:~ # systemctl start wsgi-hg.service
root@bornem:~ # systemctl status wsgi-hg.service
wsgi-hg.service - Starts WSGI script (mercurial)
	  Loaded: loaded (/lib/systemd/system/wsgi-hg.service; disabled)
	  Active: active (running) since Sun, 29 Jan 2012 21:26:45 +0100; 38s ago
	 Process: 17745 ExecStartPre=/bin/echo Starting WSGI script for mercurial  (code=exited, status=0/SUCCESS)
	Main PID: 17747 (python2.7)
	  CGroup: name=systemd:/system/wsgi-hg.service
		  └ 17747 /usr/bin/python2.7 /srv/www/htdocs/vhosts/hg/hgweb...
root@bornem:~ #