概述
如需转载请注明出处。
win10 64位、Python 3.6.3、Notepad++、Chrome 67.0.3396.99(正式版本)(64 位)
注:作者编写时间2018-04-04,linux、python 3.5.2
以下内容均是加入自己的理解与增删,以记录学习过程。不限于翻译,部分不完全照搬作者Miguel Grinberg的博客,版权属于作者,感谢他提供免费学习的资料。
传送门 | |||
---|---|---|---|
00 开篇 | 01 Hello world | 02 模板 | 03 Web表单 |
04 数据库 | 05 用户登录 | 06 个人资料和头像 | 07 错误处理 |
08 关注 | 09 分页 | 10 支持QQ邮箱 | 11 美化页面 |
12 时间和日期 | 13 I18n和L10n 翻译成中文 zh-CN | 14 Ajax(百度翻译API | 15 更好的App结构(蓝图) |
16 全文搜索 | 17 部署到腾讯云Ubuntu | 18 部署到Heroku | 19 部署到Docker容器 |
20 JavaScript魔法 | 21 用户通知 | 22 后台工作(Redis) | 23 应用程序编程接口(API) |
在上一章中,展示了托管Python应用程序的“传统”方式,并提供了基于Linux服务器部署的实例。如果不习惯管理Linux系统,认为需要投入到任务中的工作量很大。且认为有一种更简单的方法。
在本章中,将展示一种完全不同的方法,它依靠第三方 云托管提供商来执行大多数管理任务,从而可以将更多的时间花在处理应用程序上。
很多 云托管提供商都提供可运行应用程序的管理平台。在这些平台上部署应用程序,我们只需提供 实际应用程序,因为硬件、操作系统、脚本语言解释器、数据库等均由服务 来管理。这种类型的服务 称为 平台即服务(Platform as a Service,简写为 PaaS)。
我将着眼于将Microblog部署到Heroku,它是一种流行的 云托管服务,对Python应用程序也非常友好。选择Heroku不仅是因为它很受欢迎,而且因为它有一个免费服务,可做一个完整的部署而不花任何钱(但现在(2018年09月14日)有一些限制,如①免费账号每月有550小时的运行时间,如果验证信用卡可增加1000小时;②30分钟无人访问就休眠)。目前国外替代者有nanobox和Hasura等。
Heroku提供的不同服务等级 允许选择为应用程序获得多少计算能力和时间,因此随着用户群的增长,可能需要购买更多的计算单元,Heroku称之为 “dynos”。
创建Heroku账户
在部署到Heroku之前,需要拥有一个账户。访问heroku.com并创建一个免费账户。拥有账户并登陆Heroku后,就可访问仪表板,其中列出了所有应用程序。
安装Heroku CLI
Heroku提供了一个命令行工具,用于与它们的服务进行交互,称之为Heroku CLI,可用于Windows、Mac OS、Linux。该文档包含所有支持平台的安装说明。如果计划部署应用程序以测试服务,请将其安装我们的电脑上。
安装CLI后,第一件事是登录Heroku账户(也可以在cmd中操作。如下在git中完成):
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku login
heroku: Enter your login credentials
Email [电子邮箱]: 输入电子邮箱
Password: 输入你的密码。
Logged in as czy0905@outlook.com
Heroku CLI要求输入电子邮件地址和账户密码。身份验证状态将在后续命令中记住。
设置Git
git工具 是将应用程序部署到Heroku的核心。因此,如果电脑上还没它,则必须将其安装上。为什么使用git在我们的项目上?有很多方面的原因。如果计划部署到Heroku,那么还有一个,因为要部署到Heroku,应用程序必须位于git仓库中。如果要对Microblog进行测试部署 ,可从Github中clone(克隆)应用程序:
$ git clone https://github.com/miguelgrinberg/microblog
$ cd microblog
$ git checkout v0.18
git checkout
命令 选择在其历史记录中与本章对应的点处具有应用程序的特定提交。
如果更喜欢使用自己的代码而不是作者的代码,可以通过运git在顶级目录上运行git init .
命令将自己的项目转换为存储库(注意 init 后的 句点 .
,它告诉git要在当前目录中创建存储库)。
创建一个Heroku应用程序
用Heroku注册一个新的应用程序,从应用程序的 根目录中使用apps:create
命令,将应用程序名字 作为
唯一参数传递:(在cmd或git中执行都OK,在此选择git)
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku apps:create flask-mymicroblog
Creating flask-mymicroblog... done
https://flask-mymicroblog.herokuapp.com/ | https://git.heroku.com/flask-mymicroblog.git
Heroku要求应用程序具有唯一的名称。我之前使用的名称 flask-microblog
不可用,因为我正在使用它,因此需要为部署选择不同的名称(如上:microblogwithflask)。
这个命令的输出 将包括Heroku分配给应用程序的URL,以及它的git仓库。我们本地的git仓库将配置一个名为heroku的额外远程数据库。可以使用如下git remote命令验证它是否存在:
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ git remote -v
heroku
https://git.heroku.com/flask-mymicroblog.git (fetch)
heroku
https://git.heroku.com/flask-mymicroblog.git (push)
根据创建git仓库的方式,上述命令的输出还可能包含另一个名为 origin
的远程。
短暂的文件系统
Heroku平台 与其他部署平台的 不同之处在于 它具有在虚拟化平台上运行的临时文件系统。那意味着什么?这意味着 Heroku可以随时将服务器运行的虚拟服务器重置为干净状态。我们不能假设我保存到文件系统的任何数据都会持久存在,事实上,Heroku会经常回收服务器。在这些条件下工作会为我的应用程序引入一些问题,它使用了一些文件:
- 默认的SQLite数据库引擎将数据写入磁盘文件
- 应用程序的日志也会写入文件系统
- 编译的语言翻译存储库也写入本地文件
以下部分将介绍这三个方面。
使用Heroku Postgres数据库
为了解决第一个问题,将切换到另一个数据库引擎。在第17章中,使用的MySQL数据库为Ubuntu部署添加了健壮性。Heroku有一个基于Postgres数据库的自己的数据库产品,所以将切换到此以避免基于文件的SQLite。
Heroku应用程序的数据库配置了相同的Heroku CLI。在这个案例下,将在免费套餐上创建一个数据库:
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku addons:add heroku-postgresql:hobby-dev
Creating heroku-postgresql:hobby-dev on flask-mymicroblog... free
Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pg:copy
Created postgresql-shallow-23648 as DATABASE_URL
Use heroku addons:docs heroku-postgresql to view documentation
新创建的数据库URL存储在应用程序运行时可用的环境变量DATABASE_URL
中。这非常方便,因为应用程序已在这个变量中查找数据库URL。
登录到stdout
Heroku希望应用程序直接登录stdout
。当使用
heroku logs
命令时,将保存并返回应用程序打印到标准输出的任何内容。所以我要添加一个配置变量,指示我是否需要登录
stdout
或者像我一直在做的文件。以下是配置的更改:
microblog/config.py:登录到stdout的选项
class Config(object):
# ...
LOG_TO_STDOUT = os.environ.get('LOG_TO_STDOUT')
然后在应用程序工厂函数中,可以检查此配置以了解如何配置应用程序的记录器:
app/__init__.py:登录到stdout或文件
def create_app(config_class=Config):
# ...
if not app.debug and not app.testing:
if app.config['MAIL_SERVER']:
# ...
if app.config['LOG_TO_STDOUT']:
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
app.logger.addHandler(stream_handler)
else:
if not os.path.exists('logs'):
os.mkdir('logs')
file_handler = RotatingFileHandler('logs/microblog.log',
maxBytes=10240, backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s '
'[in %(pathname)s:%(lineno)d]'))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('Microblog startup')
return app
所以现在我需要在应用程序在Heroku中运行时设置环境变量LOG_TO_STDOUT
,而不是其他配置中。Heroku CLI使这很容易,因为它提供了一个选项来设置在运行时使用的环境变量:
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku config:set LOG_TO_STDOUT=1
Setting LOG_TO_STDOUT and restarting microblogwithflask... done, v4
LOG_TO_STDOUT: 1
编译翻译
依赖于本地文件的Microblog的第三个方面是编译语言翻译文件。确保这些文件 永远不会从短暂文件系统中消失的更直接的选项是将编译的语言文件添加到git存储库,以便它们在部署到Heroku后成为应用程序初始状态的一部分。在我看来,更优雅的选择是在Heroku的启动命令中包含flask translate compile
命令,以便在服务器重新启动时,这些文件将再次编译。我将使用此选项,因为我知道我的启动过程无论如何都需要多个命令,因为我还需要运行数据库迁移。所以现在,我将把这个问题放在一边,稍后当我编写Procfile时会重新访问它。
Elasticsearch Hosting
Elasticsearch是可以添加到Heroku项目的众多服务之一,但与Postgres不同,这不是Heroku提供的服务,而是与Heroku合作提供附加组件的第三方。在我撰写本文时,有三个不同的集成Elasticsearch服务提供商。在配置Elasticsearch之前,请注意Heroku要求您的帐户在安装任何第三方加载项之前将信用卡存档,即使您保留在其免费层中也是如此。如果您不想向Heroku提供信用卡,请跳过本节。仍然可以部署应用程序,但搜索功能不起作用。(PS:我选择跳过)
在作为附加组件提供的Elasticsearch选项中,我决定尝试SearchBox,它带有免费的入门计划。要将SearchBox添加到您的帐户,您必须在登录Heroku时运行以下命令:
$ heroku addons:create searchbox:starter
此命令将部署Elasticsearch服务,并将服务的连接URL保留在SEARCHBOX_URL与应用程序关联的环境变量中。再一次请记住,除非您将信用卡添加到Heroku帐户,否则此命令将失败。
如果从第16章回忆起来,我的应用程序会在ELASTICSEARCH_URL变量中查找Elasticsearch连接URL ,因此我需要添加此变量并将其设置为SearchBox分配的连接URL:
$ heroku config:get SEARCHBOX_URL
<your-elasticsearch-url>
$ heroku config:set ELASTICSEARCH_URL=<your-elasticsearch-url>
这里我首先要求Heroku打印出值SEARCHBOX_URL
,然后我添加了一个新的环境变量,其名称ELASTICSEARCH_URL
设置为相同的值。
更新requirements
Heroku希望依赖项位于`requirements.txt`文件中,就像我在第15章中定义的那样。但是对于在Heroku上运行的应用程序,我需要为此文件添加两个新的依赖项。
microblog/requirements.txt
#...
#requirements for Heroku
psycopg2==2.7.3.1
gunicorn==19.7.1
Heroku不提供自己的Web服务器。相反,它希望应用程序在环境变量中给出的端口号上启动自己的Web服务器$PORT
。由于Flask开发Web服务器不够强大,无法用于生产,我将再次使用gunicorn,即Heroku推荐的Python应用程序服务器。
该应用程序还将连接到Postgres数据库,因此SQLAlchemy需要psycopg2
安装该程序包。
gunicorn
和psycopg2
需要添加到requirements.txt文件。
Procfile
Heroku需要知道如何执行应用程序,并且它在应用程序的 根目录中使用名为Procfile
的文件。(git中命令)创建它:
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ touch Procfile
根目录下就多出了这个文件。
此文件的格式很简单,每行包括进程名称,冒号,然后是启动进程的命令。在Heroku上运行的最常见类型的应用程序是Web应用程序,对于此类应用程序,应该是进程名称web。下面你可以看到Microblog的Procfile
:
microblog/Procfile:Heroku Procfile。
web: flask db upgrade; flask translate compile; gunicorn microblog:app
在这里,定义了命令以按顺序启动Web应用程序作为三个命令。首先运行数据库迁移升级;然后编译语言翻;,最后启动服务器。
因为前两个子命令都是基于flask命令的,所以我需要添加FLASK_APP
环境变量:
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku config:set FLASK_APP=microblog.py
Setting FLASK_APP and restarting microblogwithflask... done, v5
FLASK_APP: microblog.py
该应用程序还依赖于其他环境变量,例如配置电子邮件服务器或实时翻译令牌的变量。需要用添加命令heroku config:set
命令来添加:(###部分 填上自己真实的)
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku config:set MAIL_SERVER=smtp.qq.com
Setting MAIL_SERVER and restarting microblogwithflask... done, v6
MAIL_SERVER: smtp.qq.com
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku config:set MAIL_PORT=465
Setting MAIL_PORT and restarting microblogwithflask... done, v7
MAIL_PORT: 465
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku config:set MAIL_USE_SSL=True
Setting MAIL_USE_SSL and restarting microblogwithflask... done, v8
MAIL_USE_SSL: True
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku config:set MAIL_USERNAME=###@qq.com
Setting MAIL_USERNAME and restarting microblogwithflask... done, v9
MAIL_USERNAME: ###@qq.com
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku config:set MAIL_PASSWORD=###
Setting MAIL_PASSWORD and restarting microblogwithflask... done, v10
MAIL_PASSWORD: ###
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku config:set APPID=###
Setting APPID and restarting microblogwithflask... done, v11
APPID: ###
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ heroku config:set BD_TRANSLATOR_KEY=###
Setting BD_TRANSLATOR_KEY and restarting microblogwithflask... done, v12
BD_TRANSLATOR_KEY: ###
gunicorn
命令比用于Ubuntu部署的命令更简单,因为该服务器与Heroku环境有很好的集成。例如,默认情况下,环境变量$PORT
受到推存,而不是使用-w
选项来设置工作器数量,heroku建议添加一个名为WEB_CONCURRENCY
的变量,该变量是gunicorn
在-w
未提供时使用,使得可灵活地控制工作者数量而无需修改Procfile
。
部署应用程序
所有准备步骤都已完成,因此现在是时候运行部署了。要将应用程序上载到Heroku的服务器以进行部署,请使用git push
命令。这类似于将本地git存储库中的更改推送到GitHub或其他远程git服务器的方式。
现在已经到了最有趣的部分,将应用程序推送到我们的Heroku主机帐户。这实际上非常简单,只需要将git应用程序推送到Heroku git存储库的主分支。关于如何执行此操作有几种变体,具体取决于我们创建git存储库的方式。如果正在使用作者的v0.18代码,那么需要基于此标记创建分支,并将其作为远程主分支推送,如下所示:
$ git checkout -b deploy
$ git push heroku deploy:master
如果正在使用自己的存储库,那么代码已经在master分支中,因此首先需要确保提交更改:
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ git commit -a -m "heroku deployment changes"
[master aaa5912] heroku deployment changes
3 files changed, 17 insertions(+), 6 deletions(-)
然后,运行以下命令来开始部署:
Administrator@Cchen-PC MINGW64 /d/microblog (master)
$ git push heroku master
Counting objects: 64, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (58/58), done.
Writing objects: 100% (64/64), 22.94 KiB | 0 bytes/s, done.
Total 64 (delta 5), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing python-3.6.6
remote: -----> Installing pip
remote: -----> Installing SQLite3
remote: -----> Installing requirements with pip
remote:
Collecting alembic==1.0.0 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 1))
remote:
Downloading https://files.pythonhosted.org/packages/96/c7/a4129db460c3e0ea8fea0c9eb5de6680d38ea6b6dcffcb88898ae42e170a/alembic-1.0.0-py2.py3-none-any.whl (158kB)
remote:
Collecting Babel==2.6.0 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 2))
remote:
Downloading https://files.pythonhosted.org/packages/b8/ad/c6f60602d3ee3d92fbed87675b6fb6a6f9a38c223343ababdb44ba201f10/Babel-2.6.0-py2.py3-none-any.whl (8.1MB)
remote:
Collecting blinker==1.4 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 3))
remote:
Downloading https://files.pythonhosted.org/packages/1b/51/e2a9f3b757eb802f61dc1f2b09c8c99f6eb01cf06416c0671253536517b6/blinker-1.4.tar.gz (111kB)
remote:
Collecting certifi==2018.8.24 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 4))
remote:
Downloading https://files.pythonhosted.org/packages/df/f7/04fee6ac349e915b82171f8e23cee63644d83663b34c539f7a09aed18f9e/certifi-2018.8.24-py2.py3-none-any.whl (147kB)
remote:
Collecting chardet==3.0.4 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 5))
remote:
Downloading https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl (133kB)
remote:
Collecting click==6.7 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 6))
remote:
Downloading https://files.pythonhosted.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl (71kB)
remote:
Collecting dominate==2.3.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 7))
remote:
Downloading https://files.pythonhosted.org/packages/43/b2/3b7d67dd59dab93ae08569384b254323516e8868b453eea5614a53835baf/dominate-2.3.1.tar.gz
remote:
Collecting elasticsearch==6.3.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 8))
remote:
Downloading https://files.pythonhosted.org/packages/b1/f1/89735ebb863767516d55cee2cfdd5e2883ff1db903be3ba1fe15a1725adc/elasticsearch-6.3.1-py2.py3-none-any.whl (119kB)
remote:
Collecting Flask==1.0.2 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 9))
remote:
Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB)
remote:
Collecting Flask-Babel==0.11.2 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 10))
remote:
Downloading https://files.pythonhosted.org/packages/c6/1b/ce9253dc6a71ede1d7b19cd280f7a21219b47ac75005dd97bcfbdbe8eab9/Flask_Babel-0.11.2-py2.py3-none-any.whl
remote:
Collecting Flask-Bootstrap==3.3.7.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 11))
remote:
Downloading https://files.pythonhosted.org/packages/88/53/958ce7c2aa26280b7fd7f3eecbf13053f1302ee2acb1db58ef32e1c23c2a/Flask-Bootstrap-3.3.7.1.tar.gz (456kB)
remote:
Collecting Flask-Login==0.4.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 12))
remote:
Downloading https://files.pythonhosted.org/packages/c1/ff/bd9a4d2d81bf0c07d9e53e8cd3d675c56553719bbefd372df69bf1b3c1e4/Flask-Login-0.4.1.tar.g
remote:
Collecting Flask-Mail==0.9.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 13))
remote:
Downloading https://files.pythonhosted.org/packages/05/2f/6a545452040c2556559779db87148d2a85e78a26f90326647b51dc5e81e9/Flask-Mail-0.9.1.tar.gz (45kB)
remote:
Collecting Flask-Migrate==2.2.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 14))
remote:
Downloading https://files.pythonhosted.org/packages/59/97/f681c9e43d2e2ace4881fa588d847cc25f47cc98f7400e237805d20d6f79/Flask_Migrate-2.2.1-py2.py3-none-any.whl
remote:
Collecting Flask-Moment==0.6.0 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 15))
remote:
Downloading https://files.pythonhosted.org/packages/dd/f7/13e9d7480f9097e0efe945e17309c34e0a547a6cfb3f9728324d2f9bf462/Flask_Moment-0.6.0-py2.py3-none-any.whl
remote:
Collecting Flask-SQLAlchemy==2.3.2 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 16))
remote:
Downloading https://files.pythonhosted.org/packages/a1/44/294fb7f6bf49cc7224417cd0637018db9fee0729b4fe166e43e2bbb1f1c8/Flask_SQLAlchemy-2.3.2-py2.py3-none-any.whl
remote:
Collecting Flask-WTF==0.14.2 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 17))
remote:
Downloading https://files.pythonhosted.org/packages/60/3a/58c629472d10539ae5167dc7c1fecfa95dd7d0b7864623931e3776438a24/Flask_WTF-0.14.2-py2.py3-none-any.whl
remote:
Collecting guess-language-spirit==0.5.3 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 18))
remote:
Downloading https://files.pythonhosted.org/packages/8b/4f/9ed0280b24e9e6875c3870a97659d0106a14e36db0d7d65c5277066fc7d0/guess_language-spirit-0.5.3.tar.bz2 (81kB)
remote:
Collecting idna==2.7 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 19))
remote:
Downloading https://files.pythonhosted.org/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl (58kB)
remote:
Collecting itsdangerous==0.24 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 20))
remote:
Downloading https://files.pythonhosted.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz (46kB)
remote:
Collecting Jinja2==2.10 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 21))
remote:
Downloading https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl (126kB)
remote:
Collecting Mako==1.0.7 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 22))
remote:
Downloading https://files.pythonhosted.org/packages/eb/f3/67579bb486517c0d49547f9697e36582cd19dafb5df9e687ed8e22de57fa/Mako-1.0.7.tar.gz (564kB)
remote:
Collecting MarkupSafe==1.0 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 23))
remote:
Downloading https://files.pythonhosted.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz
remote:
Collecting PyJWT==1.6.4 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 24))
remote:
Downloading https://files.pythonhosted.org/packages/93/d1/3378cc8184a6524dc92993090ee8b4c03847c567e298305d6cf86987e005/PyJWT-1.6.4-py2.py3-none-any.whl
remote:
Collecting python-dateutil==2.7.3 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 25))
remote:
Downloading https://files.pythonhosted.org/packages/cf/f5/af2b09c957ace60dcfac112b669c45c8c97e32f94aa8b56da4c6d1682825/python_dateutil-2.7.3-py2.py3-none-any.whl (211kB)
remote:
Collecting python-dotenv==0.9.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 26))
remote:
Downloading https://files.pythonhosted.org/packages/24/3d/977140bd94bfb160f98a5c02fdfbb72325130f12a325cf993182956e9d0e/python_dotenv-0.9.1-py2.py3-none-any.whl
remote:
Collecting python-editor==1.0.3 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 27))
remote:
Downloading https://files.pythonhosted.org/packages/65/1e/adf6e000ea5dc909aa420352d6ba37f16434c8a3c2fa030445411a1ed545/python-editor-1.0.3.tar.gz
remote:
Collecting pytz==2018.5 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 28))
remote:
Downloading https://files.pythonhosted.org/packages/30/4e/27c34b62430286c6d59177a0842ed90dc789ce5d1ed740887653b898779a/pytz-2018.5-py2.py3-none-any.whl (510kB)
remote:
Collecting requests==2.19.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 29))
remote:
Downloading https://files.pythonhosted.org/packages/65/47/7e02164a2a3db50ed6d8a6ab1d6d60b69c4c3fdf57a284257925dfc12bda/requests-2.19.1-py2.py3-none-any.whl (91kB)
remote:
Collecting six==1.11.0 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 30))
remote:
Downloading https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl
remote:
Collecting SQLAlchemy==1.2.10 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 31))
remote:
Downloading https://files.pythonhosted.org/packages/8a/c2/29491103fd971f3988e90ee3a77bb58bad2ae2acd6e8ea30a6d1432c33a3/SQLAlchemy-1.2.10.tar.gz (5.6MB)
remote:
Collecting urllib3==1.23 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 32))
remote:
Downloading https://files.pythonhosted.org/packages/bd/c9/6fdd990019071a4a32a5e7cb78a1d92c53851ef4f56f62a3486e6a7d8ffb/urllib3-1.23-py2.py3-none-any.whl (133kB)
remote:
Collecting visitor==0.1.3 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 33))
remote:
Downloading https://files.pythonhosted.org/packages/d7/58/785fcd6de4210049da5fafe62301b197f044f3835393594be368547142b0/visitor-0.1.3.tar.gz
remote:
Collecting Werkzeug==0.14.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 34))
remote:
Downloading https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
remote:
Collecting WTForms==2.2.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 35))
remote:
Downloading https://files.pythonhosted.org/packages/9f/c8/dac5dce9908df1d9d48ec0e26e2a250839fa36ea2c602cc4f85ccfeb5c65/WTForms-2.2.1-py2.py3-none-any.whl (166kB)
remote:
Collecting psycopg2==2.7.3.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 38))
remote:
Downloading https://files.pythonhosted.org/packages/21/44/159fe55329b6b94dd3077080fed6c2f77c0d6b858bc415a5784e9e885235/psycopg2-2.7.3.1-cp36-cp36m-manylinux1_x86_64.whl (2.6MB)
remote:
Collecting gunicorn==19.7.1 (from -r /tmp/build_7869bcf750de900e97ffccd330aae93a/requirements.txt (line 39))
remote:
Downloading https://files.pythonhosted.org/packages/64/32/becbd4089a4c06f0f9f538a76e9fe0b19a08f010bcb47dcdbfbc640cdf7d/gunicorn-19.7.1-py2.py3-none-any.whl (111kB)
remote:
Installing collected packages: six, python-dateutil, SQLAlchemy, MarkupSafe, Mako, python-editor, alembic, pytz, Babel, blinker, certifi, chardet, click, dominate, urllib3, elasticsearch, itsdangerous, Werkzeug, Jinja2, Flask, Flask-Babel, visitor, Flask-Bootstrap, Flask-Login, Flask-Mail, Flask-SQLAlchemy, Flask-Migrate, Flask-Moment, WTForms, Flask-WTF, guess-language-spirit, idna, PyJWT, python-dotenv, requests, psycopg2, gunicorn
remote:
Running setup.py install for SQLAlchemy: started
remote:
Running setup.py install for SQLAlchemy: finished with status 'done'
remote:
Running setup.py install for MarkupSafe: started
remote:
Running setup.py install for MarkupSafe: finished with status 'done'
remote:
Running setup.py install for Mako: started
remote:
Running setup.py install for Mako: finished with status 'done'
remote:
Running setup.py install for python-editor: started
remote:
Running setup.py install for python-editor: finished with status 'done'
remote:
Running setup.py install for blinker: started
remote:
Running setup.py install for blinker: finished with status 'done'
remote:
Running setup.py install for dominate: started
remote:
Running setup.py install for dominate: finished with status 'done'
remote:
Running setup.py install for itsdangerous: started
remote:
Running setup.py install for itsdangerous: finished with status 'done'
remote:
Running setup.py install for visitor: started
remote:
Running setup.py install for visitor: finished with status 'done'
remote:
Running setup.py install for Flask-Bootstrap: started
remote:
Running setup.py install for Flask-Bootstrap: finished with status 'done'
remote:
Running setup.py install for Flask-Login: started
remote:
Running setup.py install for Flask-Login: finished with status 'done'
remote:
Running setup.py install for Flask-Mail: started
remote:
Running setup.py install for Flask-Mail: finished with status 'done'
remote:
Running setup.py install for guess-language-spirit: started
remote:
Running setup.py install for guess-language-spirit: finished with status 'done'
remote:
Successfully installed Babel-2.6.0 Flask-1.0.2 Flask-Babel-0.11.2 Flask-Bootstrap-3.3.7.1 Flask-Login-0.4.1 Flask-Mail-0.9.1 Flask-Migrate-2.2.1 Flask-Moment-0.6.0 Flask-SQLAlchemy-2.3.2 Flask-WTF-0.14.2 Jinja2-2.10 Mako-1.0.7 MarkupSafe-1.0 PyJWT-1.6.4 SQLAlchemy-1.2.10 WTForms-2.2.1 Werkzeug-0.14.1 alembic-1.0.0 blinker-1.4 certifi-2018.8.24 chardet-3.0.4 click-6.7 dominate-2.3.1 elasticsearch-6.3.1 guess-language-spirit-0.5.3 gunicorn-19.7.1 idna-2.7 itsdangerous-0.24 psycopg2-2.7.3.1 python-dateutil-2.7.3 python-dotenv-0.9.1 python-editor-1.0.3 pytz-2018.5 requests-2.19.1 six-1.11.0 urllib3-1.23 visitor-0.1.3
remote:
remote: -----> Discovering process types
remote:
Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:
Done: 60.6M
remote: -----> Launching...
remote:
Released v15
remote:
https://flask-mymicroblog.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/flask-mymicroblog.git
* [new branch]
master -> master
PS:如果出现如下错误
error: src refspec deploy does not match any.
error: failed to push some refs to 'https://git.heroku.com/flask-mymicroblog.git
则可以依次运行如下命令解决:
$ touch readme
$ git add .
$ git commit -m "init"
$ git push heroku master
原因可能是:分支名称不正确。上述git push命令中第一个参数heroku是远程仓库的名字,第二个参数是refspec(通常是一个分支)
参考文章:stackoverflow
我们在git push
命令中使用的heroku
标签是在创建应用程序时由Heroku CLI自动添加的远程。deploy:master
参数意味着我将代码从deploy
分支引用的本地存储库推送到Heroku存储库的master
分支。当使用自己的项目时,可能会使用命令git push heroku master
推送您的本地master分支。由于这个项目的结构方式,我正在推动一个不是的分支master,但是Heroku方面的目标分支总是需要成为master
,这是Heroku接受部署的唯一分支。
就是这样,应用程序现在应该部署在创建应用程序的命令输出中给出的URL。在本人的例子中,URL是https://flask-mymicroblog.herokuapp.com,因此我需要键入浏览器地址栏以访问应用程序。
如果要查看正在运行的应用程序的日志条目,请使用heroku logs
命令。如果由于任何原因应用程序无法启动,这可能很有用。如果有任何错误,那些将在日志中。
heroku logs --tail
查看服务器端的日志
部署应用程序更新
要部署新版本的应用程序,只需使用新代码运行一个git push
新命令即可。这将重复部署过程,使旧部署脱机,然后将其替换为新代码。Procfile
中的命令将作为新部署的一部分再次运行,因此在此过程中将更新任何新的数据库迁移或转换。
参考:
作者博客
源代码
如需转载请注明出处。
最后
以上就是沉默小伙为你收集整理的18 Flask mega-tutorial 第18章 在Heroku上部署创建Heroku账户安装Heroku CLI设置Git创建一个Heroku应用程序短暂的文件系统使用Heroku Postgres数据库登录到stdout编译翻译Elasticsearch Hosting更新requirementsProcfile部署应用程序部署应用程序更新的全部内容,希望文章能够帮你解决18 Flask mega-tutorial 第18章 在Heroku上部署创建Heroku账户安装Heroku CLI设置Git创建一个Heroku应用程序短暂的文件系统使用Heroku Postgres数据库登录到stdout编译翻译Elasticsearch Hosting更新requirementsProcfile部署应用程序部署应用程序更新所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复