阿小信大人的头像
Life is short (You need Python) Bruce Eckel

在OpenShift上部署Django项目2014-09-02 04:44

在OpenShift上部署Django项目

帮助文档:

https://openshift.redhat.com/community/developers/python

https://github.com/openshift/django-example

0.安装所需环境:

ashin@linux:~$ sudo apt-get install ruby-full rubygems git-core

各操作系统的安装方法:https://openshift.redhat.com/community/developers/install-the-client-tools

1.安装openshift客户端:

ashin@linux:~$ sudo gem install rhc

安装时会提示:If this is your first time installing the RHC tools, please run 'rhc setup'

2.配置openshift客户端rhc:

2.1:先到openshift注册一个帐号

注册地址:https://openshift.redhat.com/app/account/new

注册完就行了,可以用web端建应用,也可以用命令行

2.2:配置本地客户端

ashin@linux:~$ rhc setup

输入注册的帐号和密码进行登录,跟着提示走。

在~/.openshift/express.conf中有定义默认的登录邮箱

3.创建domain:

最后应用地址为http://APPNAME_NAME-DOMAIN_NAME.rhcloud.com

ashin@linux:~$ rhc domain create -n DOMAIN_NAME -l REG_EMAIL

4.创建app:

ashin@linux:~$ rhc app create APP_NAME python-2.6

创建之后在工作目录下应该就有个APP_NAME的文件夹

在web上创建后应用有个ssh的git地址,可以使用git clone在本地创建应用目录。

5.将已有的django项目复制到app的wsgi目录下:

ashin@linux:~$ cp -R MY_APP APP_NAME/wsgi/

或者直接从github上将代码传到openshift上:

cd APP_NAME
git remote add upstream -m master YOUR_GIT_ADDRESS
git pull -s recursive -X theirs upstream master
git push

6.修改wsgi目录下的application文件:

#!/usr/bin/env python

import os
import sys

os.environ['DJANGO_SETTINGS_MODULE'] = 'DJANGO_PROJ_NAME.settings'
sys.path.append(os.path.join(os.environ['OPENSHIFT_REPO_DIR'], 'wsgi', 'DJANGO_PROJ_NAME'))
virtenv = os.environ['APPDIR'] + '/virtenv/'
os.environ['PYTHON_EGG_CACHE'] = os.path.join(virtenv, 'lib/python2.6/site-packages')
virtualenv = os.path.join(virtenv, 'bin/activate_this.py')
try:
    execfile(virtualenv, dict(__file__=virtualenv))
except:
    pass

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

7.修改app下的setup.py:

把变量值改成你自己的,然后将install_requires那行的注释取消,django的版本设置为自己项目的版本。我用的是django1.3

from setuptools import setup

setup(name='geek',
      version='1.0',
      description='CUIT Geek Challenge',
      author='ashin',
      author_email='254606826@qq.com',
      url='http://ashin.sinaapp.com',
      install_requires=['Django==1.3'],
     )

8.在wsgi下的django项目目录下新建openshiftlibs.py文件(与settings.py同级):

#!/usr/bin/env python
import hashlib, inspect, os, random, sys

# Gets the secret token provided by OpenShift
# or generates one (this is slightly less secure, but good enough for now)
def get_openshift_secret_token():
    token = os.getenv('OPENSHIFT_SECRET_TOKEN')
    name  = os.getenv('OPENSHIFT_APP_NAME')
    uuid  = os.getenv('OPENSHIFT_APP_UUID')
    if token is not None:
        return token
    elif (name is not None and uuid is not None):
        return hashlib.sha256(name + '-' + uuid).hexdigest()
    return None

# Loop through all provided variables and generate secure versions
# If not running on OpenShift, returns defaults and logs an error message
#
# This function calls secure_function and passes an array of:
#  {
#    'hash':     generated sha hash,
#    'variable': name of variable,
#    'original': original value
#  }
def openshift_secure(default_keys, secure_function = 'make_secure_key'):
    # Attempts to get secret token
    my_token = get_openshift_secret_token()

    # Only generate random values if on OpenShift
    my_list  = default_keys

    if my_token is not None:
        # Loop over each default_key and set the new value
        for key, value in default_keys.iteritems():
            # Create hash out of token and this key's name
            sha = hashlib.sha256(my_token + '-' + key).hexdigest()
            # Pass a dictionary so we can add stuff without breaking existing calls
            vals = { 'hash': sha, 'variable': key, 'original': value }
            # Call user specified function or just return hash
            my_list[key] = sha
            if secure_function is not None:
                # Pick through the global and local scopes to find the function.
                possibles = globals().copy()
                possibles.update(locals())
                supplied_function = possibles.get(secure_function)
                if not supplied_function:
                    raise Exception("Cannot find supplied security function")
                else:
                    my_list[key] = supplied_function(vals)
    else:
        calling_file = inspect.stack()[1][1]
        if os.getenv('OPENSHIFT_REPO_DIR'):
            base = os.getenv('OPENSHIFT_REPO_DIR')
            calling_file.replace(base,'')
        sys.stderr.write("OPENSHIFT WARNING: Using default values for secure variables, please manually modify in " + calling_file + "\n")

    return my_list


# This function transforms default keys into per-deployment random keys;
def make_secure_key(key_info):
    hashcode = key_info['hash']
    key      = key_info['variable']
    original = key_info['original']

    # These are the legal password characters
    # as per the Django source code
    # (django/contrib/auth/models.py)
    chars  = 'abcdefghjkmnpqrstuvwxyz'
    chars += 'ABCDEFGHJKLMNPQRSTUVWXYZ'
    chars += '23456789'

    # Use the hash to seed the RNG
    random.seed(int("0x" + hashcode[:8], 0))

    # Create a random string the same length as the default
    rand_key = ''
    for _ in range(len(original)):
        rand_pos = random.randint(0,len(chars))
        rand_key += chars[rand_pos:(rand_pos+1)]

    # Reset the RNG
    random.seed()

    # Set the value
    return rand_key

9.修改django项目的settings.py:

# -*- coding:utf-8 -*-
import os, imp

ON_OPENSHIFT = False
if os.environ.has_key('OPENSHIFT_REPO_DIR'):
    ON_OPENSHIFT = True

PROJECT_DIR = os.path.dirname(os.path.realpath(__file__))

DEBUG = False
TEMPLATE_DEBUG = DEBUG

ADMINS = (
    ('ashin', '254606826@qq.com'),
)

MANAGERS = ADMINS

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',  # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': os.path.join(PROJECT_DIR, 'dbfile'),  # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# On Unix systems, a value of None will cause Django to use the same
# timezone as the operating system.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'Asia/Shanghai'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'zh_CN'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale
USE_L10N = True

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = os.path.join(PROJECT_DIR, 'geekchallenge', 'static', 'uploads', '')


# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = ''

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = os.path.join(PROJECT_DIR, 'geekchallenge', 'static', '')

# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'

# URL prefix for admin static files -- CSS, JavaScript and images.
# Make sure to use a trailing slash.
# Examples: "http://foo.com/static/admin/", "/static/admin/".
ADMIN_MEDIA_PREFIX = '/static/admin/'

# Additional locations of static files
STATICFILES_DIRS = (
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

# Make this unique, and don't share it with anybody.
#SECRET_KEY = 'xsw0r3iqq=pq#w&iap%y%4e^a*b!ld8x(kn-cn*s1^+db-uw5('


default_keys = { 'SECRET_KEY':'xsw0r3iqq=pq#w&iap%y%4e^a*b!ld8x(kn-cn*s1^+db-uw5('}
use_keys = default_keys
if ON_OPENSHIFT:
    imp.find_module('openshiftlibs')
    import openshiftlibs
    use_keys = openshiftlibs.openshift_secure(default_keys)
SECRET_KEY = use_keys['SECRET_KEY']

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
#     'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
)

ROOT_URLCONF = 'geek.urls'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    os.path.join(PROJECT_DIR, 'geekchallenge', 'templates'),
)


INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'geek.geekchallenge',
    'django.contrib.flatpages',
    #'django_mongodb_engine',
    'geek.forum',
)

# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
    }
}

TEMPLATE_CONTEXT_PROCESSORS = (  
    "django.core.context_processors.auth",  
    "django.core.context_processors.debug",  
    "django.core.context_processors.i18n",  
    "django.core.context_processors.media",  
    "django.core.context_processors.request" 
)

EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_PASSWORD = 'password'
EMAIL_HOST_USER = 'geek@syclover.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True

10.将静态文件目录下所有文件copy到wsgi目录下的static文件夹中。

11.进入app目录,用git上传代码:

git add .
git commit -m 'test'
git push

ok,基本流程就是这样。访问应用地址就能看到效果了,上传文件还有点问题,后面再解决,感觉比SAE好。

我的测试项目地址:http://geek-syclover.rhcloud.com/

如果您觉得从我的分享中得到了帮助,并且希望我的博客持续发展下去,请点击支付宝捐赠,谢谢!

若非特别声明,文章均为阿小信的个人笔记,转载请注明出处。文章如有侵权内容,请联系我,我会及时删除。

#Python#   #django
分享到:
阅读[2834] 评论[0]

你可能也感兴趣的文章推荐

本文最近访客

发表评论