今天Heroku宣布支持Python,原本一直眼馋Ruby的同学有Heroku这个云主机平台,终于等到支持Python,立刻尝鲜一把。
安装Heroku环境
虽然系统是Ubuntu 10.04,但因为不想增加apt-get-repository,我没有使用官方推荐的apt-get方式。采用tarball方式,下载解压运行,提示没有ruby环境,那就安装吧:
sudo apt-get install ruby rubygems libreadline-ruby libopenssl-ruby
然后手动把解压出来的heroku-client文件夹加到PATH路径里。
配置Heroku环境
此处借用Heroku的文档,配置Heroku登录凭据与公私钥
$ heroku login Enter your Heroku credentials. Email: adam@example.com Password: Could not find an existing public key. Would you like to generate one? [Yn] Generating new SSH public key. Uploading ssh public key /Users/adam/.ssh/id_rsa.pub
编写hello world
Heroku文档是介绍使用flask这个web框架,由于习惯使用web.py,所以使用web.py来编写hello world。
编写pip的requirements.txt
$ echo "web.py==0.36" > requirements.txt
创建一个virtualenv
$ virtualenv --no-site-packages . New python executable in ./bin/python Installing setuptools............done. $source bin/activate
然后根据requirements.txt安装环境:
$ bin/pip install -r requirements.txt Downloading/unpacking web.py==0.36 (from -r requirements.txt (line 1)) Downloading web.py-0.36.tar.gz (87Kb): 87Kb downloaded Running setup.py egg_info for package web.py Installing collected packages: web.py Running setup.py install for web.py Successfully installed web.py Cleaning up...
编写.gitignore,将以下内容写到.gitignore文件里
bin build include lib .Python *.pyc
编写web.py程序
终于开始写干活的程序,直接上代码:
$ vi hello.py
import web import os, sys urls = ( '/(.*)', 'hello' ) app = web.application(urls, globals()) class hello: def GET(self, name): if not name: name = 'World' return 'Hello, ' + name + '!' if __name__ == "__main__": port = os.environ.get("PORT", "5000") sys.argv[1] = port app.run()
由于Heroku会提供PORT环境变量来指定应用程序的端口,而web.py默认使用命令行第一个参数作为端口,因此直接获取环境变量PORT,放到sys.argv[1]里,注意web.py从命令行参数读端口参数,端口参数是字符串。
使用Foreman作为启动脚本
Heroku是ruby系的产品,使用Foreman作为启动脚本
使用rubygems即可安装foreman
$ gem install foreman
在ubuntu 10.04上安装foreman,会遇到错误:
ERROR: Error installing foreman: thor requires RubyGems version >= 1.3.6而ubuntu 10.04的默认源里的rubygems是1.3.5的,参考stackoverflow一篇文章,找到解决方法:
sudo gem install rubygems-update cd /var/lib/gems/1.8/bin sudo ./update_rubygems
然后编写Procfile,这个Procfile是Foreman所读取的启动项
echo "web: python hello.py 5000" > Procfile
然后就可以启动来看下
$ foreman start 13:20:59 web.1 | started with pid 25656 13:21:00 web.1 | http://0.0.0.0:5000/
正常。
部署到Heroku
Heroku使用git push的部署方式,当代码push到远端,Heroku会自动更新代码并重启应用,使用过git的同学应该不会陌生。
$ heroku create --stack cedar Creating simple-mountain-9034... done, stack is cedar http://simple-mountain-9034.herokuapp.com/ | git@heroku.com:simple-mountain-9034.git Git remote heroku added
然后推送到远端:
$ git push heroku master Counting objects: 6, done. Delta compression using up to 4 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (6/6), 592 bytes, done. Total 6 (delta 0), reused 0 (delta 0) -----> Heroku receiving push -----> Python app detected -----> Preparing virtualenv version 1.6.1 New python executable in ./bin/python2.7 Also creating executable in ./bin/python Installing setuptools............done. Installing pip...............done. -----> Installing dependencies using pip version 1.0.1 Downloading/unpacking web.py==0.36 (from -r requirements.txt (line 1)) Creating supposed download cache at /app/tmp/repo.git/.cache/pip_downloads Storing download in cache at /app/tmp/repo.git/.cache/pip_downloads/http%3A%2F%2Fpypi.python.org%2Fpackages%2Fsource%2Fw%2Fweb.py%2Fweb.py-0.36.tar.gz Running setup.py egg_info for package web.py Installing collected packages: web.py Running setup.py install for web.py Successfully installed web.py Cleaning up... -----> Discovering process types Procfile declares types -> web -----> Compiled slug size is 2.6MB -----> Launching... done, v3 http://simple-mountain-9034.herokuapp.com deployed to Heroku To git@heroku.com:simple-mountain-9034.git * [new branch] master -> master
这里注意要修改web的进程数:
$ heroku scale web=1 Scaling web processes... done, now running 1
然后可以查看进程的状态:
$ heroku ps Process State Command ------------ ------------------ ------------------------------ web.1 up for 5s python hello.py 5000
访问自己的Heroku应用地址,例如我的是http://simple-mountain-9034.herokuapp.com/abcdefg,成功!
参考资料:
Pingback: Ubuntu 10.04 + Heroku + Python | lsharemy()