项目主页:https://github.com/progrium/dokku? (当前推荐的Linux版本是 Ubuntu 13.04)
参考资料 http://gun.io/blog/deploying-django-app-on-dokku/
安装
$ wget -qO- https://raw.github.com/progrium/dokku/master/bootstrap.sh | sudo bash
配置
0) 安装一个域名 和一个泛域名(wildcard domain通配域名) 指向这台主机.确认/home/dokku/VHOST
被设置成这个域名
默认情况下,它被设置成 服务器的 hostname(条件是dig +short $HOSTNAME能正确解析到你的主机名). 如果不能,请手动建立这个文件
如果这个文件不存在,当你push应用时, dokku 将使用端口号来发布这个应用,而不是子域名
1)将本地的用户的公钥 同 服务器上的某个用户 关联
cat ~/.ssh/id_rsa.pub | ssh zhiwei@zhiwei.li "sudo sshcommand acl-add dokku zhiwei"
服务器域名 zhiwei.li ?服务器上的用户名为 dokku, ?key在服务器的名字叫做zhiwei, 本地用户叫zhiwei
https://github.com/progrium/sshcommand 是 dokku的作者 progrium 开发的一个工具
sshcommand acl-add # adds named SSH key to user from STDIN例如:cat ~/.ssh/id_rsa.pub | ssh root@myserver sshcommand acl-add cmd zhiweikey
另外一种方法就是用
cat ~/.ssh/id_rsa.pub | ssh zhiwei@192.168.1.152 "sudo gitreceive upload-key dokku"
部署一个应用 (以python flask为例子, 全部在本地通过git运行)
参考资料 https://devcenter.heroku.com/articles/getting-started-with-python
$ mkdir helloflask$ cd helloflask
确认使用最新版的virtualenv, 如果你使用ubuntu发行版自带的版本,需要增加 –no-site-packages 选项
$ virtualenv venv --distribute或者$ virtualenv --no-site-packages venv
注意: Virtualenv 1.10以下版本提供了 --distribute?选项 来使用 setuptools的分支版本Distribute,因为 Distribute已经合并到 setuptools, 所以这个选项就没有了
我用的命令是 $ virtualenv venv
New python executable in venv/bin/pythonInstalling Setuptools……Installing Pip…
如果是python3,是不是应该指定
virtualenv -p /usr/bin/python3 venv
-p PYTHON_EXE, –python=PYTHON_EXEThe Python interpreter to use, e.g., ??–python=python2.5 will use the python2.5 interpreterto create the new environment. The default is theinterpreter that virtualenv was installed with(/usr/bin/python)
–no-site-packages Don’t give access to the global site-packages dir tothe virtual environment (default) ?这个行为是默认的
python 3.3内建venv模块
python3 -m venv myenv或者pyvenv-3.3 myenv
这里不用指定python 3,后面创建runtime.txt时指定 3.3.2(heroku只支持这个)
激活virtualenv环境
$ source venv/bin/activate
安装gunicoren和Flask
$ pip install Flask gunicorn
编写hello world
hello.py
import osfrom flask import Flaskapp = Flask(__name__)@app.route('/')def hello(): return 'Hello World!'
应用根目录下的Procfile声明启动web应用时 执行什么命令
web: gunicorn hello:app
应用根目录下的requirements.txt 用来识别python应用的依赖, 格式简单,大多数python项目指定外部的python模块也都是这种格式
可以用pip这个美美命令来生成
$ pip freeze > requirements.txt
runtime.txt 指定运行时 是python 3还是python2
python-3.3.3
gitignore里排除一些临时文件
echo "venv*.pyc" > .gitignore
创建git仓库,并提交
$ git init$ git add .$ git commit -m "init"
应用准备好,下面就跟heroku没关系了,继续 dokku
$ git remote add zhiwei dokku@zhiwei.li:helloflask$ git push zhiwei master
上面的zhiwei是git 分支的名称
远程控制
ssh -t dokku@zhiwei.li run helloflask ls -alh
格式是 run
$ sudo docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES95159914f909 app/helloflask:latest /bin/bash -c /start 5 hours ago Up 5 hours 0.0.0.0:49153->5000/tcp naughty_mclean11570331c10b 6300181b7153 /build/builder 5 hours ago Exit 0 naughty_albattanic29a1599d805 progrium/buildstep:latest /bin/bash -c mkdir - 5 hours ago Exit 0 stoic_davinci$ sudo docker inspect 95159914f909[{ "ID": "95159914f909763b2f4f3716f692d0b6e12b61f4051a66f4af76047b49f8c54b", "Created": "2013-12-05T08:16:40.824848275Z", "Path": "/bin/bash", "Args": [ "-c", "/start web" ], "Config": { "Hostname": "95159914f909", "Domainname": "", "User": "", "Memory": 0, "MemorySwap": 0, "CpuShares": 0, "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "PortSpecs": null, "ExposedPorts": { "5000/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PORT=5000" ], "Cmd": [ "/bin/bash", "-c", "/start web" ], "Dns": null, "Image": "app/helloflask", "Volumes": null, "VolumesFrom": "", "WorkingDir": "", "Entrypoint": null, "NetworkDisabled": false }, "State": { "Running": true, "Pid": 6010, "ExitCode": 0, "StartedAt": "2013-12-05T08:16:40.868229406Z", "FinishedAt": "0001-01-01T00:00:00Z", "Ghost": false }, "Image": "1a1aecffe9f0bbc9eadefee67db22976f32717a3cf87245457a2576a4218e833", "NetworkSettings": { "IPAddress": "172.17.0.4", "IPPrefixLen": 16, "Gateway": "172.17.42.1", "Bridge": "docker0", "PortMapping": null, "Ports": { "5000/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "49153" } ] } }, "SysInitPath": "/usr/bin/docker", "ResolvConfPath": "/etc/resolv.conf", "HostnamePath": "/var/lib/docker/containers/95159914f909763b2f4f3716f692d0b6e12b61f4051a66f4af76047b49f8c54b/hostname", "HostsPath": "/var/lib/docker/containers/95159914f909763b2f4f3716f692d0b6e12b61f4051a66f4af76047b49f8c54b/hosts", "Name": "/naughty_mclean", "Driver": "aufs", "Volumes": {}, "VolumesRW": {}}]$ sudo docker infoContainers: 3Images: 3Driver: aufs Root Dir: /var/lib/docker/aufs Dirs: 9WARNING: No swap limit supportroot 6010 0.0 0.0 25576 1320 ? Ss 16:16 0:00 lxc-start -n 95159914f909763b2f4f3716f692d0b6e12b61f4051a66f4af76047b49f8c54b -f /var/lib/docker/containers/95159914f909763b2f4f3716f692d0b6e12b61f4051a66f4af76047b49f8c54b/config.lxc -- /.root 6015 0.0 0.0 17880 1540 ? S 16:16 0:00 /bin/bash /start webroot 6083 0.0 0.2 80976 11332 ? S 16:16 0:03 /app/.heroku/python/bin/python /app/.heroku/python/bin/gunicorn hello:approot 6095 0.0 0.3 98212 15164 ? S 16:16 0:00 /app/.heroku/python/bin/python /app/.heroku/python/bin/gunicorn hello:app居然是以root进程运行