在Heroku上使用Django Rest Framework后端部署Angular 4前端

时间:2017-09-10 13:45:29

标签: django angular heroku deployment django-rest-framework

我使用Angular 4(使用角度CLI)和后端使用Django和Django Rest Framework构建了前端。

开发环境的设置方式使得静态资产,HTML,JS等都是Angular应用程序的一部分。这个角度应用程序在CLI上运行的服务器上运行,位于localhost:4200,并且它通过一系列HTTP调用通过CORS与另一个框架后端进行通信,DRF API在另一个本地主机上运行:8000仅用于获取和服务信息。

如何在Heroku上将其部署为生产就绪型应用程序? heroku指南说明了如何单独部署Django应用程序或单独部署Angular应用程序(在节点服务器上运行)。我是将它们部署为两个单独的实例,还是将它们组合在一起。如果是这样,我该怎么做呢?

1 个答案:

答案 0 :(得分:3)

此解决方案与Heroku上如何执行此操作的请求不匹配,但是在@pdfarhad的请求下完成。

首先关于我曾经主持过的东西,我的域名是在Godaddy注册的,并且指向我在Digitalocean创建的服务器(Droplet)。注意到godaddy上的DNS服务器指向数字扫描,ns1.digitalocean.comns2.digitalocean.comns3.digitalocean.com。然后在digitalocean上,在网络选项卡上创建了两个A record,它们都指向我创建的服务器,一个是example.com,另一个是api.example.com

完成后,当您创建新的Droplet时,将通过电子邮件发送root用户的密码,然后执行以下操作:

# ssh root@<IPADDRESSOFSERVER>
# sudo apt-get update
# sudo adduser jupiar
# sudo usermod -aG sudo jupiar
# su - jupiar
$ sudo apt-get install nginx

此时,您应该可以导航到IPADDRESS并查看nginx登录页面,您可能需要等待一段时间才能让godaddy和digitalocean通过输入example.com,我认为有一半一天过去了,直到名称服务器全部同步并填充。

现在,我只是在我的本地机器上设置无密码ssh:

$ ssh-keygen (no passphrase)
$ cat ~/.ssh/id_rsa.pub (then copy this)

现在在服务器上:

$ mkdir ~/.ssh
$ chmod 700 ~/.ssh
$ nano ~/.ssh/authorized_keys (paste the rsa you copied)
$ chmod 600 ~/.ssh/authorized_keys
$ sudo nano /etc/ssh/sshd_config
    | Make sure:
    | PasswordAuthentication no
    | PubkeyAuthentication yes
    | ChallengeResponseAuthentication no
$ sudo systemctl reload sshd
$ exit

现在您应该可以在没有密码的情况下ssh到您的服务器。

我使用anaconda python,因为我做了很多数据科学,所以:

$ wget https://repo.continuum.io/archive/Anaconda3-5.0.0.1-Linux-x86_64.sh
$ bash https://repo.continuum.io/archive/Anaconda3-5.0.0.1-Linux-x86_64.sh
    | installed to /home/jupiar/anaconda3, auto append path to .bashrc
$ . .bashrc
$ source .bashrc

现在,因为过去我在使用python virtualenvs运行linux supervisor时遇到了一些麻烦,我只是全局安装。 uwsgi主要是在C语言中,所以你需要一些包来编译它。

$ sudo apt-get install build-essential python-dev python3-dev
$ pip install uwsgi

现在,创建一个git存储库,你可以在服务器上创建一个,但我更喜欢使用github,因为它提供了很多有用的工具,并且是项目贡献者之间协作的好地方,所以创建一个私有存储库在github上,然后在你的本地机器上:(第三行是因为我使用Mac)

制作一个新文件夹,并将所有内容放在那里

$ echo "# example" >> README
$ git init
$ find . -name .DS_Store -print0 | xargs -0 git rm -f --ignore-unmatch
$ echo ".DS_Store" >> .gitignore
$ git add .
$ git commmit -m "first commit"
$ git remote add origin https://github.com/<GITUSERNAME>/<REPONAME>.git
$ git push -u origin master

所以,再次在本地机器上,设置一个新的角度4应用程序与scss样式和跳过使它成为一个git repo,因为它不会在github上正确显示,回购内部回购等......:

$ ng new frontend --style=scss --skip-git

而且,我们将暂时保留应用程序,只需记住服务器需要一个dist文件夹,您可以在前端文件夹中使用提前执行此类操作。 :

$ ng build --aot -prod

现在再次在本地机器上创建Django Rest Framework后端:

$ conda create -n exampleenv python=3.6 anaconda
$ source activate exampleenv
(exampleenv)$ pip install django
(exampleenv)$ pip install djangorestframework
(exampleenv)$ pip install django-cors-headers
(exampleenv)$ django-admin startproject backend
(exampleenv)$ cd backend
(exampleenv)$ django-admin startapp api
(exampleenv)$ python manage.py migrate
(exampleenv)$ python manage.py createsuperuser

现在,为了让最小的休息框架起作用,我们需要:

settings.py添加到INSTALLED APPS

'rest_framework',
'corsheaders',
'api',

settings.py中添加MIDDLEWARE 顶部

'corsheaders.middleware.CorsMiddleware',

settings.py添加:

CORS_ORIGIN_ALLOW_ALL = True

settings.py添加:

ALLOWED_HOSTS = ['<DIGITALOCEANSERVER-IP>', '*', 'localhost', '127.0.0.1']
backend/urls.py中的

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include('api.urls')),
]
api/models.py中的

from django.db import models

# Create your models here.

class testModel(models.Model):
    word = models.CharField("word", max_length=20)
api/serializers.py中的

from rest_framework import serializers
from .models import testModel

class testSerializer(serializers.ModelSerializer):
    word = serializers.CharField(max_length=20)

    class Meta: 
        model = testModel
        fields = ('id', 'word')
api/urls.py中的

from django.conf.urls import url, include
from rest_framework.urlpatterns import format_suffix_patterns
from .views import testView

urlpatterns = [ 
    url(r'^test/', testView.as_view()),
]
api/views.py中的

from rest_framework import generics
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from django.shortcuts import render
from .models import testModel
from.serializers import testSerializer

# Create your views here.

class testView(APIView):
    def get(self, request):
        return Response({'succeded?', 'yes'})

现在保存所有内容,如果您:

,它应该可以使用
(exampleenv)$ python manage.py runserver
navigate to :8000/api/test/

同时完成了角度4前端和DRF后端,我们可以将更改推送到github,到现在为止会有很多变化;)

现在,让我们的前端和后端进入服务器,登录到服务器,现在好主意是从你的服务器(和本地机器)添加ssh密钥,如果你已经存在,到github。在服务器上,我们可以通过以下方式完成此操作:

$ ssh-keygen -t rsa -b 4096 -C "<EMAIL ADDRESS>"
$ eval "$(ssh-agent -s)"
Agent pid ....
$ ssh-add ~/.ssh/id_rsa
    Enter passphrase for /home/jupair/.ssh/id_rsa:
    Identity added: /home/jupiar/.ssh/id_rsa (/home/jupiar/.ssh/id_rsa)

$ mkdir example
$ cd example
$ git init
$ git pull git@github.com:<GITHUBUSERNAME>/<REPONAME>.git

(在某些时候,你可能在使用https或ssh时遇到错误)如果你使用的是ssh密钥,你需要使用github的ssh repo名称(在github上,clone or download按钮会给你这些链接),在本地机器上也可能需要set-url来使用ssh名称):

[on local machine]
$ git remote set-url origin git@github.com:<GITHUBUSERNAME>/<REPONAME>.git

好的,现在在你的服务器上,你应该在你的项目文件夹中有前端和后端文件夹,在服务器上非常容易:

$ cd /etc/nginx/sites-available
$ sudo rm default
$ sudo nano frontend.conf

并将这样的内容放在里面:

server {
        listen 80;
        listen [::]:80;

        root /home/jupiar/example/frontend/dist;
        index index.html index.htm index.nginx-debian.html;

        server_name example.com;

        location / {
                try_files $uri $uri/ =404;
        }
}

现在我们需要将该文件链接到已启用的网站:

$ sudo ln -s /etc/nginx/sites-available/frontend.conf /etc/nginx/sites-enabled/frontend.conf
$ cd /etc/nginx/sites-enabled
$ sudo rm default
$ sudo systemctl restart nginx.service

走向example.com,我们现在应该看到角度应用正常工作,

好的,现在为了使后端可以使用,有点棘手:

$ cd /etc/nginx/sites-available
$ sudo nano backend.conf

并放置如下内容:

server {
    listen 80;
    listen [::]:80;

    server_name api.example.com;

    location /static/admin {
        alias /home/jupair/anaconda3/lib/python3.6/site-packages/django/contrib/admin/static/admin;
    }

    location /static/rest_framework {
        alias /home/jupiar/anaconda3/lib/python3.6/site-packages/rest_framework/static/rest_framework;
    }

    location / {
        proxy_pass http://127.0.0.1:9000/;
        proxy_set_header    Host                $host;
        proxy_set_header    X-Real-IP           $remote_addr;
        proxy_set_header    X-Forwarded-For     $remote_addr;
        proxy_set_header    X-Forwarded-Proto   $scheme;
        proxy_redirect      off;

    }
}

现在,将该文件链接到已启用网站:

$ sudo ln -s /etc/nginx/sites-available/backend.conf /etc/nginx/sites-enabled/backend.conf

现在设置主管使用uwsgi启动django app

$ sudo apt-get install supervisor
$ sudo nano /etc/supervisor/conf.d/backend_api.conf

在里面,有类似的东西:

[program:backend_api]
command = /home/jupiar/anaconda3/bin/uwsgi --http :9000 --wsgi-file /home/jupiar/example/backend/backend/wsgi.py
directory = /home/jupiar/example/backend
user = jupiar
autostart = true
autorestart = true
stdout_logfile = /var/log/backnd_api.log
stderr_logfile = /var/log/backend_api_err.log

现在,你需要运行:

$ sudo supervisorctl reread
$ sudo supervisorctl update
$ sudo supervisorctl restart backend_api
$ sudo systemctl restart nginx.service

现在,转到api.example.com/api/test/应该会给你suceeded: true的django休息框架响应。

从现在开始,只要您想要进行实时更改,就可以使用自定义shell脚本,如下所示:

cd /home/jupiar/example
git reset --hard (sometimes you may need to run this)
git pull git@github.com/<GITUSERNAME>/<PROJECTNAME>.git
sudo supervisorctl restart backend_api
sudo systemctl restart nginx.service

这就是它,我相信一切都在于我记得这样做,任何问题或者如果出现问题/不适合你,请发表评论让我知道:)