【详细解释】如何使用AWS EC2秒速部署Django 3应用程序【Nginx、gunicorn、PostgreSQL】
使用AWS EC2云服务器,以最简单的配置将Nginx、gunicorn和postgresql部署。
如果要用Python创建Web应用程序,首选是Django,并且使用最新的3系进行部署。本篇文章的主题是详细解释如何进行基本的AWS部署。尽管由于详细的图示,文章可能会显得比较长,但我相信一旦熟悉了,可能只需大约20分钟就能完成。
在中文中重述以下内容(只需要一种方案):
在Django的教程中,我认为通常会把应用部署到Heroku的免费版上,
但无论是对于工作还是制作个人作品集来说,使用Heroku并不理想。
✖️ 使用Heroku进行部署的不利之处
-
- 無料だとアクセスに時間かかる(しばらくアクセスされていない場合)
-
- herokuデプロイだとポートフォリオに使うには少し手抜き感を持つ採用者増えた
- 日本の企業で使うなら大体AWS
⭕️ Heroku部署的优点
-
- 無料で簡単。初心者に優しい
- 情報も多い
✖️ AWS部署的缺点
-
- AWSは1年間の無料期間過ぎてしまうと、毎月がアクセスなくても店で「うな重」食えるくらいはお金かかる
- 少し複雑。インフラ周りの知識がいる
⭕️ AWS部署的优点
-
- 使っていない会社の方が少ないので就職・転職・フリーランスいずれもキャリア有利になるはず
-
- インフラ周りの知識つく
- 高単価になりやすいDevOpsエンジニアの基礎学べる
因此,我將專注於如何在AWS上快速且仔細地部署,並在本文中加以記載。
对于那些需要兼顾勉强和练习目的的人,我也会提供解除已部署应用的方法,以确保不花费任何费用,让您放心。
环境
-
- Mac
-
- Python 3.8
-
- Django 3.1.5
-
- PostgreSQL 12.5
-
- Nginx 1.18.0
- gunicorn 20.0.4
步骤
-
- 我在Github上创建一个私有仓库
-
- 在本地用Django创建一个最简单的应用程序
-
- 进行推送
-
- 创建EC2实例
-
- 从AWS中获取Git代码并部署
- 完成后拆除它
如果你是一个初学者,我认为你可以尝试按照以下步骤在AWS上练习部署。一旦你成功完成这些步骤,你可以尝试部署自己的应用程序或者类似过去文章的简单应用程序。
在Github上创建一个存储库。
我会确保这篇文章可以在公共仓库中公开。
然而,对于初学者来说,最好在私人仓库中进行操作,以确保安全性,因为可能会不小心将危险的内容公开。
当你在add .gitignore时勾选了Python选项,并选择了不公开的文件,它会自动创建一个排除这些文件的配置,这样非常方便。
从GitHub进行克隆
$ mkdir django
$ cd django
请在 Mac 上设置 SSH。有很多文章可以找到,我也会附上我的文章。虽然写的是 Ubuntu,但是在 Mac 上也可以用相同的方法。
对于已经设置了 SSH 的人来说,可以将 HTTPS 的 URL 复制并克隆到本地。
$ git clone ここにコピーしたURL
$ cd django-aws
在我的情况下,我使用django-aws创建了一个代码库。
用Django在本地创建最基本的应用程序
这次我们将使用pipenv创建虚拟环境。
只要能在我的电脑上正常运行,你可以选择在本地创建任何虚拟环境!
我以前写了一篇Pipenv环境搭建的文章,顺便贴出来。这次要用的是Mac…
由于我的Anaconda太重了,我决定使用Pipenv进行【Windows10 Python环境搭建】。
如果尚未安装pipenv,请安装并指定版本。
$ pip install pipenv
$ pipenv --python 3.8.7
将Django和用于读取.env文件的组件以及访问数据库所需的组件一并添加进来。
$ pipenv install django
$ pipenv install django-environ
$ pipenv install dj-database-url
创建一个虚拟环境,并创建一个名为testapp的项目和一个名为app的应用程序。
运行startproject testapp .命令将在当前目录中创建一个项目。
$ pipenv shell
$ django-admin startproject testapp .
$ django-admin startapp app
在有manage.py文件的位置上,输入命令并尝试启动本地服务器。
$ python manage.py runserver
http://127.0.0.1:8000/ 可以被简化为 “本地主机地址为 8000 端口”。
如果火箭起飞了就可以
当在.env文件中发布时,仅编写危险数据。
在manage.py所在的目录中创建一个名为.env的文件。
将 settings.py 文件中以下三个内容写入 .env 文件中。
※请勿包含无用的空格、逗号或引号。
SECRET_KEY=1234567890sdogdmsmoa@:dmmgsv94kmvaso(9l
DEBUG=False
DATABASE_URL=sqlite:///db.sqlite3
将相关内容从.env文件中读取并进行变更。
import environ
import os
.
.
env = environ.Env()
env.read_env(os.path.join(BASE_DIR, '.env'))
SECRET_KEY = env('SECRET_KEY')
DEBUG = env('DEBUG')
INSTALLED_APPS = [
'app.apps.AppConfig', # 追加
]
.
.
.
DATABASES = {
'default': env.db(),
}
因为你在createapp中指定了app,所以’app.apps.AppConfig’会变成这样。如果你在djangoapp中使用createapp,那么就会变成’djangoapp.apps.DjangoappConfig’。
确认.gitignore
只要按照步骤来做,我认为就没有问题,但是如果使用了其他方法,那么请查看以下的.gitignore文件中的.env描述。
.env
通过这样做,可以让环境变量不被加入到 GitHub 仓库中。
为了将所需的库安装到生产环境中,创建一个 requirements.txt 文件。
我会导出我在本地使用的库。
稍后,我会将其安装在用于部署库的服务器上。
$ pip freeze > requirements-dev.txt
现在,已经将在本地运行所需的库写入到requirements-dev.txt文件中。
在EC2上添加额外使用的库,除了本地库。
接下来,创建requirements.txt文件。
-r requirements-dev.txt
gunicorn
psycopg2
当你写下这个时,可以在requirements-dev.txt中写下必要的库,以使其在开发环境中运行,并添加一种方法来描述构建生产环境所需的库。
创建一个只显示简单字符的应用。
添加路由。
from django.contrib import admin
from django.urls import path, include #追加
urlpatterns = [
path('admin/', admin.site.urls),
path('',include("app.urls")) #追加
]
请添加读取应用程序中的路由的功能。
在app目录中创建urls.py文件。
当访问localhost:8000时,使用views.py中的index方法来创建页面。
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
编写一个仅渲染纯文字HTML的应用程序的处理过程。
from django.http import HttpResponse
def index(request):
return HttpResponse('文字だけアプリ')
当我尝试访问时
http://127.0.0.1:8000/ 可以重新表达为:
http://127.0.0.1:8000/
我做好了只显示文字的应用程序,就像这样(笑)。
将代码推送到 Github。
只要能把代码放在EC2创建的地方,除了git还有其他方法,但最方便的是git。
-
- 将代码推送到GitHub上
-
- 在EC2上拉取代码以获取
- 创建一个生产环境,以便运行我们这次开发的应用程序
那么,将其推送到存储库中。
※ 已经按照之前的步骤进行设置,但为了保险起见,不要将.env文件推送。
$ git add .
$ git commit -m "文字だけアプリ"
$ git push
7. 在AWS EC2上部署操作
在创建账号时,我们将省略IAM设置等步骤。
在AWS控制台上进行操作。
请搜索并选择EC2。
*由于AWS的UI经常更改,如果与图像不同,请选择相似的选项。
这次我将使用Ubuntu操作系统。
请将安全组更改为易懂的“django”,然后点击确认和创建。
这只是为了区分我在这次使用时选择的安全组,所以任何都可以。
您的安全受到威胁了呢。
本来应该将 SSH 设置为只能让自己家和工作场所的 IP 访问,但是 IP 会经常变化,而且如果在家以外的地方工作就无法访问,非常麻烦。
这只是练习,不用理会那些威胁。
這次我們命名為djangoapp,下載密鑰對。只要我自己知道就可以,請隨意。注意:
-
- 为了不丢失密钥对,请注意不要丢失它们。否则你将无法访问。
-
- 绝对不能将此密钥公开在互联网上!
-
- 绝对不能将此密钥放入需要通过GitHub进行推送的目录中!
- 否则会出现很麻烦的情况?。
请在主文件夹下创建一个名为aws_key的文件夹,并将下载的密钥移动到该文件夹中,以便更易理解。然后点击”创建实例”。
按下「显示实例」即可返回以下画面。
一旦开始执行,则继续进行下一步骤。
控制台操作
让我们尝试在终端上连接,因为在”SSH客户端”选项卡上有连接方法的说明。
我在我的电脑上,进入保存密钥文件的目录,然后输入所写的命令。很可能命令是类似这样的。
$ chmod 400 ここが鍵の名前
$ ssh -i "鍵名" ubuntu@ec2-13-111-111-111.ap-northeast-1.compute.amazonaws.com
我认为2-13-111-111-111中的数字是不同的。
将「例:」上面的内容原封不动地复制粘贴到控制台。
接着发生了什么
因为被询问是否确定要继续连接(是/否/指纹),所以回答是并输入。
我已经将其安装进了EC2(操作系统是Ubuntu)。
8. 在我创建的Ubuntu的EC2实例上进行操作。
虽然说是 EC2,但它只是一个 Linux的个人电脑,所以与在 Mac上建立环境的过程并没有太大区别,我们可以继续进行。
Ubuntu的软件包管理器是apt-get。可能会有旧版本,建议更新一下。
※ 类似于Mac上的brew。
# cd で一応homeディレクトリで行うことにする
$ cd
$ sudo apt-get update
如果有人关注安全问题,请创建一个新用户并授予权限等。这里我们跳过。
我将下载使用的一整套东西。
我将安装Python和PostgreSQL数据库,以及服务器软件nginx和其他必要的库。
$ sudo apt-get install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx
如果出现[Y/n],请输入Y。
PostgreSQL数据库配置
我們將設置Posgres數據庫。
-
- 创建数据库
-
- 创建用户(请适时更改密码)
-
- 设置数据库的字符编码为UTF8
-
- 设置事务隔离级别(暂时可以复制粘贴)
-
- 以日本时间为准
- 将所有数据库权限授予已创建的用户
$ sudo -u postgres psql
postgres=# CREATE DATABASE djangodb;
postgres=# CREATE USER django WITH PASSWORD 'testPassword1';
postgres=# ALTER ROLE django SET client_encoding TO 'utf8';
postgres=# ALTER ROLE django SET default_transaction_isolation TO 'read committed';
postgres=# ALTER ROLE django SET timezone TO 'UTC+9';
postgres=# GRANT ALL PRIVILEGES ON DATABASE djangodb TO django;
postgres=# \q
顺便说一下,在Mac上输入反斜杠的方法是按住Option键然后按¥键。
可以将其放入虚拟环境中。
我们在这里使用virtualenv作为虚拟环境。请进行更新和安装。
$ sudo -H pip3 install --upgrade pip
$ sudo -H pip3 install virtualenv
现在, 我们会创建一个虚拟环境并进入其中。
虚拟环境的名字可以设为django,但是需要使用一个容易理解的名字。
使用源代码中的django/bin/activate来启动虚拟环境。
$ virtualenv django
$ source django/bin/activate
一旦成功进入虚拟环境(django)后,虚拟环境的名称会显示在最前面,就像使用Django的manage.py等时,必须进入虚拟环境才能使用,所以请注意。
从Github上克隆生成的代码。
我要从GitHub上克隆。
请参考以下文章进行克隆。
我决定将Django项目克隆到home目录下。
$ cd
$ git clone git@github.com:ユーザー名/リポジトリ名.git
然后,我们将使用在本地上编写的requirements.txt文件来安装所需的库。
$ ls
django django-aws
$ cd django-aws
$ pip install -r requirements.txt
创建.env文件
由于在gitignore中排除了,本地没有.env文件。
如果不创建,无法读取Django使用的密钥等,会出现错误,所以需要创建。
请在manage.py的同一目录层级下创建与本地相同的文件。
$ vim .env
请将以下两个位于本地的.env文件中的内容粘贴,并在下方添加数据库连接设置。
使用以下规则:postgres://USER:PASSWORD@HOST:PORT/NAME,即可连接。
SECRET_KEY=1234567890sdogdmsmoa@:dmmgsv94kmvaso(9l
DEBUG=False
DATABASE_URL=postgres://django:ここにさっき設定したDBのパスワード@localhost:/djangodb
ALLOWED_HOSTS=13.111.111.111
※ 一般而言,使用vim进行编辑时,按下i键。保存方式是按下esc键,然后输入冒号,再输入wq。
请在AWS EC2的控制台中输入ALLOWED_HOSTS字段,其中包含公有IPv4地址。
请注意:如果您没有设置此主机的IP和AWS的弹性IP地址,在每次停止实例后,它们都会发生变化。所以,如果您在设置之前停止了实例,就需要在这里重新设置。
如果设置了弹性IP地址,则不需要重新设置,但如果关联的实例处于停止状态,可能每月会产生数百日元的费用!如果不再使用实例,则最好释放弹性IP。
编辑settings.py
由于我添加了配置文件.env的内容,所以可以读取它。
$ cd testapp
$ vim settings.py
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')
执行迁移
移动到 manage.py 所在的目录,并执行 migrate 操作。
$ python3 manage.py migrate
如果迁移成功,就可以了!
9. 我们可以在开发服务器上进行确认。
如果不使用Nginx gunicorn,本章就结束了。
返回EC2界面,编辑“入站规则”
只要启动我通常在本地使用的服务器,基本上部署就可以算是完成了!
当运行服务器时,我决定在8000端口上启动,因此允许了8000端口。
由于一応已经完成了,所以请确认一下。
在manage.py所在的目录中,以本地服务器的方式启动服务器。
IP地址全部允许,但端口号为8000。
(正如先前在入站规则中指定的8000号端口)
$ python3 manage.py runserver 0.0.0.0:8000
复制公共IPv4地址和端口到浏览器。
54.250.111.11:8000:五四点二五零点一一一点一一,八千
以类似的方式进行访问。
我成功了。暂时可以。
我已经成功部署了一个只能显示文本的应用。如果只是制作一个原型可能还可以,但如果是普通的Django配置,我们会使用gunicorn和nginx,所以让我们将其配置好。
10. gunicorn的配置
一旦离开虚拟环境,我们开始进行工作。
$ deactivate
我将编写gunicorn的配置。
$ sudo vim /etc/systemd/system/gunicorn.service
在我这里的情况是这样的。
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/django-aws
ExecStart=/home/ubuntu/django/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/ubuntu/django-aws/testapp.sock testapp.wsgi:application
[Install]
WantedBy=multi-user.target
工作目录=/home/ubuntu/与存储库同名的
ExecStart=/home/ubuntu/仮想環境的名字/bin/gunicorn –access-logfile – –workers 3 –bind unix:/home/ubuntu/和仓库名字相同的/Django项目名字.sock Django项目名字.wsgi:application
请只进行调整。
Gunicorn服务的自动启动和启用
$ sudo systemctl start gunicorn.service
$ sudo systemctl enable gunicorn
11. Nginx的配置。
接下来我们要创建nginx的配置文件。
sudo vim /etc/nginx/sites-available/与仓库名称相同
$ sudo vim /etc/nginx/sites-available/django-aws
请修改以下内容。
server {
listen 80;
server_name ここにパブリックIP;
location = /favicon.ico {access_log off; log_not_found off;}
location /static/ {
root /home/ubuntu/リポジトリの名前と同じ;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/リポジトリの名前と同じ/プロジェクト名.sock;
}
}
创建符号链接
$ sudo ln -s /etc/nginx/sites-available/django-aws /etc/nginx/sites-enabled/
启动 Nginx 并打开 80 端口。
刚才执行了 python manage.py runserver 的人,暂时移除了 8000 端口。
$ sudo systemctl restart nginx
$ sudo ufw delete allow 8000
$ sudo ufw allow 'Nginx Full'
12. 安全组设置
刚刚,对通过8000端口的内容进行了更改。更改为使用HTTP。
※因为不再使用8000端口,最好将其删除。
由于本次情况下采用了Django,我会对安全组进行编辑。
检查HTTP和0.0.0.0/0,并保存规则。
重新启动gunicorn。
$ sudo systemctl restart gunicorn
再输入一次公共IP地址到URL中,
http://13.111.111.11/ 可以用下列方式进行复述:
这是一个网站的网址:http://13.111.111.11/
表示完成了!你做得好吗?
13. 破坏的方法
一般的的做了试验性文章就结束了。但是,我们已经发布了
-
- 1年の無料期間過ぎたので壊したい
-
- 必要なくなった
-
- 他のEC2立てたい
- もう一回練習したい
我认为有类似的东西。
所以我准备迅速摧毁它们。
破坏方法 shǐ fǎ)
这次需要的是
-
- EC2インスタンスを終了させる
- セキュリティグループを削除
如果您想要停止收费,只需终止最小限度的EC2即可。
希望刪除的是「終了」。希望你把「削除」寫上去啦 ?
这就是结束了。
使用弹性IP的人进行开放
另外,这次没使用,可以略过,但是经常会使用到一个服务,即使用弹性IP来确保即使停止或重新启动EC2实例,IP地址不会改变。
如果你正在使用EC2,请在关闭它后”释放”它。如果不释放,每个月将收取数百元费用。
从左边的兰花开始
-
- 弹性IP
-
- 解除与EC2的绑定
-
- 释放弹性IP
-
- 终止EC2
- 删除安全组
我认为你应该试试做一下。
实现补全CSS
但是,表达的目的已经达到了。
只需要一个选项,将以下内容用中文进行本地化改写:
http://13.111.111.11/admin/
十三点一一一一一一一一一一一一一一个点一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一/admin/
CSS没有生效。
在部署Django时,当使用静态文件(如CSS、图片、JS)时,需要使用命令。
在manage.py相同的位置创建static文件夹,并在settings.py的底部添加以上的描述。
$ mkdir static
$ cd testapp
$ vim settings.py
在代码中添加一个用于设置保存CSS文件的目录的配置。
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
$ source ~/django/bin/activate
$ python3 manage.py collectstatic
132 static files copied to '/home/ubuntu/django-aws/static'.
我说了一下,将静态文件放在/home/ubuntu/django-aws/static文件夹中。
这个文件夹是刚刚在settings.py中指定的目录。
现在已经完成了,试着访问一下。
http://13.111.111.11/管理员/ (Mandarin Chinese)
完成了。
我创建了一个超级管理员并尝试使用管理界面。
因为Django在默认情况下具有创建管理界面的功能,所以让我们尝试使用它。(非常方便!)
创建超级用户并登录。
$ python3 manage.py createsuperuser
Username (leave blank to use 'ubuntu'): djangosuper
Email address:
Password:
Password (again):
Superuser created successfully.
请提供一个名称和密码来创建账户。(输入密码时不会显示)。默认情况下,无需填写电子邮箱,因此可随意填写或不填写。请记住,这个账户可以从全球访问,所以密码要设置复杂一些。
我们完成了!
您可以通过此界面向数据库添加数据或设置访问限制。
请参考我以前编写的有关处理此类事项的Django应用程序的文章。