使用Docker将Django部署到Heroku

开始

因为除了Python和Conda之外,我没有其他任何知识,所以我花了很多时间才搭建好了Django、Docker和Heroku环境。

这次我们将接收化合物的SMILES输入,并展示该化合物。

参考的網站

在Docker上使用Anaconda安装的Django,并在Heroku上运行
将使用Conda环境在Heroku上部署开发的应用的方法
Django入门指南

环境

Windows 11
窗口 11

Anaconda
安纳康达

VScode
视角编码

使用Docker创建容器。

请参考在Docker上使用Anaconda安装的Django并在Heroku上运行的方法,您需要参考2、3、4、5步骤。在进入conda的虚拟环境后,请安装与Anaconda创建Django环境相同的软件。

最後,使用类似于docker commit django djangotest:1.0.0的命令将docker保存为适当的版本。

2. 使用anaconda建立django环境。

可以使用任何名字,在Windows 11环境下创建Django环境(省略Anaconda环境的创建)。如果需要,您可以安装RDKit,但对于普通的应用程序来说是不必要的。

(base)       > conda create -n django_env python==3.7
(base)       > conda activate django_env
(django_env) > conda install django=3.* -c conda-forge
(django_env) > conda install -c rdkit -c conda-forge rdkit
(django_env) > conda install django-heroku -c conda-forge

接下来要使用Django创建应用程序。

项目名称:wepapps,应用名称:chem_app将被制作。

(django_env) > mkdir django_sample
(django_env) > cd django_sample
(django_env) > mkdir webapps
(django_env) > cd webapps
(django_env) > django-admin startproject webapps .
(django_env) > python manage.py startapp chem_app

django-admin startproject webapps .不需要与 mkdir webapps 相同的名称。

我們將在這裡確認一下執行 “python manage.py runserver 0.0.0.0:8000” 的情況。

制作应用程序

在django_sample/webapps/webapps/setting.py文件中,进行以下更改。


# herokuでアクセスできるようにしておく
ALLOWED_HOSTS =  ['127.0.0.1', '.herokuapp.com']

~

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [  
            # htmlを読み込めるようにしておく。
            os.path.join(BASE_DIR, 'chem_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',
            ],
        },
    },
]

下一步,将django_sample/webapps/webapps/urls.py更改如下:

from django.conf.urls import url, include
from django.contrib import admin
from django.urls import path
import chem_app.views as chem # django_sample/webapps/chem_app/views.pyをchemとして扱っています

urlpatterns = [
    path('admin/', admin.site.urls),
    path('smiles2picture/', chem.smiles2pic, name='smiles2picuture'),
    path('smiles2picture/result', chem.smiles2pic_result, name='s2p_res'),
]

将django_sample/webapps/chem_app/views.py文件更改如下。

from django.shortcuts import render
from django.http import HttpResponse  # Load Module
from rdkit import Chem
from rdkit.Chem import Draw
import base64
from io import BytesIO
from PIL import Image
import os

def pil_to_base64(img, format="jpeg"):
    buffer = BytesIO()
    img.save(buffer, format)
    img_str = base64.b64encode(buffer.getvalue()).decode("ascii")

    return img_str

def smiles2pic(request):
    return render(request,"smiles2picture.html")

def smiles2pic_result(request):
    # SMILESから画像を生成する
    smiles = request.POST.get("SMILES", None)
    print(f"smiles:{smiles}")
    m = Chem.MolFromSmiles(smiles)
    img = Draw.MolToImage(m,size=(300, 300))
    img_base64 = pil_to_base64(img, format="png")
    return render(request, 'chemtest.html',{"title":smiles,"img":img_base64})

请添加以下内容到django_sample/webapps/chem_app/templates/smiles2picture.html和django_sample/webapps/chem_app/templates/chemtest.html中。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Smiles2Picture</title>
</head>
<body>
    <p>化合物のSMILESを入力</p>
    <form action="/smiles2picture/result" method="POST">
        {% csrf_token %}
        <input type="text" name="SMILES">
        <input type="submit" value="送信">
    </form>
</body>
</html>
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>{{ title }}</title>
    </head>
    <body>
        <img src="data:image/png;base64,{{img}}">
    </body>
</html>

在这里,我们将由rdkit生成的图像转换为base64格式,直接传递到html文件中,而不是保存为文件,这是因为Heroku无法保存并重复使用文件。对于静态文件情况下,似乎需要在Django上进行一些复杂的操作。

在这里再次输入 “python manage.py runserver 0.0.0.0:8000” 并访问 http://127.0.0.1:8000/smiles2picture/ 来确认是否正常运行。

生成Dockerfile。

在django_sample文件夹下设置Dockerfile。

# 自分のdockerイメージに書き換える
FROM djangotest:1.0.2

SHELL ["/bin/bash", "-c","-l"]

RUN echo "chmod 777 /root/.pyenv/versions/miniconda3-latest/etc/profile.d/conda.sh" >> ~/.bashrc
RUN echo "source /root/.pyenv/versions/miniconda3-latest/etc/profile.d/conda.sh" >> ~/.bashrc
RUN echo "conda activate base" >> ~/.bashrc
RUN echo "conda activate django" >> ~/.bashrc
RUN echo "conda env list" >> ~/.bashrc

ENV PATH /root/.pyenv/versions/miniconda3-latest/envs/django/bin:$PATH

COPY webapps/ ~/webapps
WORKDIR ~/webapps
CMD gunicorn --bind 0.0.0.0:$PORT webapps.wsgi

5. 引入Heroku。

需要安装git。
从官方网站中选择适合您环境的版本进行安装。
然后安装Heroku CLI。在Windows上,可以相对轻松地完成该步骤。

6. 在Heroku上进行推送。

heroku container:login
heroku create myappname
heroku container:push web -a myappname
heroku container:release web -a myappname

应该已经在Heroku上应用了。访问自己创建的网站并确认是否正常运行。

如果不行的话,可以通过以下命令在Heroku上查看日志:heroku logs –tail -a myappname。

我会将我创建的网站临时公开。https://mychemodel2.herokuapp.com/smiles2picture

最终目录结构的补充说明

DJANGO_SAMPLE
│  Dockerfile
│
└─webapps
    │  db.sqlite3
    │  manage.py
    │
    ├─chem_app
    │  │  admin.py
    │  │  apps.py
    │  │  models.py
    │  │  tests.py
    │  │  views.py
    │  │  __init__.py
    │  │
    │  ├─migrations
    │  │      __init__.py
    │  │
    │  ├─static
    │  │  └─chem_app
    │  │      └─images
    │  │          └─  test.png
    │  │
    │  └─templates
    │         chemtest.html
    │         index.html
    │         smiles2picture.html
    │  
    └─webapps
        │  asgi.py
        │  settings.py
        │  urls.py
        │  wsgi.py
        └─ __init__.py
广告
将在 10 秒后关闭
bannerAds