Skip to content

Instantly share code, notes, and snippets.

@matheussl
Last active December 23, 2015 23:19
Show Gist options
  • Save matheussl/6709417 to your computer and use it in GitHub Desktop.
Save matheussl/6709417 to your computer and use it in GitHub Desktop.
Customizando o django-fab-deploy pra funcionar com Nginx + Gunicorn + Supervisor + Celery + Redis + Rabbitmq + Mysql
[program:{{ INSTANCE_NAME }}-celery]
command={{ ENV_DIR }}/bin/python {{ PROJECT_DIR }}/manage.py celeryd worker --concurrency=5 --loglevel=info -n {{ SERVER_NAME }}
stdout_logfile={{ ENV_DIR }}/logs/celeryd.log
stderr_logfile={{ ENV_DIR }}/logs/celeryd-error.log
user=popcode
autostart=true
autorestart=true
startsecs=10
stopwaitsecs=600
import os
import sys
import site
# prevent errors with 'print' commands
sys.stdout = sys.stderr
# Activate virtualenv
activate_this = os.path.expanduser("{{ ENV_DIR }}/bin/activate_this.py")
execfile(activate_this, dict(__file__=activate_this))
# adopted from http://code.google.com/p/modwsgi/wiki/VirtualEnvironments
def add_to_path(dirs):
# Remember original sys.path.
prev_sys_path = list(sys.path)
# Add each new site-packages directory.
for directory in dirs:
site.addsitedir(directory)
# Reorder sys.path so new directories at the front.
new_sys_path = []
for item in list(sys.path):
if item not in prev_sys_path:
new_sys_path.append(item)
sys.path.remove(item)
sys.path[:0] = new_sys_path
add_to_path([
os.path.normpath('{{ ENV_DIR }}/lib/python2.5/site-packages'),
os.path.normpath('{{ ENV_DIR }}/lib/python2.6/site-packages'),
os.path.normpath('{{ ENV_DIR }}/lib/python2.7/site-packages'),
os.path.normpath('{{ PROJECT_DIR }}'),
])
os.environ['DJANGO_SETTINGS_MODULE'] = 'src.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
from fab_deploy import *
from fabric.api import run
from fab_deploy.utils import run_as_sudo
from fab_deploy.utils import upload_config_template
import fab_deploy.deploy
import httplib2
DEFAULT_SERVER_ADMIN = '[email protected]'
# Settings.
STANDARD_SETTINGS = {
'VCS': 'git',
'SERVER_ADMIN': DEFAULT_SERVER_ADMIN,
'USER': 'my_user',
'SUDO_USER': 'my_sudo_user',
'INSTANCE_NAME': 'my_project',
'DB_NAME': 'my_project',
'DB_USER': 'my_user',
'DB_PASSWORD': 'password',
'DB_ROOT_PASSWORD': 'password',
'CONFIG_TEMPLATES_PATHS': ['path/to/config_templates'],
'REMOTE_CONFIG_TEMPLATE': 'path/to/settings/settings_local.server.py', # relative
'LOCAL_CONFIG': 'path/to/settings/settings_local.py',
'PIP_REQUIREMENTS_PATH': 'path/to/reqs/',
'PIP_REQUIREMENTS': 'deploy.txt',
'OS': 'lucid',
'GUNICORN_PORT': '8003',
'GIT_BRANCH': 'master',
}
# Host definitions.
@define_host('[email protected]')
def production():
"""Production server."""
return STANDARD_SETTINGS
@define_host('[email protected]')
def production():
"""Beta server."""
return STANDARD_SETTINGS
# Commands & utilities.
@run_as_sudo
def aptitude_update():
run('DEBIAN_FRONTEND=noninteractive sudo aptitude update')
def mysql_drop_db():
"""WARNING: drops the entire database."""
mysql_execute('DROP database pck')
def profile_template():
"""Installs profile (shell) template."""
upload_config_template('profile', '~/.profile', use_sudo=False)
@inside_project
def compilemessages():
"""compile django translations."""
django_commands.manage('compilemessages')
@run_as_sudo
def install_gettext():
"""intall gettext."""
run("sudo apt-get install gettext")
@run_as_sudo
def install_pil_dependences():
"""intall gettext."""
with settings(warn_only=True):
run("sudo apt-get build-dep python-imaging")
run("""
sudo ln -s /usr/lib/`uname -i`-linux-gnu/libfreetype.so /usr/lib/;
sudo ln -s /usr/lib/`uname -i`-linux-gnu/libjpeg.so /usr/lib/;
sudo ln -s /usr/lib/`uname -i`-linux-gnu/libz.so /usr/lib/;
""")
@run_as_sudo
def supervisor_install():
with settings(warn_only=True):
sudo('DEBIAN_FRONTEND=noninteractive apt-get install supervisor')
sudo('service supervisor start')
pass
# Web Server
@run_as_sudo
def gunicorn_setup():
""" Updates nginx config and restarts nginx. """
name = env.conf['INSTANCE_NAME']
run('mkdir -p %s/logs' % env.conf['ENV_DIR'])
utils.upload_config_template('gunicorn.config',
'/etc/supervisor/conf.d/%s_gunicorn.conf' % name,
use_sudo=True)
with settings(warn_only=True):
sudo('supervisorctl stop %s-gunicorn' %name)
sudo('supervisorctl remove %s-gunicorn' %name)
sudo('supervisorctl reread')
sudo('supervisorctl add %s-gunicorn' % name)
sudo('supervisorctl start %s-gunicorn' %name)
@run_as_sudo
def gunicorn_restart():
with settings(warn_only=True):
sudo('supervisorctl restart %s-gunicorn' % env.conf['INSTANCE_NAME'])
@run_as_sudo
def gunicorn_stop():
with settings(warn_only=True):
sudo('supervisorctl stop %s-gunicorn' % env.conf['INSTANCE_NAME'])
@run_as_sudo
def gunicorn_start():
with settings(warn_only=True):
sudo('supervisorctl start %s-gunicorn' % env.conf['INSTANCE_NAME'])
@utils.run_as_sudo
def nginx_setup():
""" Updates nginx config and restarts nginx. """
name = env.conf['INSTANCE_NAME']
utils.upload_config_template('nginx.config',
'/etc/nginx/sites-available/%s' % name,
use_sudo=True)
with settings(warn_only=True):
sudo('ln -s /etc/nginx/sites-available/%s /etc/nginx/sites-enabled/%s' % (name, name))
sudo('invoke-rc.d nginx restart')
@run_as_sudo
def setup_web_server():
""" Sets up a web server (gunicorn + nginx). """
nginx.nginx_install()
supervisor_install()
gunicorn_setup()
nginx_setup()
# Celery
@run_as_sudo
def rabbitmq_install():
with settings(warn_only=True):
sudo('apt-get install rabbitmq-server')
sudo('rabbitmqctl start')
@run_as_sudo
def redis_install():
with settings(warn_only=True):
sudo('apt-get install redis-server')
sudo('/etc/init.d/redis-server start')
@run_as_sudo
def celery_setup():
""" Updates nginx config and restarts nginx. """
name = env.conf['INSTANCE_NAME']
utils.upload_config_template('celery.config',
'/etc/supervisor/conf.d/%s.conf' % name,
use_sudo=True)
sudo('supervisorctl reread')
with settings(warn_only=True):
sudo('supervisorctl stop %s-celery' %name)
sudo('supervisorctl remove %s-celery' %name)
sudo('supervisorctl reread')
sudo('supervisorctl add %s-celery' % name)
sudo('supervisorctl start %s-celery' %name)
@run_as_sudo
def celery_restart():
with settings(warn_only=True):
sudo('supervisorctl restart %s-celery' % env.conf['INSTANCE_NAME'])
@run_as_sudo
def celery_start():
with settings(warn_only=True):
sudo('supervisorctl start %s-celery' % env.conf['INSTANCE_NAME'])
@run_as_sudo
def celery_stop():
with settings(warn_only=True):
sudo('supervisorctl stop %s-celery' % env.conf['INSTANCE_NAME'])
# Full deploy.
@run_as_sudo
def full_deploy():
"""Full, complete deploy."""
os = utils.detect_os()
if not console.confirm("Is the OS detected correctly (%s)?" % os, default=False):
abort("Detection fails. Please set env.conf.OS to correct value.")
system.prepare_server()
install_pil_dependences()
mysql_install()
mysql_create_db()
mysql_create_user()
mysql_grant_permissions()
install_gettext()
deploy()
# Deploy.
@run_as_sudo
def deploy():
"""Deploy project and restart apache."""
redis_install()
celery_stop()
gunicorn_stop()
with settings(warn_only=True):
virtualenv.virtualenv_create()
gunicorn_start()
make_clone()
virtualenv.pip_install(env.conf.PIP_REQUIREMENTS, restart=False)
update_django_config()
syncdb()
migrate()
collectstatic()
compilemessages()
setup_web_server()
celery_setup()
gunicorn_restart()
celery_start()
[program:{{ INSTANCE_NAME }}-gunicorn]
command={{ ENV_DIR }}/bin/python {{ PROJECT_DIR }}/manage.py run_gunicorn 127.0.0.1:{{ GUNICORN_PORT }} --access-logfile={{ ENV_DIR }}/logs/gunicorn-access.log --log-level=debug
stdout_logfile={{ ENV_DIR }}/logs/gunicorn.log
stderr_logfile={{ ENV_DIR }}/logs/gunicorn-error.log
user=popcode
autostart=true
autorestart=true
startsecs=10
stopwaitsecs=600
server {
listen 80;
server_name {{ SERVER_NAME }};
access_log /var/log/nginx/{{ INSTANCE_NAME }}.access.log;
charset utf-8;
client_max_body_size 8m;
gzip_types text/plain text/xml text/css application/javascript application/x-javascript application/json;
location / {
proxy_pass http://127.0.0.1:{{ GUNICORN_PORT }};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# change /static to your static folder name
location /static/ {
root {{ PROJECT_DIR }}/;
autoindex off;
expires 1M;
}
# change /static to your static folder name
location /media/ {
root {{PROJECT_DIR}}/;
autoindex off;
expires 1M;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root {{ PROJECT_DIR }}/static/;
}
}
server {
listen 80;
server_name www.{{ SERVER_NAME }};
rewrite ^(.*)$ http://{{ SERVER_NAME }}$1 permanent;
}
{% for SECONDARY_SERVER_NAME in SECONDARY_SERVER_NAMES %}
server {
listen 80;
server_name www.{{ SECONDARY_SERVER_NAME }};
rewrite ^(.*)$ http://{{ SECONDARY_SERVER_NAME }}$1 permanent;
}
server {
listen 80;
server_name {{ SECONDARY_SERVER_NAME }};
location / {
proxy_pass http://{{ SERVER_NAME }};
proxy_set_header X-Real-IP $remote_addr;
}
}
{% endfor %}
# uncomment the following in order to deny all requests with unmatched server_name;
# for nginx >= 0.8.21 replace 'default' with 'default_server'
# server {
# listen 80 default;
# server_name _;
# return 444;
# }
gunicorn==18.0
django-fab-deploy==0.7.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment