Djadhere » Historique » Version 1
Élie Bouttier, 08/10/2016 12:28
1 | 1 | Élie Bouttier | h1. Djadhere |
---|---|---|---|
2 | 1 | Élie Bouttier | |
3 | 1 | Élie Bouttier | C’est le SI de tetaneutral.net ! Il est codé en Python avec le framework web Django. |
4 | 1 | Élie Bouttier | Il est accessible à l’adresse https://adherents.tetaneutral.net. |
5 | 1 | Élie Bouttier | |
6 | 1 | Élie Bouttier | h2. Contribuer |
7 | 1 | Élie Bouttier | |
8 | 1 | Élie Bouttier | Le code source est sur la forge de ffdn : https://code.ffdn.org/tetaneutral.net/djadhere |
9 | 1 | Élie Bouttier | Celle-ci permet également d’ouvrir des tickets ou de créer des pull-requests. |
10 | 1 | Élie Bouttier | Pour rejoindre l’équipe, demander à djanos ou nim65s sur IRC. |
11 | 1 | Élie Bouttier | |
12 | 1 | Élie Bouttier | h2. Déploiement |
13 | 1 | Élie Bouttier | |
14 | 1 | Élie Bouttier | Il est déployé sur la VM djadhere.tetaneutral.net (Debian 8.6 Jessie). |
15 | 1 | Élie Bouttier | Deux instances sont déployées, la première pour la version de production, et la deuxième pour la version de developpement. |
16 | 1 | Élie Bouttier | |
17 | 1 | Élie Bouttier | Le serveur web utilisé est nginx. |
18 | 1 | Élie Bouttier | La configuration se trouve dans le fichier @/etc/nginx/sites-available/djadhere@. |
19 | 1 | Élie Bouttier | |
20 | 1 | Élie Bouttier | Les certificats letsencrypt sont généré avec @certbot@ (installé depuis les backports) : |
21 | 1 | Élie Bouttier | |
22 | 1 | Élie Bouttier | @certbot -c /etc/letsencrypt/webroot.ini -d mondomaine.tetaneutral.net@ |
23 | 1 | Élie Bouttier | |
24 | 1 | Élie Bouttier | La base de données utilisée est postgresql. |
25 | 1 | Élie Bouttier | |
26 | 1 | Élie Bouttier | Django est lancé par @uwsgi@. |
27 | 1 | Élie Bouttier | La configuration de celui-ci se trouve dans le dossier @/etc/uwsgi/@. |
28 | 1 | Élie Bouttier | Les dossiers @apps-available@ et @apps-enabled@ ne sont pas utilisé. |
29 | 1 | Élie Bouttier | En effet, l’ajout du .service systemd uwsgi@.service permet de lancer de manière indépendante chaque instance. |
30 | 1 | Élie Bouttier | |
31 | 1 | Élie Bouttier | Voici une description du déploiement de la prod, le déploiement en dev étant analogue. |
32 | 1 | Élie Bouttier | |
33 | 1 | Élie Bouttier | Le dossier @/etc/uwsgi/djadhere/@ contient un lien symbolique vers la configuration uwsgi de cette instance. |
34 | 1 | Élie Bouttier | Le lien est nommé @prod@ permettant d’utiliser systemd ainsi : |
35 | 1 | Élie Bouttier | |
36 | 1 | Élie Bouttier | @systemctl {start,stop,restart,status} uwsgi@djadhere-prod@ |
37 | 1 | Élie Bouttier | |
38 | 1 | Élie Bouttier | Un utilisateur @djadhere-prod@ a été créé (et automatiquement un groupe du même nom). |
39 | 1 | Élie Bouttier | L’utilisateur @www-data@ a été rajouté au groupe @djadhere-prod@. |
40 | 1 | Élie Bouttier | L’umask de @djadhere-prod@ est définie à 077 dans son @.bashrc@. |
41 | 1 | Élie Bouttier | |
42 | 1 | Élie Bouttier | Le home de djadhere-prod se trouve dans le dossier @/srv/djadhere/prod@ et contient : |
43 | 1 | Élie Bouttier | |
44 | 1 | Élie Bouttier | * @uwsgi.ini@ : la conf uwsgi symlinké depuis @/etc/uwsgi/djadhere/prod@ |
45 | 1 | Élie Bouttier | * @uwsgi.socket@ : le socket unix référencé dans la conf de nginx |
46 | 1 | Élie Bouttier | * @touch-to-reload@ : un fichier permettant de relancer uwsgi via la commande touch : @touch touch-to-reload@ |
47 | 1 | Élie Bouttier | * @app@ : un clone du projet Git |
48 | 1 | Élie Bouttier | * @log@ : les logs (nginx + uwsgi + django) |
49 | 1 | Élie Bouttier | * @venv@ : le virtualenv dans lequel tourne django |
50 | 1 | Élie Bouttier | * @webdir@ : le dossier servie par nginx (g+rX) qui contient un dossier static et un dossier media (géré par django) |
51 | 1 | Élie Bouttier | * @update.sh@ : un script pour mettre à jour |
52 | 1 | Élie Bouttier | |
53 | 1 | Élie Bouttier | Voici la conf uwsgi.ini : |
54 | 1 | Élie Bouttier | |
55 | 1 | Élie Bouttier | <pre> |
56 | 1 | Élie Bouttier | [uwsgi] |
57 | 1 | Élie Bouttier | |
58 | 1 | Élie Bouttier | uid = djadhere-prod |
59 | 1 | Élie Bouttier | gid = djadhere-prod |
60 | 1 | Élie Bouttier | |
61 | 1 | Élie Bouttier | chdir = /srv/djadhere/prod/app |
62 | 1 | Élie Bouttier | |
63 | 1 | Élie Bouttier | plugin=python3 |
64 | 1 | Élie Bouttier | module=djadhere.wsgi:application |
65 | 1 | Élie Bouttier | virtualenv = /srv/djadhere/prod/venv |
66 | 1 | Élie Bouttier | env=DJANGO_SETTINGS_MODULE=djadhere.local_settings |
67 | 1 | Élie Bouttier | |
68 | 1 | Élie Bouttier | uwsgi-socket=/srv/djadhere/prod/uwsgi.socket |
69 | 1 | Élie Bouttier | chmod-socket=660 |
70 | 1 | Élie Bouttier | |
71 | 1 | Élie Bouttier | pidfile=/srv/djadhere/prod/uwsgi.pid |
72 | 1 | Élie Bouttier | touch-reload = /srv/djadhere/prod/touch-to-reload |
73 | 1 | Élie Bouttier | |
74 | 1 | Élie Bouttier | logto=/srv/djadhere/prod/log/uwsgi.log |
75 | 1 | Élie Bouttier | logfile-chmod=400 |
76 | 1 | Élie Bouttier | logfile-chown=djadhere-prod:djadhere-prod |
77 | 1 | Élie Bouttier | |
78 | 1 | Élie Bouttier | vacuum=True |
79 | 1 | Élie Bouttier | </pre> |
80 | 1 | Élie Bouttier | |
81 | 1 | Élie Bouttier | Voici une partie de la configuration local de django (situé dans @app/djadhere/local_settings.py@) : |
82 | 1 | Élie Bouttier | |
83 | 1 | Élie Bouttier | <pre> |
84 | 1 | Élie Bouttier | from djadhere.settings import * |
85 | 1 | Élie Bouttier | |
86 | 1 | Élie Bouttier | from os.path import join |
87 | 1 | Élie Bouttier | |
88 | 1 | Élie Bouttier | |
89 | 1 | Élie Bouttier | BASE_DIR = '/srv/djadhere/prod/' |
90 | 1 | Élie Bouttier | |
91 | 1 | Élie Bouttier | SECRET_KEY = 'removed' |
92 | 1 | Élie Bouttier | |
93 | 1 | Élie Bouttier | DATABASES = { |
94 | 1 | Élie Bouttier | 'default': { |
95 | 1 | Élie Bouttier | 'ENGINE': 'django.db.backends.postgresql_psycopg2', |
96 | 1 | Élie Bouttier | 'NAME': 'djadhere_prod', |
97 | 1 | Élie Bouttier | 'USER': 'djadhere_prod', |
98 | 1 | Élie Bouttier | 'PASSWORD': 'removed', |
99 | 1 | Élie Bouttier | 'HOST': 'localhost', |
100 | 1 | Élie Bouttier | 'PORT': '', |
101 | 1 | Élie Bouttier | }, |
102 | 1 | Élie Bouttier | } |
103 | 1 | Élie Bouttier | |
104 | 1 | Élie Bouttier | DEBUG = False |
105 | 1 | Élie Bouttier | |
106 | 1 | Élie Bouttier | LOGGING = { |
107 | 1 | Élie Bouttier | 'version': 1, |
108 | 1 | Élie Bouttier | 'disable_existing_loggers': False, |
109 | 1 | Élie Bouttier | 'handlers': { |
110 | 1 | Élie Bouttier | 'file': { |
111 | 1 | Élie Bouttier | 'level': 'WARNING', |
112 | 1 | Élie Bouttier | 'class': 'logging.FileHandler', |
113 | 1 | Élie Bouttier | 'filename': join(BASE_DIR, 'log/debug.log'), |
114 | 1 | Élie Bouttier | }, |
115 | 1 | Élie Bouttier | 'mail_admins': { |
116 | 1 | Élie Bouttier | 'class': 'django.utils.log.AdminEmailHandler', |
117 | 1 | Élie Bouttier | 'level': 'ERROR', |
118 | 1 | Élie Bouttier | # But the emails are plain text by default - HTML is nicer |
119 | 1 | Élie Bouttier | 'include_html': True, |
120 | 1 | Élie Bouttier | }, |
121 | 1 | Élie Bouttier | }, |
122 | 1 | Élie Bouttier | 'loggers': { |
123 | 1 | Élie Bouttier | 'django.request': { |
124 | 1 | Élie Bouttier | 'handlers': ['file', 'mail_admins'], |
125 | 1 | Élie Bouttier | 'level': 'WARNING', |
126 | 1 | Élie Bouttier | 'propagate': True, |
127 | 1 | Élie Bouttier | }, |
128 | 1 | Élie Bouttier | }, |
129 | 1 | Élie Bouttier | } |
130 | 1 | Élie Bouttier | |
131 | 1 | Élie Bouttier | STATIC_ROOT = join(BASE_DIR, 'webdir/static') |
132 | 1 | Élie Bouttier | STATIC_URL = '/static/' |
133 | 1 | Élie Bouttier | |
134 | 1 | Élie Bouttier | MEDIA_ROOT = join(BASE_DIR, 'webdir/media') |
135 | 1 | Élie Bouttier | MEDIA_URL = '/media/' |
136 | 1 | Élie Bouttier | |
137 | 1 | Élie Bouttier | ALLOWED_HOSTS = [ 'adherents.tetaneutral.net' ] |
138 | 1 | Élie Bouttier | |
139 | 1 | Élie Bouttier | DEFAULT_FROM_EMAIL = 'noreply@tetaneutral.net' |
140 | 1 | Élie Bouttier | SERVER_EMAIL = 'djadhere <projet-web-at-lists.tetaneutral.net>' |
141 | 1 | Élie Bouttier | EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' |
142 | 1 | Élie Bouttier | EMAIL_HOST = 'smtp' |
143 | 1 | Élie Bouttier | EMAIL_SUBJECT_PREFIX = "[PROD] " |
144 | 1 | Élie Bouttier | |
145 | 1 | Élie Bouttier | ADMINS = ( |
146 | 1 | Élie Bouttier | ('Prénom Nom', 'adresse mail'), |
147 | 1 | Élie Bouttier | ) |
148 | 1 | Élie Bouttier | </pre> |
149 | 1 | Élie Bouttier | |
150 | 1 | Élie Bouttier | Et le script d’easy update : |
151 | 1 | Élie Bouttier | |
152 | 1 | Élie Bouttier | <pre> |
153 | 1 | Élie Bouttier | #!/bin/bash |
154 | 1 | Élie Bouttier | |
155 | 1 | Élie Bouttier | cd ~/app |
156 | 1 | Élie Bouttier | git fetch |
157 | 1 | Élie Bouttier | git checkout master |
158 | 1 | Élie Bouttier | pip install --upgrade -r requirements.txt |
159 | 1 | Élie Bouttier | ./manage.py migrate |
160 | 1 | Élie Bouttier | echo yes | ./manage.py collectstatic |
161 | 1 | Élie Bouttier | |
162 | 1 | Élie Bouttier | cd ~ |
163 | 1 | Élie Bouttier | chmod g+rX webdir -R |
164 | 1 | Élie Bouttier | touch touch-to-reload |
165 | 1 | Élie Bouttier | </pre> |