0%

Heroku 部署 Python 应用(Django)

记一次部署云端 Django 应用


Heroku 准备

  1. 访问 https://heroku.com 注册 Heroku 账号

  2. 安装 Heroku CLI,该工具用来后续的部署以及管理 Heroku 账号中托管的应用程序

    1
    scoop install heroku-cli
  3. 使用命令行登录 Heroku 账号,让本机在执行 heroku 命令时知道所对应的 Heroku 账号

    1
    heroku login

    该命令会打开浏览器进行 Heroku 账号的登陆验证,之后就可以使用 heroku 管理自己的账号及应用程序,认证信息存储在用户家目录下的 _netrc 文件中

    1
    2
    heroku apps  # 查看账户部署的所有应用
    git clone https://git.heroku.com/<app_name>.git # 克隆应用程序app_name的源代码到本地

    如果不先 heroku login 是无法成功 git clone 仓库,会报如下错误

    Do not authenticate with username and password using git.
    Run heroku login to update your credentials, then retry the git command.

为部署到 Heroku 对 Django 项目修改

可以使用官方教程中配置好的 Django 项目

1
2
git clone https://github.com/heroku/python-getting-started.git
cd python-getting-started

如果使用该项目则直接转至部署,如果是自己的 Django 项目,则可以参考官方项目进行以下修改

  • 安装必要的包

    1
    2
    pip install gunicorn  # 一个服务器软件,heroku使用它做web服务器
    pip install django-heroku
  • 项目根目录增加 requirements.txt 文件

    1
    pip freeze > requirements.txt

    部署到 Heroku 时,Heroku 使用该文件安装依赖 pip install -r requirements.txt 并运行应用

    Heroku recognizes an app as a Python app by looking for key files. Including a requirements.txt in the root directory is one way for Heroku to recognize your Python app.

  • 项目根目录增加 runtime.txt 文件

    1
    2
    3
    python --version  # 查看本机使用的python版本
    Python 3.8.2
    echo python-3.8.2 > runtime.txt
  • 为部署到 Heroku 而修改项目 settings.py

    1
    2
    3
    import django_heroku
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
    django_heroku.settings(locals())
  • 为部署到 Heroku 而修改项目 wsgi.py

  • 项目根目录增加 Procfile 文件

    1
    echo "web: gunicorn <project_name>.wsgi --log-file -" > Procfile  # <project_name>替换为包含wsgi.py文件的项目名

    这行配置让 Heroku 将 gunicorn 用作服务器,并使用 ./<project_name>/wsgi.py 中的设置来启动应用程序。标志 log-file 告诉 Heroku 应将哪些类型的事件写入日志

    Use a Procfile, a text file in the root directory of your application, to explicitly declare what command should be executed to start your app.

    gunicorn 不能在 Windows 上运行,为了可以 heroku local 本地验证应用程序,需额外增加 Procfile.windows 文件

    1
    echo "web: python manage.py runserver 0.0.0.0:5000" > Procfile.windows
  • 创建用于存储静态文件的目录

    在 Heroku 上,Django 搜集所有的静态文件,并将它们放在一个地方,以便能够高效地管理它们。在项目配置文件的目录下新建 static/ 目录,并添加占位文件

    1
    2
    mkdir .\<project_name>\static  # <project_name>替换为包含settings.py文件的项目名
    echo "placeholder" > .\<project_name>\static\placeholder.txt
  • 让 Heroku 在本地运行程序并检查

    首先解决一个 bug,上述的 > 重定向在 PowerShell 中执行,生成的文件编码为 UTF-16 LE(如果在 CMD 中执行,生成的文件编码则为 UFT-8),执行 heroku local 会出现错误。所以先确保 requirements.txtplaceholder.txtProcfileProcfile.windowsruntime.txt 文件的编码为 UTF-8,然后操作如下

    1
    2
    python manage.py collectstatic  # 收集生成静态文件
    heroku local web -f Procfile.windows # 使用指定的Procfile本地运行

    浏览器访问:http://localhost:5000/

部署

  1. 使用 Git 跟踪项目文件

    1
    git init

    创建 .gitignore 文件,内容如下

    1
    2
    3
    4
    5
    6
    ll_env/
    *.pyc
    __pycache__/
    staticfiles
    .env
    *.sqlite3

    提交一个版本:git add . git commit -m,查看远程仓库 git remote -v 此时为空

  2. Heroku 创建应用并部署

    1
    heroku create

    创建空的 App,查看远程仓库 git remote -v 此时已关联到该 App(如果先创建 heroku create,后 git init,则 git push 时出错,无法推送到该关联的 App)

    1
    git push heroku master

使用 Heroku CLI 管理部署的应用

1
2
3
4
5
6
7
8
9
10
11
heroku open  # 打开该仓库关联的App
heroku logs --tail # 查看该App的访问日志
heroku ps # check how many dynos are running
heroku ps:scale web=1 # 将该App中类型为web的dynos的数量改为1(如果为0则访问App出错)
heroku run python manage.py shell # 开启一个类型为run的dynos运行python shell
heroku run bash # 开启一个类型为run的dynos运行bash shell
heroku addons # 查看App使用的附件(Heroku默认使用Postgres数据库,数据库也是一个addons)
heroku pg # manage postgresql databases
heroku config:set TIMES=2 # set the config var on Heroku(也可以在项目根目录创建.env文件并写入TIMES=2
heroku config # Listing the config vars for your app will display the URL that your app is using to connect to the database
heroku apps:destroy --app <AppName> # 将指定项目<AppName>从Heroku删除

上述部署的应用虽然有数据库的功能,但数据库为空,为了能访问并使用数据库,需要生成新的表,执行以下命令

1
2
heroku run python manage.py migrate
heroku pg:psql # 如果本地机器安装了Postgres,则可以执行这个命令连接数据库

改进 Heroku 部署

  1. 在 Heroku 上创建超级用户

    1
    2
    3
    4
    heroku run bash
    ls
    python manage.py createsuperuser
    exit
  2. 创建对用户友好的 URL

    Heroku 默认创建的应用名字为两个随机单词加一串数字,不够友好,执行以下命令修改 App 的名字

    1
    heroku apps:rename <NewAppName>
  3. 确保项目安全

    修改项目 settings.py

    1
    2
    ALLOWED_HOSTS = ['NewAppName.herokuapp.com']  # NewAppName替换为应用程序名字
    DEBUG = False
  4. 创建自定义错误页面

    在项目配置文件的目录下新建 templates/ 目录,并添加 404.html 500.html

    使用 Django 的快捷函数 get_object_or_404() 从数据库获取请求的对象,替换 Models.objects.get() 方法

  5. 继续开发

    1
    2
    3
    4
    5
    6
    ...
    # 修改了一些文件
    git add .
    git commit -m "commit message"
    git push heroku master
    heroku run python manage.py migrate # 如果迁移了数据库则执行

参考

Getting Started on Heroku with Python
python编程:从入门到实践