Déploiement de COIN en production chez Illyse¶
COIN est actuellement déployé sur pallando, sous Wheezy.
- Table of contents
- Déploiement de COIN en production chez Illyse
Cette doc reprend chaque point du déploiement chez Illyse, pas à pas. C'est évidemment à adapter.
Le serveur web utilisé est nginx, il y a quelques trucs à adapter pour apache ou lighttpd (le support de sendfile/XSendfile est différent selon les serveurs web, voir ci-dessous).
Installation¶
sudo apt-get install python-virtualenv gunicorn postgresql python-dev python-pip libldap2-dev libpq-dev libsasl2-dev git sudo adduser --disabled-login --disabled-password --gecos coin coin sudo su - coin git clone https://code.ffdn.org/FFDN/coin.git virtualenv COIN . COIN/bin/activate pip install -r coin/requirements.txt # Debian version of gunicorn (wheezy) pip install gunicorn==0.14.5 # For jessie-backports or stretch pip install gunicorn==19.6.0
Configuration¶
Coin lui-même¶
Dans /home/coin/coin/coin/settings_locals.py
(oui, ça fait beaucoup de canards...) :
# -*- coding: utf-8 -*- import os import ldap BASE_DIR = os.path.dirname(os.path.dirname(__file__)) PROJECT_PATH = os.path.abspath(os.path.dirname(__file__)) ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) DATABASES = { # Base de donnée du SI 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'illyse_coin', 'USER': 'illyse_coin', 'PASSWORD': 'monmotdepassepostgresql', 'HOST': 'localhost', # Empty for localhost through domain sockets 'PORT': '', # Empty for default }, # LDAP backend pour stockage et mise à jour de données 'ldap': { 'ENGINE': 'ldapdb.backends.ldap', 'NAME': 'ldap://ldap6.illyse.org:389/', 'TLS': True, 'GLOBAL_OPTIONS': {ldap.OPT_X_TLS_REQUIRE_CERT: ldap.OPT_X_TLS_NEVER}, 'USER': 'cn=coin,ou=services,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR', 'PASSWORD': 'monmotdepasseldap' } } # Backend to use when sending private files to client # In production, must be sendfile.backends.xsendfile with Apache xsend file mod # Or failing xsendfile, use : sendfile.backends.simple # https://github.com/johnsensible/django-sendfile SENDFILE_BACKEND = 'sendfile.backends.nginx' SENDFILE_ROOT = '/home/coin/coin/smedia' SENDFILE_URL = '/protected' GRAPHITE_SERVER = "http://graphite.illyse.org" ALLOWED_HOSTS = ["coin.illyse.org"] SERVER_EMAIL = 'coin@coin.illyse.org' ADMINS = ( ('alertes', 'alertes@illyse.org'), ) MANAGERS = ADMINS STATIC_ROOT = os.path.join(BASE_DIR, 'coin/static/') SECRET_KEY = 'SECRET_KEY_CHANGEME' # Do we use LDAP or not LDAP_ACTIVATE = True # LDAP Base DNs LDAP_USER_BASE_DN = "ou=users,ou=unix,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR" LDAP_GROUP_BASE_DN = "ou=groups,ou=unix,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR" VPN_CONF_BASE_DN = "ou=vpn,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR" DSL_CONF_BASE_DN = "ou=radius,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR" # First UID to use for users LDAP_USER_FIRST_UID = 2000 DATABASE_ROUTERS = ['ldapdb.router.Router'] DEFAULT_FROM_EMAIL = "support@illyse.org" # Membership configuration # Default cotisation in €, per year MEMBER_DEFAULT_COTISATION = 20 MEMBER_MEMBERSHIP_INFO_URL = 'https://www.illyse.org/projects/failocal/wiki/Cotisation' # feed name (used in template), url, max entries to display FEEDS = (('isp', 'http://www.illyse.net/feed/', 3), ('ffdn', 'http://www.ffdn.org/fr/rss.xml', 3))
Permissions Unix pour la génération de factures¶
Les PDF des factures sont générés dans smedia/invoices
, et il faut donc que l'utilisateur sous lequel tourne Django puisse écrire dedans.
mkdir -p /home/coin/coin/smedia/invoices chown coin:www-data /home/coin/coin/smedia/invoices chmod 775 /home/coin/coin/smedia/invoices
Fichiers statiques¶
Il faut mettre tous les fichiers statiques à un seul endroit, où ils seront servis par Nginx. Pour faire ça, en tant qu'utilisateur coin
:
. COIN/bin/activate cd coin python manage.py collectstatic
Postgresql¶
Création de l'utilisateur postgresql et de la base¶
sudo su - postgres createuser -D -E -P -R -S illyse_coin # Enter password (same as in coin config) createdb -O illyse_coin illyse_coin
Création des tables¶
sudo su - coin . COIN/bin/activate cd coin python manage.py migrate
Import des données initiales dans la base¶
# Infos spécifiques à Illyse, pour la personnalisation de l'interface ainsi que pour isp.json python manage.py loaddata illyse # Pool d'IP d'Illyse python manage.py loaddata ip_pool
Nginx¶
Dans
/etc/nginx/site-available/coin.illyse.org:
server { listen [::]:80; server_name coin.illyse.org; rewrite ^(.*) https://$server_name$1 permanent; } server { listen [::]:443 ssl; server_name coin.illyse.org; ssl on; ssl_certificate /etc/ssl/certs/illyse-pallando-cert-cacert.pem; ssl_certificate_key /etc/ssl/private/illyse-pallando-privkey.pem; root /var/www/; access_log /var/log/nginx/coin.illyse.org.access.log; error_log /var/log/nginx/coin.illyse.org.error.log; proxy_redirect off; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; location /static/ { alias /home/coin/coin/coin/static/; } # Invoices, see SENDFILE_* options in coin location /protected/ { internal; alias /home/coin/coin/smedia/; } location / { proxy_pass http://localhost:8282; } }
Gunicorn¶
Dans /etc/gunicorn.d/coin
:
CONFIG = { 'working_dir': '/home/coin/coin', 'python': '/home/coin/COIN/bin/python', 'user': 'www-data', 'group': 'www-data', 'args': ( '--bind=127.0.0.1:8282', '--workers=3', # '--worker-class=egg:gunicorn#sync', # '--timeout=30', #'--preload', 'coin.wsgi', ), }
Crontab¶
En tant qu'utilisateur coin
, on ajoute des tâches cron : générer des factures, et envoyer des mails de rappel de cotisation.
MAILTO=tresorier@illyse.org # m h dom mon dow command 59 23 * * * /home/coin/COIN/bin/python /home/coin/coin/manage.py charge_subscriptions 42 3 * * * /home/coin/COIN/bin/python /home/coin/coin/manage.py call_for_membership_fees
Migration de la base de données¶
Pour migrer la base de données complète d'une machine à une autre, le plus simple est de la dumper en JSON d'un côté et de la recharger de l'autre côté.
python manage.py dumpdata --indent 2 --natural-foreign --natural-primary > ../dump-20150530-natural.json
Attention, les options --natural-foreign --natural-primary
sont nécessaires, voir https://docs.djangoproject.com/en/1.8/topics/serialization/#topics-serialization-natural-keys
Pour charger le dump de l'autre côté :
python manage.py loaddata dump-20150530-natural.json
Au passage, en cas de déménagement de serveur, bien penser à copier les PDF qui sont dans smedia
...
Installation de graphite¶
Graphite est utilisé pour tracer les graphes de trafic. Graphite est interrogé uniquement par COIN, et est alimenté par le serveur VPN.
Installation en utilisant les packages debian:
sudo apt install graphite-web graphite-carbon Effacer les fichiers de base de données lors de la suppression de graphite-carbon ? >> Non
Par défaut, Graphite utilise une BDD SQLLite, pour une utilisation en production, on préfère une base postgres, qui gère les instances multiples.
sudo apt install postgresql libpq-dev python-psycopg2 su - postgres psql CREATE USER graphite WITH PASSWORD 'miaou'; CREATE DATABASE graphite WITH OWNER graphite; \q sudo vim /etc/graphite/local_settings.py SECRET_KEY = 'a_secret_miaou_key' TIME_ZONE = 'Europe/Paris' USE_REMOTE_USER_AUTHENTICATION = True DATABASES = { 'default': { 'NAME': 'graphite', 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'USER': 'graphite', 'PASSWORD': 'miaou', 'HOST': '::1', 'PORT': '' } } sudo graphite-manage syncdb Would you like to create one now? (yes/no): no (oui pour avoir un user pour se loguer sur l'interface web) sudo vim /etc/default/graphite-carbon CARBON_CACHE_ENABLED=true sudo vim /etc/carbon/carbon.conf ENABLE_LOGROTATION = True CARBON_METRIC_PREFIX = vpn1 PICKLE_RECEIVER_INTERFACE = @ip_listen sudo vim /etc/carbon/storage-schemas.conf [vpn1] pattern = ^vpn1\. retentions = 5m:31d,30m:1y #A vérifier/adapter : On conserve 1 point pour 5minutes sur 31jours, et 1 point pour 30minutes sur 1an. sudo cp /usr/share/doc/graphite-carbon/examples/storage-aggregation.conf.example /etc/carbon/storage-aggregation.conf service carbon-cache start
A ce stade, le serveur VPN doit être capable d'envoyer les metrics à Carbon. (communication en TCP sur le port 2004 par défaut)
Installation d'un serveur web pour graphite-web et servir les images de graphes à COIN.
Avec nginx + uwsgi :
sudo apt install nginx uwsgi uwsgi-plugin-python vim /etc/nginx/sites-available/graphite upstream graphite { server unix:/run/uwsgi/app/graphite/socket; } server { listen [::]:80; server_name graphite.toto.tld; access_log /var/log/nginx/graphite.access.log; error_log /var/log/nginx/graphite.error.log; location / { include uwsgi_params; uwsgi_pass graphite; } } sudo ln -s /etc/nginx/sites-available/graphite /etc/nginx/sites-enabled/graphite vim /etc/uwsgi/apps-available/graphite.ini [uwsgi] processes = 2 socket = /run/uwsgi/app/graphite/socket chdir = /usr/share/graphite-web mount = /graphite=/usr/share/graphite-web/graphite.wsgi file = graphite.wsgi gid = www-data uid = _graphite sudo ln -s /etc/uwsgi/apps-available/graphite.ini /etc/uwsgi/apps-enabled/
Sous debian 10, python3 et conf uwsgi légèrment différente:
sudo apt install uwsgi-plugin-python3 vim /etc/uwsgi/apps-available/graphite.ini [uwsgi] uid = _graphite gid = _graphite buffer-size = 32768 chdir = /usr/share/graphite-web env = DJANGO_SETTINGS_MODULE=graphite.settings max-requests = 100 module = graphite.wsgi:application plugins = python3 processes = 5 socket = /run/uwsgi/app/graphite/socket touch-reload = /usr/lib/python3/dist-packages/graphite/wsgi.py
Ou bien avec apache :
sudo apt-get install apache2 libapache2-mod-wsgi sudo a2dissite 000-default sudo cp /usr/share/graphite-web/apache2-graphite.conf /etc/apache2/sites-available sudo a2ensite apache2-graphite sudo service apache2 reloadDans le firewall de la machine du graphite, on autorise:
- La machine qui héberge COIN à attaquer sur le port tcp 80 (pour servir les graphes)
- Le serveur VPN à attaquer sur le port tcp 2004 (pour alimenter les graphes en données)
Updated by Baptiste Berton over 2 years ago · 9 revisions