如何将 Django 服务器单独部署到 heroku 上

Django server 单独部署 heroku

视频资源

部署步骤的 checklist

  • 他进行的步骤我从视频中找到了他的 github 并把步骤清单列在这里:
- Copy the project seperately
- Go to 'Getting Started on Heroku with Python'
- Create an Heroku account
- install pipenv
- Install git ( check git --version)
- Install Heroku CLI
- Login heroku
- Create a virtual enviroment
- Run manage.py not gonna run - pip freeze nothing installing
- Check which version django,requests you have and install it
- Run manage.py and then stop it
- Go to django heroku
- Create a Procfile and
- Install django-heroku
- Add stuff to settings.py file
- Install guincorn
- pip freeze > requirements.txt
- heroku create attreyaweb (to create an app on heroku)
- git status git commands (git push heroku master)
- Open up the website
- Admin panel not working. heroku run bash. Migrations

准备工作

创建账号

  • 要创建一个 heroku 账号,点此处 这是一个平台,类似于 github,也是通过 git 进行管理,所以要注册一个账号,最终也是通过 git 命令将服务器部署到 heroku 上

    在这里插入图片描述

使用 pipenv / anaconda 创建python 和 Django 运行环境

  • 他这里提到的 install pipenv 的原因是想通过 pipenv 创建一个虚拟环境,这个虚拟环境也可以通过 anaconda 来创建;虚拟环境的作用主要是保护你本地 python 环境,虚拟环境可以在不影响你本地所有东西的情况下创建一个隔离的环境,在这里面你可以创建任意的 Python 运行环境,也可以随时将这个虚拟环境删除
    • 我用的命令是 conda create -n server python=3.9 也就是创建了一个名为 server 的 python 版本是 3.9 的虚拟环境;
    • python 版本的选择一定要非常慎重,因为目前 heroku 最新的版本只支持几种 python 版本,所以如果你python 版本选错了后面部署的时候他无法在 heroku 那边完成部署,还会报版本错误。
    • 至于它现在支持的版本,可以去这里查;注意你的 Heroku-20 还是 Heroku-22,我部署的时候是 Heroku-22 所以直接选择了 3.9 的 python
      在这里插入图片描述

安装 git

  • 安装 git,这个主要是保证你的本地有 git 能够将代码 push 到远端仓库,这个只要是用过 github 或者 gitlab 的小伙伴应该都是ok 的

安装 heroku cli

  • 创建一个 heroku 的脚手架 heroku cli,这个安装的方法 官网 也给了
    • 我是苹果系统,所以采用第一种方式安装了 heroku 的脚手架在这里插入图片描述
    • 登录 heroku 这个步骤我们后面在进行,这里先不急
    • 创建虚拟环境我们也已经做完了,就是用 anaconda 创建的;这一步其实应该是写代码之前的配环境环节,但如果你到了这里,很显然你已经代码写完,如果你不是用 heroku 支持的 python 版本开发的程序,你最好用 conda 重新配一个环境,然后把代码复制粘贴到新环境里调试一下看看能不能正常运行。

安装 gunicorn

  • 注意: 一定在自己的环境中 pip install gunicorn 这个虽然在你本地的环境中用不到,你本地运行服务器也没有用,但是当你上传代码到 heroku,他会使用 gunicorn 来帮你部署,所以 gunicorn 必须要出现在你的环境中,这样才能随着下一步 freeze 操作生成的 requirements.txt 一起 push 到远端 heroku 仓库

生成 requirements.txt 文件

  • 下一步的 pip freeze > requirements.txt 的作用主要是将你所有的 python 环境输出到 requirements.txt 这个文件里面,这个文件记录了你所有运行代码需要的 library 的列表,部署的时候会从这里面读取然后在远程给你配置部署环境,所以非常重要。

    这一步还有一点非常重要:如果你的 requirements.txt 中出现了这种问题,一定要注意,将后面的内容删掉,手动换成版本号,和其他的那些写法一样,你可以用 pip list 来检查当前环境下所有 library 的版本,唯一正确的写法就是 package名称==版本号

    在这里插入图片描述

如果各位觉得没有必要在 heroku 上安装这么多基础环境,而是想通过手动指定几个环境,那么一定要注意, 不要少上传环境,否则很难排查,尤其是这么几个,如果你没写到 requirements.txt 中,你最后会 build 成功但是无法启动应用
在这里插入图片描述

  • 切记,切记!!!!

手动创建 Procfile 文件

  • 接下来需要创建一个 Procfile 文件,这个文件 没有后缀!没有后缀!没有后缀!(mac 容易将无后缀的文件默认是 txt 格式,一定要注意这个问题,这个文件是真正的无后缀的)
  • Procfile 文件中写的内容是 web: gunicorn myproject.wsgi 这里的 myproject 替换成你的文件的名称,比如我这个服务器中,就应该写成web: gunicorn djangoServer.wsgi 这个文件对于 heroku 的部署非常重要,否则部署一定会失败
  • 这个文件的位置如下:

    在这里插入图片描述

安装 django-heroku

  • 再接着就是安装 django-heroku ,安装命令 pip install django-heroku

    • 如果这一步报下面的错,说明在安装 psycopg2 的时候发生了问题:
      在这里插入图片描述
    • 解决方法是 mac osbrew install postgresql
    • 然后重新运行这个命令 pip install django-heroku
    • 当然也有可能是其他问题
  • 接下啦,按照官网的指示对 setting.py 的内容进行设置,官网推荐你怎么写你就怎么写

    在这里插入图片描述

    • 根据官网推荐的这个文件去修改你 Django 中原本的 settings.py 文件,
    • 我把自己的 settings.py 也贴在这里,大家可以参考,尤其注意的是 ALLOWED_HOSTS = ["*"] 这句话一定不要漏:
    """
    Django settings for djangoServer project.
    
    Generated by 'django-admin startproject' using Django 3.2.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/3.2/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/3.2/ref/settings/
    """
    import datetime
    from pathlib import Path
    import dj_database_url
    import os
    from django.test.runner import DiscoverRunner
    from pathlib import Path
    
    # Build paths inside the project like this: BASE_DIR / 'subdir'.
    BASE_DIR = Path(__file__).resolve().parent.parent
    
    """
    Heroku
    """
    IS_HEROKU = "DYNO" in os.environ
    SECRET_KEY = "CHANGE_ME!!!! (P.S. the SECRET_KEY environment variable will be used, if set, instead)."
    
    if 'SECRET_KEY' in os.environ:
        SECRET_KEY = os.environ["SECRET_KEY"]
    
    # Generally avoid wildcards(*). However since Heroku router provides hostname validation it is ok
    if IS_HEROKU:
        ALLOWED_HOSTS = ["*",
                         're-echidna-django.herokuapp.com']
    else:
        ALLOWED_HOSTS = ['*','re-echidna-django.herokuapp.com']
    
    # SECURITY WARNING: don't run with debug turned on in production!
    if not IS_HEROKU:
        DEBUG = True
    
    # Application definition
    
    
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = 'django-insecure-pm42jjw)=bp1*8m3+vd=#kfnbe99213px8yb9*_7^%r6d$wlii'
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = ["*"]
    
    
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'RE_app.apps.AppConfig',
        'corsheaders'
    ]
    
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        # 'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.common.CommonMiddleware'
    ]
    
    CORS_ORIGIN_ALLOW_ALL = True
    CORS_ALLOW_CREDENTIALS = True
    
    ROOT_URLCONF = 'djangoServer.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'RE_app', 'templates')]
            ,
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 'djangoServer.wsgi.application'
    
    
    # Database
    # https://docs.djangoproject.com/en/3.2/ref/settings/#databases
    
    DATABASES = {
        'default': {
            # 'ENGINE': 'django.db.backends.sqlite3',
            # 'ENGINE': None,
            # 'ENGINE': 'djongo',
            # 'NAME': BASE_DIR / 'db.sqlite3',
            # 'NAME': 'RE_ECHIDNA',
            # 'ENFORCE_SCHEMA': False,
            # 'CLIENT': {
            # 'host': 'mongodb+srv://<username>:<password>@<atlas cluster>/<myFirstDatabase>?retryWrites=true&w=majority'}
            # 'host': 'mongodb+srv://ZIYUQ:<password>@cluster0.366apt7.mongodb.net/?retryWrites=true&w=majority'}
        }
    
    }
    
    
    
    
    # Password validation
    # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    
    # Internationalization
    # https://docs.djangoproject.com/en/3.2/topics/i18n/
    
    LANGUAGE_CODE = 'en-us'
    
    TIME_ZONE = 'UTC'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/3.2/howto/static-files/
    
    STATIC_URL = '/static/'
    
    # Default primary key field type
    # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
    
    DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
    
    
    """
    Heroku
    """
    # Test Runner Config
    class HerokuDiscoverRunner(DiscoverRunner):
        """Test Runner for Heroku CI, which provides a database for you.
        This requires you to set the TEST database (done for you by settings().)"""
    
        def setup_databases(self, **kwargs):
            self.keepdb = True
            return super(HerokuDiscoverRunner, self).setup_databases(**kwargs)
    
    
    # Use HerokuDiscoverRunner on Heroku CI
    if "CI" in os.environ:
        TEST_RUNNER = "djangoServer.settings.HerokuDiscoverRunner"
    
    
    # Default primary key field type
    # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
    
    DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
    
    # print(os.path.join(BASE_DIR, 'RE_app', 'templates'))
    

手动创建 runtime.txt 文件规定 python 的部署版本

  • 部署前的最后一步,是在文件夹中创建一个 runtime.txt 的文本文件,里面写上你希望远端使用的 python 的版本:

    在这里插入图片描述

    • 说明一下,这里我本地其实 python 是 3.9.0 但是我大胆判断,远端的 3.9.15 应该和 3.9.0 是兼容的,而且远端只支持那么几种 python 版本,我只能选择 3.9.15 因此我这里可以告诉你,本地 3.9 的系列的 python 应该都不影响部署。

正式部署

  • 前面是所有的准备工作,现在可以开始部署了:
    • 进入你的项目文件夹,以我自己为例,我进入最外层的 djangoServer 文件夹即可:
      在这里插入图片描述

在终端登录 heroku

  • heroku login 登录到你自己的 heroku 账号,他会弹出一个界面,登录即可。(如果你使用了 vpn ,执行这一步的时候尽量断掉,否则有可能说你 ip 地址不一致)

终端创建 heroku 仓库

  • 这时候创建一个 heroku 仓库 heroku create xxxxx 任意名字,比如我 heroku create re-echidna-dataportal 他就会在 heroku 你的账号下面创建一个库。
  • 由于我们是直接在本地一个非空的文件夹中创建仓库,所以接下来我们要把这个本地文件夹 init 一下,然后关联上远端的仓库。具体操作也可以根据自己项目中的部署指导来操作(但是官网给出的操作步骤是从零构件一个远端库然后拉到本地,在这个库中你完成代码任务并 push 到远端,如果你是按照我的方法本地已经写完了代码,项目文件夹已经不为空了,就按我的方法执行):
    在这里插入图片描述
    在这里插入图片描述

init 本地项目文件夹并与远端创建的 heroku 关联

  • git init
  • heroku git:remote -a xxxx xxx 是刚才 create 的名称
  • 到这里,我们已经将本地的文件和远端的仓库建立联系了

将本地项目 push 到 heroku 完成部署

  • git add . 将本地所有的文件提交到本地仓库
  • git commit -am "随便说一句话"
  • git push heroku master 这句话一执行,远端会根据你的 requirements 准备运行环境,并通过 runtime 选择 python 版本并检查是否支持,最后通过 procfile 来部署
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暖仔会飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值