# 在 Render.com 上部署 Django 4.2

- Link: https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/
- Published: 2023-06-26T12:15:15+08:00
- Author: 白宦成

文章目录

 [Toggle](https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/#)

 * [初始化项目](https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/#%e5%88%9d%e5%a7%8b%e5%8c%96%e9%a1%b9%e7%9b%ae)
 * [编写逻辑代码](https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/#%e7%bc%96%e5%86%99%e9%80%bb%e8%be%91%e4%bb%a3%e7%a0%81)
 * [配置项目以支持 Render 的服务端环境。](https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/#%e9%85%8d%e7%bd%ae%e9%a1%b9%e7%9b%ae%e4%bb%a5%e6%94%af%e6%8c%81_render_%e7%9a%84%e6%9c%8d%e5%8a%a1%e7%ab%af%e7%8e%af%e5%a2%83%e3%80%82)
    - [1. 从环境变量中读取 Secret Key](https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/#1_%e4%bb%8e%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f%e4%b8%ad%e8%af%bb%e5%8f%96_secret_key)
    - [2. 在环境变量中读取 Debug 配置](https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/#2_%e5%9c%a8%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f%e4%b8%ad%e8%af%bb%e5%8f%96_debug_%e9%85%8d%e7%bd%ae)
    - [3. 从环境变量中读取可用域名](https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/#3_%e4%bb%8e%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f%e4%b8%ad%e8%af%bb%e5%8f%96%e5%8f%af%e7%94%a8%e5%9f%9f%e5%90%8d)
 * [配置 render.yml 来支持 Render BluePrint](https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/#%e9%85%8d%e7%bd%ae_renderyml_%e6%9d%a5%e6%94%af%e6%8c%81_render_blueprint)
    - [build.sh](https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/#buildsh)
    - [render.yml](https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/#renderyml)
 * [总结](https://www.ixiqin.com/2023/06/26/deploying-django-4-2-on-render-com/#%e6%80%bb%e7%bb%93)

最近在写 Linux 中国的翻译工具的时候，后端我使用的是 Django，版本则选择了 Django 
4.2，Python 3.11。在部署 Django 的时候，我选择使用 Render.com 来部署。 不过，在部署
的时候，我遇到了一些问题，Render 官方提供的 [Getting Started with Django on Render](https://render.com/docs/deploy-django)
会部署错误，所以有了今天这篇文章， 告诉大家如何把最新的 Django 4.2 部署到 Render
上。

## 初始化项目

Render 没有使用 pip，而是使用 [Poetry](https://python-poetry.org/) 来管理 Django
项目的，因此，你需要使用 [Poetry](https://python-poetry.org/) 来完成项目的初始化。

    ```php
    poetry init #初始化 Poetry 的 配置文件
    poetry add django gunicorn # 添加依赖 Django 和 gunicorn
    poetry run django-admin startproject linuxondjango .
    Code language: PHP (php)
    ```

初始化项目基本上就是用 Poetry 替代 pip ，这里没有需要针对 Render 特化的部分，就不做
过多的介绍。

## 编写逻辑代码

当你完成了项目的初始化之后，可以编写你自己的业务逻辑代码，这部分不再多讲，可以正常
开发使用。

## 配置项目以支持 Render 的服务端环境。

### 1. 从环境变量中读取 Secret Key

Django 使用 Secret Key 作为 Session 加密等一些加密场景的 Salt 和 Seed，所以在 Django
Admin 创建项目时，会默认生成一个 Session。不过出于安全考虑，最好不要将其放在代码
中，而是在服务端生成后，通过环境变量来存储，避免代码泄露后导致的 session 被解密。

你需要在 `settings.py` 中，添加如下代码，来替代默认的 key。

    ```php
    import os
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = os.environ.get('SECRET_KEY', default='your secret key')
    Code language: PHP (php)
    ```

### 2. 在环境变量中读取 Debug 配置

Render 会自动配置一些环境变量，因此，你可以直接通过判断当前环境上下文来确认当前是否
是在 Render 的服务端，如果不在，则配置 Debug 为 True，来解决线上不使用 Debug 模式
的需求。

    ```javascript
    DEBUG = 'RENDER' not in os.environ
    Code language: JavaScript (javascript)
    ```

### 3. 从环境变量中读取可用域名

Django 是有域名配置的，非配置域名，无法访问当前应用，因此，你需要在 Render 当中读
取域名，来确保可以正常访问。当然，如果你自己配置了自己的域名，也可以直接手动写在`
ALLOWED_HOSTS` 当中。

    ```javascript
    ALLOWED_HOSTS = []

    RENDER_EXTERNAL_HOSTNAME = os.environ.get("RENDER_EXTERNAL_HOSTNAME")
    if RENDER_EXTERNAL_HOSTNAME:
        ALLOWED_HOSTS.append(RENDER_EXTERNAL_HOSTNAME)

    Code language: JavaScript (javascript)
    ```

## 配置 render.yml 来支持 Render BluePrint

你可以直接复制下面的内容，来作为你的项目的启动配置。其中 build.sh 为构建项目的配置。

### build.sh

build.sh 当中最重要的是重新安装 Poetry，因为我使用的是 Python 3.11.4， 和 Render
默认的 Python 3.7 不匹配，所以没办法直接用默认的 Poetry，需要自动手动升级 Poetry。

    ```php
    #!/usr/bin/env bash
    # exit on error
    set -o errexit

    pip install --upgrade pip; pip install poetry;  # 重新安装一下最新的 Poetry，因为默认的 Poetry 的版本比较低。
    poetry install

    python manage.py collectstatic --no-input
    python manage.py migrate
    Code language: PHP (php)
    ```

### render.yml

Render 当中，最重要的是 `startCommand` 和 `PYTHON_VERSION` ，startCommand 这里是
我使用 gunicorn 来启动 Django 应用，而 `PYTHON_VERSION` 则是用来设定具体的 Python
版本，这里我根据我自己的需求，选择了 Python 3.11.4。

    ```php
    databases:
      - name: linuxondjango-db
        databaseName: mysite
        user: mysite
        plan: free

    services:
      - type: web
        name: linuxondjango
        plan: free
        runtime: python
        buildCommand: "./build.sh"
        startCommand: "gunicorn linuxondjango.wsgi:application"
        envVars:
          - key: DATABASE_URL
            fromDatabase:
              name: linuxondjango-db
              property: connectionString
          - key: SECRET_KEY
            generateValue: true
          - key: WEB_CONCURRENCY
            value: 4
          - key: PYTHON_VERSION # 这里的 python version 是用来指定 Python 版本的，比如这里我用的是 3.11.4。
            value: 3.11.4
    Code language: PHP (php)
    ```

## 总结

Render 的教程总体来说没啥大问题，但是在一些小的点上，需要你自己简单 Hack 一下，比如
需要自己升级一下 Poetry、设定 Python 版本。如果你也在用高版本的 Django & Render，
希望这篇文章 可以帮到你。
