Setup a production-like environment in vagrant
- We already use Daphne and channels to prepare the future use of websockets. - The app is served behind an nginx reverse-proxy - The services we need are managed by systemctl The production-like running instance of GestionÉvénementiel can be accessed on localhost:8080 outside vagrant.
This commit is contained in:
parent
981c5cade5
commit
e64c3d0b37
8 changed files with 193 additions and 43 deletions
7
evenementiel/asgi.py
Normal file
7
evenementiel/asgi.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
import os
|
||||
from channels.asgi import get_channel_layer
|
||||
|
||||
if "DJANGO_SETTINGS_MODULE" not in os.environ:
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "evenementiel.settings")
|
||||
|
||||
channel_layer = get_channel_layer()
|
2
evenementiel/routing.py
Normal file
2
evenementiel/routing.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Nothing yet
|
||||
channel_routing = []
|
|
@ -43,6 +43,7 @@ INSTALLED_APPS = [
|
|||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'channels',
|
||||
'bootstrapform',
|
||||
'debug_toolbar',
|
||||
'widget_tweaks',
|
||||
|
@ -82,21 +83,19 @@ TEMPLATES = [
|
|||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'evenementiel.wsgi.application'
|
||||
CHANNEL_LAYERS = {
|
||||
"default": {
|
||||
"BACKEND": "asgi_redis.RedisChannelLayer",
|
||||
"CONFIG": {
|
||||
"hosts": [(
|
||||
"redis://:{passwd}@{host}:{port}/{db}"
|
||||
.format(passwd="dummy", host="localhost", port=6379, db=0)
|
||||
)],
|
||||
},
|
||||
"ROUTING": "evenementiel.routing.channel_routing",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
|
||||
|
||||
# # MySQL
|
||||
# DATABASES = {
|
||||
# 'default': {
|
||||
# 'ENGINE': 'django.db.backends.sqlite3',
|
||||
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
# }
|
||||
# }
|
||||
|
||||
# PostGreSQL
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql',
|
||||
|
@ -108,6 +107,9 @@ DATABASES = {
|
|||
}
|
||||
}
|
||||
|
||||
STATIC_ROOT = "/srv/GE/static/"
|
||||
MEDIA_ROOT = "/srv/GE/media/"
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
|
||||
|
|
|
@ -1,25 +1,102 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
# Configuration de la base de données. Le mot de passe est constant car c'est
|
||||
# pour une installation de dév locale qui ne sera accessible que depuis la
|
||||
# machine virtuelle.
|
||||
# The credentials of the database. Can be public since they will only be used in
|
||||
# the local development environment
|
||||
DBUSER="event_gestion"
|
||||
DBNAME="event_gestion"
|
||||
DBPASSWD="4KZt3nGPLVeWSvtBZPsd9jdssdJMds78"
|
||||
|
||||
# Installation de paquets utiles
|
||||
# Not critical either
|
||||
REDIS_PASSWD="dummy"
|
||||
|
||||
# It is used in quite a few places
|
||||
SETTINGS="evenementiel.settings_dev"
|
||||
|
||||
# ---
|
||||
# Installs the dependencies
|
||||
# ---
|
||||
|
||||
# System packages
|
||||
apt-get update && apt-get upgrade
|
||||
apt-get install -y python3-pip python3-dev python3-venv libpq-dev postgresql \
|
||||
postgresql-contrib libjpeg-dev
|
||||
postgresql-contrib libjpeg-dev nginx redis-server
|
||||
|
||||
# Setup Database and User
|
||||
# Python packages, in a virtual environment
|
||||
sudo -H -u vagrant python3 -m venv ~vagrant/venv
|
||||
sudo -H -u vagrant ~vagrant/venv/bin/pip install -U pip wheel
|
||||
sudo -H -u vagrant ~vagrant/venv/bin/pip install -U -r /vagrant/requirements-devel.txt
|
||||
|
||||
|
||||
# ---
|
||||
# Setup the production-like environment
|
||||
# ---
|
||||
|
||||
# Database and User
|
||||
sudo -u postgres createdb $DBNAME
|
||||
sudo -u postgres createuser -SDR $DBUSER
|
||||
sudo -u postgres psql -c "ALTER USER $DBUSER WITH PASSWORD '$DBPASSWD';"
|
||||
sudo -u postgres psql -c "ALTER USER $DBUSER CREATEDB;"
|
||||
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DBNAME TO $DBUSER;"
|
||||
|
||||
# Mise en place du .bash_profile pour tout configurer lors du `vagrant ssh`
|
||||
# The working directory for Daphne and cie
|
||||
mkdir -p /srv/GE/{media,static}
|
||||
chown -R vagrant:vagrant /srv/GE
|
||||
|
||||
# Nginx
|
||||
cp /vagrant/provisioning/nginx.conf /etc/nginx/sites-available/ge.conf
|
||||
if [ ! -h /etc/nginx/sites-enabled/ge.conf ]
|
||||
then
|
||||
# If the configuration file is not activated yet, activates it
|
||||
ln -s /etc/nginx/sites-available/ge.conf /etc/nginx/sites-enabled/ge.conf
|
||||
fi
|
||||
rm -f /etc/nginx/sites-enabled/default # We do not need this
|
||||
service nginx restart
|
||||
|
||||
# Daphne and the worker(s)
|
||||
for service in {daphne,worker}.service
|
||||
do
|
||||
cp /vagrant/provisioning/$service /etc/systemd/system/$service
|
||||
sed "s/{{DBUSER}}/$DBUSER/" -i /etc/systemd/system/$service
|
||||
sed "s/{{DBNAME}}/$DBNAME/" -i /etc/systemd/system/$service
|
||||
sed "s/{{DBPASSWD}}/$DBPASSWD/" -i /etc/systemd/system/$service
|
||||
sed "s/{{SETTINGS}}/$SETTINGS/" -i /etc/systemd/system/$service
|
||||
systemctl enable $service
|
||||
systemctl start $service
|
||||
done
|
||||
|
||||
# Redis
|
||||
redis-cli CONFIG SET requirepass $REDIS_PASSWD
|
||||
if [ ! $? ]
|
||||
then
|
||||
# In case the requirepass command failed, checks that it was because the
|
||||
# password was already set *to the right value*.
|
||||
redis-cli AUTH $REDIS_PASSWD
|
||||
fi
|
||||
redis-cli -a $REDIS_PASSWD CONFIG REWRITE
|
||||
|
||||
|
||||
# ---
|
||||
# Prepare Django
|
||||
# ---
|
||||
|
||||
function venv_python {
|
||||
sudo -H -u vagrant DJANGO_SETTINGS_MODULE=$SETTINGS \
|
||||
DBUSER=$DBUSER DBNAME=$DBNAME DBPASSWD=$DBPASSWD \
|
||||
~vagrant/venv/bin/python \
|
||||
$@
|
||||
}
|
||||
|
||||
cd /vagrant
|
||||
venv_python manage.py collectstatic --noinput
|
||||
venv_python manage.py migrate
|
||||
|
||||
unset venv_python
|
||||
|
||||
|
||||
# ---
|
||||
# Setup a friendly environment for the user
|
||||
# ---
|
||||
|
||||
cat >> ~vagrant/.bashrc <<EOF
|
||||
|
||||
# On utilise les settings de développement
|
||||
|
@ -37,24 +114,3 @@ cd /vagrant
|
|||
source ~vagrant/venv/bin/activate
|
||||
EOF
|
||||
chown vagrant: ~vagrant/.bashrc
|
||||
|
||||
# On va dans /vagrant où se trouve le code
|
||||
cd /vagrant
|
||||
|
||||
# Installation des dépendances python
|
||||
# Notes :
|
||||
# - Je ne comprends pas trop pourquoi j'ai besoin d'installer wheel, il devrait
|
||||
# venir avec pip il me semble… Mais sans ça, l'installation de
|
||||
# django-boostrap-form échoue.
|
||||
# - A priori upgrade pip via pip est inutile au moment où j'écris ce script mais
|
||||
# la version de pip de PyPi peut être mise à jour plus vite que celle des
|
||||
# paquets Debian et on préfère la version la plus récente (ça nous a déjà posé
|
||||
# des problèmes).
|
||||
sudo -H -u vagrant python3 -m venv ~vagrant/venv
|
||||
sudo -H -u vagrant ~vagrant/venv/bin/pip install -U pip wheel
|
||||
sudo -H -u vagrant ~vagrant/venv/bin/pip install -U -r requirements-devel.txt
|
||||
|
||||
# Préparation de Django
|
||||
sudo -H -u vagrant DJANGO_SETTINGS_MODULE='evenementiel.settings_dev' \
|
||||
DBUSER=$DBUSER DBNAME=$DBNAME DBPASSWD=$DBPASSWD \
|
||||
~vagrant/venv/bin/python manage.py migrate
|
||||
|
|
19
provisioning/daphne.service
Normal file
19
provisioning/daphne.service
Normal file
|
@ -0,0 +1,19 @@
|
|||
Description="Gestion Événementiel - Daphne"
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=vagrant
|
||||
Group=vagrant
|
||||
TimeoutSec=300
|
||||
WorkingDirectory=/vagrant
|
||||
Environment="DJANGO_SETTINGS_MODULE={{SETTINGS}}"
|
||||
Environment="DBNAME={{DBNAME}}"
|
||||
Environment="DBUSER={{DBUSER}}"
|
||||
Environment="DBPASSWD={{DBPASSWD}}"
|
||||
ExecStart=/home/vagrant/venv/bin/daphne -u /srv/GE/GE.sock \
|
||||
evenementiel.asgi:channel_layer
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
40
provisioning/nginx.conf
Normal file
40
provisioning/nginx.conf
Normal file
|
@ -0,0 +1,40 @@
|
|||
upstream GE {
|
||||
# Daphne listens on a unix socket
|
||||
server unix:/srv/GE/GE.sock;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
server_name localhost;
|
||||
|
||||
# All the trafic is routed to Daphne
|
||||
location ~ ^/ {
|
||||
# A copy-paste of what we have in production
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-SSL-Client-Serial $ssl_client_serial;
|
||||
proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
|
||||
proxy_set_header X-SSL-Client-S-DN $ssl_client_s_dn;
|
||||
# Reverse-proxy
|
||||
proxy_pass http://GE;
|
||||
}
|
||||
|
||||
# Static files
|
||||
location ~ ^/static/ {
|
||||
root /srv/GE/static/;
|
||||
access_log off;
|
||||
add_header Cache-Control "public";
|
||||
expires 7d;
|
||||
}
|
||||
|
||||
# Uploaded media
|
||||
location ~ ^/media/ {
|
||||
root /srv/GE/static/;
|
||||
access_log off;
|
||||
add_header Cache-Control "public";
|
||||
expires 7d;
|
||||
}
|
||||
}
|
19
provisioning/worker.service
Normal file
19
provisioning/worker.service
Normal file
|
@ -0,0 +1,19 @@
|
|||
[Unit]
|
||||
Description="Gestion Événementiel - Worker"
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=vagrant
|
||||
Group=vagrant
|
||||
TimeoutSec=300
|
||||
WorkingDirectory=/vagrant
|
||||
Environment="DJANGO_SETTINGS_MODULE={{SETTINGS}}"
|
||||
Environment="DBNAME={{DBNAME}}"
|
||||
Environment="DBUSER={{DBUSER}}"
|
||||
Environment="DBPASSWD={{DBPASSWD}}"
|
||||
ExecStart=/home/vagrant/venv/bin/python manage.py runworker
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -1,5 +1,10 @@
|
|||
Django==1.11.*
|
||||
psycopg2
|
||||
asgi-redis
|
||||
Pillow
|
||||
channels
|
||||
django-bootstrap-form==3.2.1
|
||||
django-widget-tweaks
|
||||
|
||||
# Production specific
|
||||
daphne
|
||||
|
|
Loading…
Reference in a new issue