使用dotCloud在云端部署Django应用程序

dotCloud的目标是提供一系列不同的独立服务,作为构建模块,来构建应用程序。如果你需要一个数据库,可以直接从他们所支持的许多数据库中挑选一个。如果应用程序前端使用Django或Rails,而在后端使用Java,也是可以的。大多数开发人员不会在开发所有应用中使用同一个技术栈,所以这可以让你灵活地使用最好的工具来完成这项工作。dotCloud还提供了很好的测试环境,可以尝试新的服务,看看它们如何运行,而无需安装、配置和维护仅仅用于测试的服务。

我将详细介绍将我的博客安装到dotCloud上的步骤,希望能够回答一些常见的问题。

文档

在我开始使用任何新服务之前,我通常会做的第一件事就是查看文档。DotCloud有一个很好的文档列表以及一些关于如何开始的教程。这4个文档是我使用最多的。

http://docs.dotcloud.com/firststeps/platform-overview/

http://docs.dotcloud.com/tutorials/python/django/

http://docs.dotcloud.com/services/mysql/

http://docs.dotcloud.com/services/mysql-masterslave/

第一步:

像现在所有很酷的服务一样,dotCloud使用基于python的CLI(命令行界面),所以在我们开始之前,我们需要安装dotCloud客户端并进行配置,以便我们可以开始使用它。

#创建我的dotcloud虚拟环境。
$ mkvirtualenv dotcloud

#使用pip安装dotcloud客户端
$ pip install dotcloud

#创建我们的博客应用程序
$ dotcloud create blog

# 当收到提示时,输入api密钥,密钥可从这里获得:http://www.dotcloud.com/account/settings
#<密钥写这里>

#如果你没有收到输入密钥的提示,可以运行这个命令,它会让你再次输入你的API密钥。
$ dotcloud register

现在我们已经完成了客​​户端设置,并创建了一个应用程序,现在我们可以开始构建我们的服务了。我已经在github上fork了我的博客仓库,以便我可以针对dotCloud进行修改,而不会影响我的原始仓库。

#进入项目目录
CD ~/projects

#fork kkecochranenet 到新分支 kencochranenet_dotcloud,然后克隆到本地
git clone git://github.com/kencochrane/kencochranenet_dotcloud.git kencochranenet_dotcloud

#进入新的目录。
cd kencochrane_dotcloud

根据文档,现在需要创建一个wsgi.py文件,并放在项目根目录下。使用http://docs.dotcloud.com/tutorials/python/django/#wsgi-py 作为模板,创建如下wsgi.py文件。在使用默认模板时有点小问题,需要添加一个路径到sys.path,以便wsgi可以正确地找到我的django应用程序。完成的文件如下:

import os
import sys

#与示例模板不同的是,作者加入了下面这些内容
sys.path.insert(0,os.path.abspath(os.path.join(os.path.dirname(__ file __),'mysite')))
os.environ ['DJANGO_SETTINGS_MODULE'] ='mysite.settings'

import django.core.handlers.wsgi
djangoapplication = django.core.handlers.wsgi.WSGIHandler()
def application(environ, start_response):
    if 'SCRIPT_NAME' in environ:
        del environ['SCRIPT_NAME']
    return djangoapplication(environ, start_response

DotCloud使用PIP requirements 依赖文件来管理项目依赖关系。现在已经有pip文件了,而且在正确的位置,命名也没有问题,所以我们不需要做任何事情,但是如果没有的话,需要创建一个并放在根目录下,命名为 requirements.txt

服务

当我们将服务添加到部署堆栈时,dotCloud会在我们的部署容器中提供一个名为“/home/dotcloud/environment.json”的文件,提供适当的连接信息。这使我们不必在settings.py文件中硬编码用户名/密码和服务器URL,而且也会更安全一些,因为无需在源码仓库中出现这些信息。

如何使用dotCloud提供的这个json文件呢?在settings.py文件的顶部,添加如下内容:

import json
with open('/home/dotcloud/environment.json') as f:
  env = json.load(f)

把上述代码添加到settings.py文件,就有了一个变量env,它具有我们需要的所有env环境设置。

你可以进一步添加一些自定义代码来检查environment.json文件是否存在。如果存在,说明正在生产环境中,所以使用json里的设置,如果不存在,说明在本地调试模式,可以本地设置。如果想更好一点,可以自己写一个类似于dotCloud提供的这种json文件,里面包含本地开发时的设置。如果程序找不到dotcloud提供的json,它可以查找和加载你的设置。这佯作的目的是,可以为生产环境和开发环境使用相同的设置文件,只需要在顶部添加一些代码即可加载正确的env文件。

数据库

大多数应用程序需要一个数据库,这个博客也一样。下面讲述如何设置数据库,以在dotcloud上使用博客。以MySQL数据库为例。使用Django框架,需要在settings.py中设置数据库。下面是在settings.py中设置mysql数据库连接的方法。请注意,数据库的名称没有在env文件中,而是需要自己设置。

DATABASES = {
    'default':{
        'ENGINE':'django.db.backends.mysql',
        'NAME':'blogdb',
        'USER':env ['DOTCLOUD_DB_MYSQL_LOGIN'],
        'PASSWORD':env ['DOTCLOUD_DB_MYSQL_PASSWORD'],
        'HOST':env ['DOTCLOUD_DB_MYSQL_HOST'],
        'PORT':int(env ['DOTCLOUD_DB_MYSQL_PORT']),
    }
}

创建数据库

dotCloud为您提供您自己的专用数据库,具有完全的root权限。权力巨大,责任重大。其中一个职责就是您需要创建自己的数据库模式和用户。一般需要通过如下命令,来完成:

#连接到dotcloud mysql服务器实例
$ dotcloud run blog.db -- mysql -u root -p

#mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 34
Server version: 5.1.41-3ubuntu12.10 (Ubuntu)

# 创建用户和数据库,并授予用户权限

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database blogdb;
Query OK, 1 row affected (0.00 sec)

mysql> create user 'blog_username' identified by 'strong_password';
Query OK, 0 rows affected (0.05 sec)

mysql> grant all on blogdb.* to 'blog_user'@'%';
Query OK, 0 rows affected (0.04 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> exit;Bye
Shared connection to database closed.

是不是很眼熟?写在这里,以便查阅。

如果想更加方便,可以创建一个小的python脚本,来检查是否成功创建了数据库,如果没有的话,会自动创建。这样在部署之前,不必登录到数据库手动完成。该文件命名为createdb.py,内容如下。这个脚本是针对mysql的。如果你想要一个postgreSQL数据库,你可以使用这个模板作为模板,然后修改它,以便在postgreSQL上运行。

import MySQLdb
import os
from wsgi import *

def create_dbs(names):
    print("create_dbs: let's go.")
    django_settings = __import__(os.environ['DJANGO_SETTINGS_MODULE'], fromlist='DATABASES')
    print("create_dbs: got settings.")
    databases = django_settings.DATABASES
    for name, db in databases.iteritems():
        if name in names and db['ENGINE'].endswith('mysql'):
            host = db['HOST']
            user = db['USER']
            password = db['PASSWORD']
            port = db['PORT']
            db_name = db['NAME']
            print 'creating database %s on %s' % (db_name, host)
            db = MySQLdb.connect(user=user,
                                passwd=password,
                                host=host,
                                port=port)
            cur = db.cursor()
            print("Check if database is already there.")
            cur.execute("""SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
                         WHERE SCHEMA_NAME = %s""", (db_name,))
            results = cur.fetchone()
            if not results:
                print("Database %s doesn't exist, lets create it." % db_name)
                sql = """CREATE DATABASE IF NOT EXISTS %s """ % (db_name,)
                print("> %s" % sql)
                cur.execute(sql)
                print(".....")
            else:
                print("database already exists, moving on to next step.")


if __name__ == '__main__':
    import sys
    print("create_dbs start")
    create_dbs(sys.argv[1:])
    print("create_dbs all done")

添加一个缓存

由于大部分博客内容变化不大,非常适合使用缓存。因此,我们将利用Django内置的缓存功能,在博客中添加一些缓存。通常我使用memcached进行缓存,但是dotCloud的memcached支持现在是有限的。之所以受到限制,是因为memcached没有任何内置的认证机制,为了确保它是安全的,你需要运行一个支持SASL的特殊版本的memcached,大多数的memcached客户端不支持这个。因此,dotCloud决定不完全支持memcached,而不是部署一个不安全的服务。有一些方法可以强行使用memcached,但它涉及到各种复杂的防火墙规则,并运行诸如stunnel之类的东西。虽然可以做到,但不是很好。

dotCloud建议使用redis来作为缓存,redis具有与memcached相同的缓存功能,还包括身份验证。所以我们将使用redis作为缓存。为了使用redis,我们需要添加redis库,因为redis缓存支持不是内置到Django中的。在您的requirements.txt文件中,您需要添加django-redis == 1.4.5,以便这些库可供Django使用。

一旦你安装了这个库,你将需要将这些设置添加到settings.py文件中,以便django知道使用哪个redis服务器和密码。

CACHES = {
    'default':{
        'BACKEND':'redis_cache.cache.RedisCache',
        'LOCATION':env ['DOTCLOUD_CACHE_REDIS_HOST'] +':'+ env ['DOTCLOUD_CACHE_REDIS_PORT'],
        'OPTIONS':{
            'DB':1,
            'PASSWORD':env ['DOTCLOUD_CACHE_REDIS_PASSWORD'],
            'PARSER_CLASS':'redis.connection.HiredisParser'
        },
    },
}

#我们也将使用redis作为会话缓存。
SESSION_ENGINE ='django.contrib.sessions.backends.cached_db'

有关使用redis作为Django缓存的更多信息,请查看这些链接。

  • https://github.com/niwibe/django-redis
  • http://pypi.python.org/pypi/django-redis/1.4.5
  • https://docs.djangoproject.com/en/1.3/topics/cache/
  • http://answers.dotcloud.com/question/213/redis-cache-settings-for-django

Django管理员

我们也需要一个简单的方法来为创建django管理员帐户。为了做到这一点,我有这个mkadmin.py脚本。下面的默认密码为“P@s$w0rd1 ”,一旦您安装了代码,您将需要登录到管理员帐户,并将密码更改为更安全的密码。

#!/usr/bin/env python
from wsgi import *
from django.contrib.auth.models import User
u, created = User.objects.get_or_create(username='admin')
if created:
    u.set_password('P@s$w0rd1')
    u.is_superuser = True
    u.is_staff = True
    u.save()

媒体

需要将我们的静态和媒体文件放在以下位置:

static = / home / dotcloud / data / static /

media = / home / dotcloud / data / media /。

因此,我们需要确保我们更改settings.py文件,并设置一个nginx.conf文件以映射到正确的位置。这里是settings.py文件的更改。

#媒体文件设置
MEDIA_ROOT ='/home/dotcloud/data/media/'
MEDIA_URL ='/media/'

#静态文件设置
STATIC_ROOT ='/home/dotcloud/data/static/'
STATIC_URL ='/static/'

#管理员前缀
ADMIN_MEDIA_PREFIX ='/static/admin/'

这是nginx.conf中的配置:

location /media/ {root/home/dotcloud/data; }
location /static/ {root/home/dotcloud/data; }

安装后

我们将创建一个postinstall脚本来处理在服务器上安装代码后需要做的所有任务。包含调用我们的createdb.py和mkadmin.py文件,以及同步我们的数据库,运行migration并运行collectstatic将所有静态文件移动到正确的位置。

#!/bin/sh
python createdb.py default
python mysite/manage.py syncdb --noinput
python mysite/manage.py migrate
python mkadmin.py
mkdir -p /home/dotcloud/data/media /home/dotcloud/data/static
python mysite/manage.py collectstatic --noinput

不要忘记,需要授权postinstall,createdb.py和mkadmin.py脚本是可执行的。

#使脚本可执行。
$ chmod + x postinstall createdb.py mkadmin.py

dotcloud.yml

现在我们已经将应用程序的项目结构全部设置好了,并且按照dotCloud的方式进行了配置,下面可以配置我们的部署堆栈。这是通过一个名为dotcloud.yml的文件完成的。有关dotcloud.yml文件的更多信息,请查看此链接:http://docs.dotcloud.com/guides/build-file/

www:
  type: python
db:
  type: mysql
cache:
  type: redis

这告诉我们需要3个服务,一个python www服务,一个mysql数据库服务和一个redis缓存服务。这是一个非常基本的设置,根据你想要实现的目的,可以变得更加复杂。

请注意,这不是针对高可用性设置的,因为没有任何实例被扩展。有关更多信息,请参阅下面的扩展部分。如果您正在dotCloud上运行生产环境中的应用,建议扩展所有服务,以便能够承受EC2服务器崩溃和其他不可预见的问题。

部署

现在我们准备部署Django应用程序,但是首先要注意,dotcloud会读取.gitignore文件,如果在.gitignore文件中,忽略了某个设置文件,这个设置文件就不会被保存到仓库,不会把更改推送到云端。需要将其从.gitignore中删除,以便将这些文件正常同步。只有提交的更改才会被push,所以不要忘记提交更改。如果想用更巧妙的方式,或者想更加安全的话,可以使用脚本从安全的位置下载文件,并以这种方式进行安装。

一切都准备好了,下面所要做的就是将应用上传到dotCloud。

#推出你的更改到服务器
$ dotcloud push blog

服务信息

一旦将代码推送到dotCloud,您可以通过运行info命令来查看它的信息。

#获取有关我们新服务的信息
$ dotcloud info blog
cache:
    config:
        redis_password: <password>
        redis_replication: true
    instances: 1
    type: redis
db:
    config:
        mysql_masterslave: true
        mysql_password: <password>
    instances: 1
    type: mysql
www:
    config:
        static: static
        uwsgi_processes: 4
    instances: 1
    type: python
    url: <url was here>

扩展

扩展能够增强应用的能力,处理更多流量或可能发生的故障。使用一般的非PaaS设置,扩展应用可能会非常痛苦和耗时,但使用PaaS,扩展可以像运行一些命令一样简单。有三种扩展类型:纵向,水平,高可用性。

纵向扩展,意味着增大当前服务,使其可以变得更大。通常数据库这样做,因为数据库越大,所需的空间和内存就越多。

水平扩展,意味着创建一个以上的服务实例,以便在不同的服务之间分配工作,提供更大的容量。

高可用性意味着同时有多个服务在运行,如果其中一个服务出现问题,另一个服务可以及时补上来。这将有助于避免发生故障(EC2实例崩溃)导致长时间停止运转。理想情况下,在生产环境中运行时,所有服务都应按照“高可用性”进行扩展。

有两种类型的服务,有状态的,无状态的。有状态服务是有持久数据的服务。有状态服务的例子是mysql,redis,postgresql,solr,MongoDB和RabbitMQ。

在dotCloud上部署一个“水平高可用扩展的有状态服务”,意味着要创建一个主/从设置,如果主设备有任何问题,可以自动切换到从设备。dotCloud在MySQL,Redis和MongoDB上支持HA扩展。

有状态的服务一般如下扩展:

mysql:2(主/从)

redis:2(主/从)

mongodb:3或5(使用副本集)

扩展无状态服务,和扩展上述支持的有状态服务,步骤是相同的。只需在命令行中运行相应的扩展命令:

$ dotcloud scale app db=2

对于无状态应用程序,除非你是订阅了dotCloud的企业版,否则,仅限于一定数量的扩展范围。如果你的应用程序需要大量扩展,你应该联系dotCloud,让他们知道你打算做什么,他们会告诉你如何最好地实现你的目标。

链接:http : //docs.dotcloud.com/guides/scaling/

数据库备份

在dotCloud上托管应用程序,并不意味着不需要备份数据。应当备份的最重要的信息,就是数据库。幸运的是,dotCloud可以轻松备份数据库。如何设置数据库备份请参阅:http : //docs.dotcloud.com/guides/backups/

电子邮件

如果应用需要发送或接收电子邮件,请参阅下面步骤。由于dotCloud运行在EC2上,EC2被很多人利用来发送垃圾邮件,因此最好使用第三方电子邮件提供商。受欢迎的是MailGunSendGridCritSendAmazon SES

你可以用几种不同的方法来设置它。第一种方法是最简单的方法,它允许您为每个服务配置SMTP设置。可以按下面方法(见下文)。可以手动设置该服务的SMTP设置,当应用程序需要发送电子邮件时,它将使用这些设置。这是最简单的设置,但这种方法有缺点,如果有多个服务的话,需要手动为每个服务进行一次设置。另外,如果想更改设置,则需要销毁服务并重新创建,因为只在服务创建时读取这些设置。

www:
  type: python
  config:
    smtp_server: smtp.mailgun.org
    smtp_port: 25
    smtp_username: postmaster@company.com
    smtp_password: YourMailGunPassword

更好的方法是使用dotCloud的SMTP服务。SMTP服务可以接收右键,并将邮件转发到正确的地址。最好的情况是使用第三方电子邮件提供商,但是您也可以使用典型的省钱解决方案——用gmail发送电子邮件。使用gmail时一定要小心,因为gmail不允许发送大量邮件,一旦达到每日邮件数量限制,就不能再发送了。所以,如果每天的邮件数量很少,可以这样做,但如果数量很大,就不要用gmail了。此外,电子邮件始终显示来自你的gmail,这适合一些系统提醒类的邮件,但如果是正规业务的话,就不是很合适了。

这里是一个使用mailgun的例子。

mailer:
  type: smtp
  config:
    smtp_relay_server: smtp.mailgun.org
    smtp_relay_port: 587
    smtp_relay_username: postmaster@yourmailgundomain.com
    smtp_relay_password: YourMailgunPassword

这里是一个使用Gmail的例子。

mailer:
  type: smtp
  config:
    smtp_relay_server: smtp.gmail.com
    smtp_relay_port: 587
    smtp_relay_username: your_gmail_username@gmail.com
    smtp_relay_password: Your_Gmail_Password

如果做好了上述配置,在environment.json文件中,就可以找到它们。

如果您想接收电子邮件,最好使用像MailGun这样的服务。

链接:

定时工作

如果您的应用程序需要运行定时作业,请按照下面步骤操作:http : //docs.dotcloud.com/guides/periodic-tasks/

Celery

这个博客并不需要celery,但dotCloud支持celery。有关更多信息,请点击此链接:http : //docs.dotcloud.com/tutorials/python/django-celery/

S3FS

如果您在s3上存储数据,则可以挂载s3存储桶,以便可以从应用程序上,像访问本地目录一样访问s3。在存储由访问者上传的文件,或在不同Web进程之间共享文件时很有帮助。按照以下说明进行设置:http : //docs.dotcloud.com/guides/s3fs/

日志

如果你需要查看日志,看看运行状态,你可以通过两种方法来完成。第一种方法会在控制台显示日志。

#查看日志,打印到控制台。按ctrl-c停止。
$ dotcloud logs blog.www

或者通过ssh登录并查看你的日志。

#打开一个shell
$ dotcloud ssh blog.www

最常用的日志放在下面的目录下:

#nginx访问和错误日​​志。
/var/log/nginx/<app_name>.{access,error}.log

#wsgi错误日志
/var/log/supervisor/uswgi.log

重新启动服务

如果需要重新启动服务,只需使用此命令。

#重新启动服务
dotcloud restart blog.www

本文的版权归 你竟然在代码里下毒 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏极客生活

数据分析sql技能之数据库导入

作为数据分析师很多时候由于各种原因无法直接连接到数据库上进行sql操作。 尤其是需要大量数据计算的时候,虽然只是查询操作,但是不小心会产生非常大的CPU消耗,...

551
来自专栏Petrichor的专栏

文件层次结构

文件系统层次结构标准(英语:Filesystem Hierarchy Standard,FHS)定义了Linux操作系统中的主要目录及目录内容。在大多数情况下,...

894
来自专栏小俊博客

Memtester一键脚本:检测VPS真实可分配内存及超售情况

Memtester是一个检测VPS真实可分配内存的小工具,适用于检测VPS超售情况。本程序检测的可分配内存指的是用户使用时最大能占用的内存量。

3913
来自专栏木头编程 - moTzxx

我在对PHPAdmin进行数据库文件导入时遇到的几个问题,备忘

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

744
来自专栏Web 开发

用PHP来执行定时任务

上个月有个需求,用PHP写了一个接口给SDK使用,原始数据使用MySQL进行记录。热数据用Redis进行+1的原子操作。每隔一定时间,由一个PHP脚本(姑且就命...

680
来自专栏cmazxiaoma的架构师之路

Redis、Jmeter、MySQL的那些事

1724
来自专栏蓝天

统计UPD丢包工具

下载位置:https://github.com/eyjian/libmooon/tree/master/shell

712
来自专栏Python中文社区

如何快速爬取B站全站视频信息

專 欄 ❈陈键冬,Python中文社区专栏作者,知乎专栏:尽瞎扯 GitHub: https://github.com/chenjiandongx ❈ B站我...

24510
来自专栏CDA数据分析师

让你效率提高300%的Excel键盘技巧

本文为简书作者傲看今朝原创,CDA数据分析师已获得授权 刚进惠普的时候,听说公司里的某个领导操作Excel从不用鼠标,感觉真是太牛逼了,满是崇拜的眼神。然而经过...

1868
来自专栏IMWeb前端团队

短信中的链接为什么那么短?

本文作者:IMWeb coverguo 原文出处:IMWeb社区 未经同意,禁止转载 前言 前段时间读了一些关于短网址的文章,加上刚好收到一个含有短网...

31710

扫码关注云+社区