Skip to content

Instantly share code, notes, and snippets.

@tsuyukimakoto
Forked from hirokiky/environments.json
Created August 21, 2012 03:12
Show Gist options
  • Save tsuyukimakoto/3411186 to your computer and use it in GitHub Desktop.
Save tsuyukimakoto/3411186 to your computer and use it in GitHub Desktop.
{
"secret_key":"$secret_key"
"akismet_api_key":"$akismet_api_key"
"db_default_user":$mysqluser
"db_default_password":$mysqlpassword
"db_default_host":"$host"
"db_default_port":"$port"
}
# -*- coding: utf-8 -*-
import os
import socket
import getpass
from string import Template
from fabric.api import local, run, sudo, cd, env, settings
from fabric.state import env
from fabric.contrib.files import sed, exists, append, contains, uncomment
from fabric.network import join_host_strings, normalize
from fabric.context_managers import settings
"""
Fab settings
"""
env.hosts = ['djangoproject.vir']
env.git_code_url = 'git://github.com/django-ja/djangoproject.jp.git'
env.git_docs_url = 'git://github.com/django-docs-ja/django-docs-ja.git'
env.mysqluser = env.user
env.mysqlpassword = 'enterpassword'
env.dbname = 'djangoprojectjp'
env.secret_key = 'entersecretkey'
env.akismet_api_key = 'enterakismetkey'
def change_ssh_port(after=22):
"""
For security changing the default ssh port.
"""
host = normalize(env.host_string)[1]
before = str(env.port)
host_string=join_host_strings(env.user,host,before)
with settings(host_string=host_string, user=env.user):
print("{0} CHANGING SSH PORT TO: {1}".format(env.host, str(after)))
sed('/etc/ssh/sshd_config','Port '+ str(before),'Port '+str(after),use_sudo=True)
sudo('/etc/init.d/ssh restart')
def upload_ssh_key(rollback=False):
"""
Upload your ssh key for passwordless logins
"""
auth_keys = '/home/{0}/.ssh/authorized_keys'.format(env.user)
if not rollback:
local_user = getpass.getuser()
host = socket.gethostname()
u = '@'.join([local_user,host])
u = 'ssh-key-uploaded-{0}'.format(u)
sudo('mkdir -p /home/{0}'.format(env.user))
# determine local .ssh dir
home = os.path.expanduser('~')
ssh_key = None
ssh_dsa = os.path.join(home,'.ssh/id_dsa.pub')
ssh_rsa = os.path.join(home,'.ssh/id_rsa.pub')
if os.path.exists(ssh_dsa):
ssh_key = ssh_dsa
elif os.path.exists(ssh_rsa):
ssh_key = ssh_rsa
if ssh_key:
with open(ssh_key, 'r') as f:
ssh_file = f.read()
print("{0} UPLOADING SSH KEY".format(env.host))
append(auth_keys,ssh_file, use_sudo=True)
def restrict_ssh():
"""
Restrict password login, and root login.
"""
sshd_config = '/etc/ssh/sshd_config'
if not exists('/home/{0}/.ssh/authorized_keys'.format(env.user)):
print('{0} You need to upload_ssh_key first.'.format(env.host))
return False
sed(sshd_config, 'PermitRootLogin yes', 'PermitRootLogin no', use_sudo=True)
uncomment(sshd_config,'#(\s?)PermitRootLogin(\s*)no',use_sudo=True)
sed(sshd_config, 'PermitEmptyPassword yes', 'PermitEmptyPassword no', use_sudo=True)
uncomment(sshd_config,'#(\s?)PermitEmptyPassword(\s*)no',use_sudo=True)
sed(sshd_config, 'PasswordAuthentication yes', 'PasswordAuthentication no', use_sudo=True)
uncomment(sshd_config,'#(\s?)PasswordAuthentication(\s*)no',use_sudo=True)
sudo('/etc/init.d/ssh restart')
def setup_ufw_rules(sshport):
"""
Setup ufw app rules.
"""
firewall_rules = ['default deny', 'allow 80/tcp', 'allow 443/tcp', 'allow {0}/tcp'.format(sshport)]
print('deleting all rules')
sudo('ufw reset')
print('enable ufw')
sudo('ufw enable')
for rule in firewall_rules:
with settings(warn_only=True):
print('ufw {0}'.format(rule))
sudo('ufw {0}'.format(rule))
output = sudo('ufw reload')
print(output)
def disable_services():
"""
For performance, disable unnecesaly daemon.
"""
disables = ['acpid', 'apmd', 'atd', 'dns-clean', 'pppd-dns']
for d in disables:
if exists('/etc/init.d/{0}'.format(d)):
sudo('update-rc.d {0} disable'.format(d))
def install_packages():
"""
Install a set of baseline packages and configure where necessary
"""
base_packages = ['nginx', 'mysql-server', 'python-setuptools', 'python-dev', 'libmysqlclient-dev', 'build-essential', 'git']
python_packages = ['virtualenv', 'pip']
sudo('apt-get update')
for p in base_packages:
sudo('apt-get install {0}'.format(p))
with cd('/tmp'):
for p in python_packages:
sudo('easy_install {0}'.format(p))
def deploy_code():
"""
Update code on the servers from Git.
"""
if not exists('~/djangoproject.jp/'):
with cd('~'):
print("cloning djangoproject.jp: {0}".format(env.git_code_url))
run('git clone {0}'.format(env.git_code_url))
with cd('/home/{0}/djangoproject.jp/'.format(env.user)):
run('git fetch && git reset --hard origin/master')
def update_virtualenv(env_name, packages, reqs=None):
"""
Update virtualenv for the project, and update depencies.
"""
if not exists('~/envs/{0}'.format(env_name)):
run('mkdir -p ~/envs')
with cd('~/envs'):
run('virtualenv {0}'.format(env_name))
with prefix('source ~/envs/{0}/bin/activate'.format(env_name)):
run('export PIP_RESPECT_VIRTUALENV=true')
for p in packages:
sudo('pip install "{0}"'.format(p))
if reqs:
sudo('pip install -r {0}'.format(reqs))
def deploy_doc(doc_version):
"""
Update docs on the servers from Git.
"""
with prefix('source ~/envs/djangoproject.jp/bin/activate'):
run('export PIP_RESPECT_VIRTUALENV=true')
# ドキュメントのバージョンに応じたvirtualenvを作成
if doc_version == "1.0":
update_virtualenv('1.0', ['Sphinx==0.4.3'])
else:
sudo('pip install Sphinx')
if not exists('~/doc/{0}/'.format(doc_version)):
run('mkdir -p ~/doc')
with cd('~/doc'):
run('git clone {0} {1}'.format(env.git_docs_url, doc_version))
with cd('~/doc/{0}'.format(doc_version)):
with prefix('source ~/envs/{0}/bin/activate'.format(doc_version)):
run('git fetch && git reset --hard {0}'.format(doc_version))
run('make html')
def setup_mysql():
"""
Setup mysql
"""
create_user_sql = """grant select,insert,delete,update,create,drop,file,alter,index on *.* to '{user}'@'localhost' identified by '{password}';""".format(user=env.mysqluser, password=env.mysqlpassword)
run('echo "{grant_sql}" | mysql --user=root --password'.format(grant_sql=create_user_sql))
run('mysqladmin -u {0} -p{1} create {2}'.format(env.mysqluser, env.mysqlpassword, env.dbname))
def setup_gunicorn():
"""
Setup gunicorn, and start daemon.
"""
run('source ~/envs/djangoproject.jp/bin/activate && python djangoproject.jp/manage.py run_gunicorn -w 1 -b 127.0.0.1:5000 -D && ps -aux | grep gunicorn')
run('ps -aux | grep gunicorn')
def setup_nginx():
"""
Setup nginx.
"""
# plain_defaultからdefaultを生成しアップロード
local('cp ./plain_default ./default')
local('sed -i -e "s/{{ username }}/{0}/g" ./default'.format(env.user))
put('./default', '/etc/nginx/sites-available/default', use_sudo=True)
sudo('nginx -t')
sudo('/etc/init.d/nginx reload')
def setup_environments():
"""
Update enviroments.json which to set secret informetions.
"""
tmpl_file = os.path.join(os.path.dirname(__file__),'environments.json')
real_file = os.path.join(os.path.dirname(__file__),'environments.json_mod')
with cd('~/djangoproject.jp'):
with open(tmpl_file, 'r') as f:
json = Template(f.read()).substitute(secret_key=$env.secret_key, akismet_api_key = env.akismet_api_key,
db_default_user=env.mysqluser, db_default_password=env.mysqlpassword,
db_default_host='localhost',db_default_port='3306')
with open(real_file, 'w') as f:
f.write(json)
put(real_file, '/home/{0}/djangoproject.jp/environments.json'.format(env.user))
local('rm -f {0}'.format(real_file))
def managepy(cmd):
"""
Helper: run a management command remotely.
"""
with prefix('source ~/envs/djangoproject.jp/bin/activate'):
with cd('~/djangoproject.jp'):
run('python manage.py {0}'.format(cmd))
def syncdb():
"""
Run syncdb.
"""
managepy('syncdb')
def base_deploy(sshport):
"""
Base deploy: secure login, firewall, disable unnecessaly searvicies.
"""
change_ssh_port(sshport)
upload_ssh_key()
restrict_ssh()
setup_ufw_rules(sshport)
disable_services()
sudo('reboot')
def full_deploy():
"""
Full deploy: new code, update dependencies, migrate, and restart services.
"""
install_packages()
deploy_code()
setup_environments()
update_virtualenv('djangoproject.jp', ['MySQL-python'], '~/djangoproject.jp/requirement.txt')
deploy_doc('1.0')
setup_mysql()
syncdb()
setup_gunicorn()
setup_nginx()
upstream djangoja-website {
server 127.0.0.1:5000;
}
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/localhost.access.log;
error_log /var/log/nginx/localhost.error.log debug;
location ^~ /doc/ja/1.0 {
alias /home/{{ username }}/doc/1.0/_build/html;
index index.html;
break;
}
location ^~ /m {
alias /home/{{ username }}/djangoproject.jp/media;
break;
}
location / {
if (!-f $request_filename){
proxy_pass http://djangoja-website;
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment