aws v2.2.exe
by Sumeet Kumar
通過Sumeet Kumar
如何使用Python 3.6在AWS EC2上創建運行uWSGI,NGINX和PostgreSQLDjango服務器 (How to create a Django server running uWSGI, NGINX and PostgreSQL on AWS EC2 with Python 3.6)
Getting a server up and running for a new project every time might be time-consuming or difficult for new developers. So I thought I’d write a step-by-step guide that will ease the deployment process.
對于新開發人員而言,每次都為新項目啟動服務器并運行可能會非常耗時或困難。 因此,我想寫一個循序漸進的指南,以簡化部署過程。
If you’re in no mood to read, you can copy paste each step as described (replace values) and get your server up and running ?
如果您不想閱讀,則可以按說明復制粘貼每個步驟(替換值),并使服務器啟動并運行?
先決條件: (Prerequisites:)
Amazon Linux EC2 instance up and running with the associated key pair (ssh access to it).
使用關聯的密鑰對(通過ssh訪問 )啟動并運行Amazon Linux EC2實例。
Port 22, 80 must be open for this instance.
此實例必須打開端口 22、80。
- Django application that you want to deploy. 您要部署的Django應用程序。
- Database settings are configured to use PostgreSQL. 數據庫設置配置為使用PostgreSQL。
requirements.txt is present in your app, having dependencies list to install.
Requirements.txt存在于您的應用中,具有要安裝的依賴項列表。
- Git repository for your Django app. Django應用程序的Git存儲庫。
SSH和更新ubuntu實例 (SSH & update ubuntu instance)
You need to ssh into your EC2 instance, so make sure you have port 22 open for your instance and then do a update/upgrade.
您需要使用SSH進入EC2實例,因此請確保為實例打開了端口22 ,然后進行更新/升級。
ssh -i path-to-your-key.pem ubuntu@your-aws-instance-public-ipsudo apt-get update && sudo apt-get upgrade -y
在AWS EC2上安裝Python3.6.x(ubuntu 16.04) (Installing Python3.6.x on AWS EC2 (ubuntu 16.04))
We will download the tar.xz file from official site and than manually install it. Before that we need to install some required dependencies.
我們將從官方網站下載tar.xz文件,然后手動安裝。 在此之前,我們需要安裝一些必需的依賴項。
建立和安裝依賴項 (Building and installing dependencies)
sudo apt install build-essential checkinstallsudo apt install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev
下載并手動安裝所需的Python版本 (Downloading & manually installing required Python version)
cd /opt && sudo wget https://www.python.org/ftp/python/3.6.6/Python-3.6.6.tar.xzsudo tar -xvf Python-3.6.6.tar.xzcd Python-3.6.6/sudo ./configuresudo make && sudo make install
刪除下載的文件 (Removing downloaded file)
sudo rm -rf Python-3.6.6.tar.xz
檢查Python版本 (Check Python version)
python3 -V
> Python 3.6.6
為我們的應用程序設置Ubuntu用戶 (Setting up Ubuntu user for our application)
Django itself is very secure framework, I agree. But web applications are still vulnerable. It is good practice to run your application as system users with limited privileges which has limited access to resources on your server. So in this section, we will be adding a new user & permission group to our EC2 instance.
我同意,Django本身是非常安全的框架。 但是Web應用程序仍然容易受到攻擊。 優良作法是以特權有限的系統用戶身份運行應用程序,這對服務器上的資源具有有限的訪問權限。 因此,在本節中,我們將向我們的EC2實例添加一個新的用戶和權限組。
添加ubuntu系統組'groupname'[在我的情況下為webapps]并將用戶'username'[在我的情況下為Bunny]分配給該組 (Adding ubuntu system group ‘groupname’ [webapps in my case] and assign a user ‘username’ [bunny in my case] to this group)
sudo groupadd --system webapps
sudo useradd --system --gid webapps --shell /bin/bash --home /webapps/project_name bunny
Note: I am assuming “project_name” is the name that you might have used during “django-admin startproject <name>”
注意:我假設“ project_name ”是您在“ django-admin startproject <na me>”期間使用的名稱。
創建一個目錄來存儲您的應用程序 (Create a directory to store your application)
Create a directory to store your application in /webapps/project_name/. Change the owner of that directory to your application user bunny:
創建目錄以將您的應用程序存儲在/ webapps / project_name /中。 將該目錄的所有者更改為您的應用程序用戶兔子:
sudo mkdir -p /webapps/project_name/sudo chown bunny /webapps/project_name/
允許對其他組用戶的訪問僅限于應用程序目錄 (Allow limited access to other group users to application directory)
sudo chown -R bunny:users /webapps/project_namesudo chmod -R g+w /webapps/project_name
現在您可以切換到您的用戶 (Now you can switch to your user)
sudo su - bunny// your console will switch to something like this
bunny@ip-172-31-5-231:~$
To switch back to sudo user, just do ctrl+d
and it’ll kill the user terminal.
要切換回sudo用戶,只需執行ctrl+d
,它將殺死用戶終端。
安裝和配置PostgresSQL (Installing and configuring PostgresSQL)
安裝PostgreSQL并創建數據庫 (Installing PostgreSQL & creating database)
sudo apt install postgresql postgresql-contribsudo su - postgrespostgres@ip-172-31-5-231:~$ psqlpostgres=# CREATE DATABASE database_name;
在psql終端中更改Postgres的默認密碼 (Changing default password for postgres while in psql terminal)
postgres=# \password
在虛擬環境中通過Git在EC2實例上部署Django應用 (Deploy Django app on EC2 instance via Git in virtual environment)
Deploying your app using a virtual environment allows your app and its requirements to be handled separately. It is good practice to keep your app isolated.
使用虛擬環境部署應用程序可以單獨處理您的應用程序及其要求。 保持應用隔離是一個很好的做法。
Using the environment concept is handy when you are deploying more than one Django app on a single instance to keep them and their dependencies isolated from each other.
當您在單個實例上部署多個Django應用程序以使它們及其依賴項相互隔離時,使用環境概念非常方便。
We will be creating a virtual environment in our system user (bunny) directory. Before that we will be installing git as a sudo user.
我們將在系統用戶( bunny )目錄中創建虛擬環境 。 在此之前,我們將以sudo用戶身份安裝git。
安裝Git并從git repo中提取代碼 (Installing Git and pulling your code from git repo)
sudo apt-get install gitsudo su - bunny// change to your repo https or ssh link
bunny@ip-172-31-5-231:~$ git remote add origin git@github.com:<user>/<user-repo>.gitbunny@ip-172-31-5-231:~$ git pull origin <branch_name>
Note that we haven’t cloned our complete repo here. Instead we manually set our git link and only pulled the branch that we want to deploy to this instance. You may have a different instance for your development, beta, or production ready web app corresponding to each branch on git.
請注意,我們尚未在此處克隆完整的存儲庫。 取而代之的是,我們手動設置git鏈接,并僅拉出要部署到該實例的分支。 您可能有與git上每個分支相對應的開發,測試版或生產就緒型Web應用程序的不同實例。
在當前目錄中使用Python3.6創建虛擬環境 (Creating virtual environment using Python3.6 in current directory)
bunny@ip-172-31-5-231:~$ python3.6 -m venv .
bunny@ip-172-31-5-231:~$ source bin/activate
(project_name)bunny@ip-172-31-5-231:~$ pip install -r requirements.txt
At this point, we have successfully set up our project. Now we need to run some manage.py command. This will require that we are in the directory where our manage.py is present, or every time we need to give a path to it:
至此,我們已經成功建立了我們的項目。 現在我們需要運行一些manage.p y命令。 這將要求我們位于manage.py所在的目錄中,或者每次我們需要提供路徑時:
(project_name)bunny@ip-172-31-5-231:~$ python <path-to->manage.py migrate(project_name)bunny@ip-172-31-5-231:~$ python <path-to->manage.py createsuperuser(project_name)bunny@ip-172-31-5-231:~$ python <path-to->manage.py collectstatic
Note: collectstatic
command requires that the STATIC configuration is setup properly. We are not discussing that here, though, as it is not in the scope of this tutorial.
注意: collectstatic
命令要求正確配置STATIC配置。 但是,我們不在這里討論,因為它不在本教程的范圍內。
(project_name)bunny@ip-172-31-5-231:~$ python <path-to->manage.py runserver 0.0.0.0:8000
This will start up the development server on port 8000
. Assuming port 8000 is also open for your instance, you can visit your server's domain name or IP address followed by 8000
in your browser.
這將在端口8000
上啟動開發服務器。 假設您的實例也打開了端口8000,則可以在瀏覽器中訪問服務器的域名或IP地址,后跟8000
。
http://your_server_domain_or_public_IP:8000
http://your_server_domain_or_public_IP:8000/admin
Note: Don’t forget to add your domain or IP to ALLOWED_HOST in your settings.py
注意:不要忘記在您的settings.py中將您的域或IP添加到ALLOWED_HOST中
設置uWSGI Application Server (Setting up the uWSGI Application Server)
Now that we’ve got our project set up and ready to go, we can configure uWSGI to serve our app to the web instead of the lightweight development server provided by Django.
現在我們已經完成了項目的準備并可以開始使用,我們可以配置uWSGI以將我們的應用程序提供給網絡,而不是Django提供的輕量級開發服務器。
If you’re thinking of running the runserver command on a screen, drop it. The dev server with Django is terribly lightweight, highly insecure, and not scalable.
如果您想在屏幕上運行runserver命令,請將其刪除。 使用Django的開發服務器非常輕巧,高度不安全且不可擴展。
You can install uWSGI either in virtualenv or globally and configure it accordingly.
您可以在virtualenv或全局中安裝uWSGI并進行相應的配置。
In this tutorial, we’ll be installing uWSGI in virtualenv. Before we can install uWSGI, we need the Python development files that the software relies on.
在本教程中,我們將在virtualenv中安裝uWSGI。 在安裝uWSGI之前,我們需要該軟件所依賴的Python開發文件。
安裝uWSGI及其依賴項 (Installing uWSGI along with its dependencies)
sudo apt-get install python3-dev
sudo su - bunny
bunny@ip-172-31-5-231:~$ source bin/activate
(project_name)bunny@ip-172-31-5-231:~$ pip install uwsgi
Let’s run the server using uWSGI. This command does the same thing a manage.py runserver would do. You need to replace values accordingly to successfully test with this command.
讓我們使用uWSGI運行服務器。 此命令執行manage.py runserver將執行的相同操作。 您需要相應地替換值,才能使用此命令成功進行測試。
(project_name)bunny@ip-172-31-5-231:~$ uwsgi --http :8000 --home <path-to-virtualenv> --chdir <path-to-manage.py-dir> -w <project-name>.wsgi
創建uWSGI配置文件 (Creating uWSGI configuration file)
Running uWSGI from the command line is only useful for testing. For actual deployment, we will create a .ini file somewhere in our system user directory. This file will contain all the configuration for handling a heavy request load, and can be tweaked accordingly.
從命令行運行uWSGI僅對測試有用。 對于實際部署,我們將創建一個。 伊尼 文件在我們系統用戶目錄中的某個位置。 該文件將包含用于處理繁重的請求負載的所有配置,并且可以相應地進行調整。
Later in this tutorial, we will run uWSGI behind NGINX. NGINX is highly compatible with uWSGI and has built-in support for interacting with uWSGI.
在本教程的后面,我們將在NGINX之后運行uWSGI。 NGINX與uWSGI高度兼容,并內置了與uWSGI交互的支持。
在系統用戶目錄中創建目錄conf ,將在其中存儲uwsgi.ini (Create a directory conf in your system user directory where you will store uwsgi.ini)
(project_name)bunny@ip-172-31-5-231:~$ mkdir conf
(project_name)bunny@ip-172-31-5-231:~$ cd conf
(project_name)bunny@ip-172-31-5-231:~$ nano uwsgi.ini
Copy the below code from the gist and save it I think the comments are explanatory enough for each option.
從主旨中復制以下代碼并將其保存,我認為注釋對于每個選項都足以解釋。
NOTE: updateMe
is supposed to be you project name. It is the same name you gave above while creating the system user directory, so update accordingly.
注意: updateMe
應該是您的項目名稱。 它與您在創建系統用戶目錄時在上面輸入的名稱相同,因此請進行相應更新。
[uwsgi]# telling user to execute file
uid = bunny# telling group to execute file
gid = webapps# name of project you during "django-admin startproject <name>"
project_name = updateMe# building base path to where project directory is present [In my case this dir is also where my virtual env is]
base_dir = /webapps/%(project_name)# set PYTHONHOME/virtualenv or setting where my virtual enviroment is
virtualenv = %(base_dir)# changig current directory to project directory where manage.py is present
chdir = %(base_dir)/src/# loading wsgi module
module = %(project_name).wsgi:application# enabling master process with n numer of child process
master = true
processes = 4# enabling multithreading and assigning threads per process
# enable-threads = true
# threads = 2# Enable post buffering past N bytes. save to disk all HTTP bodies larger than the limit $
post-buffering = 204800# Serialize accept() usage (if possibie).
thunder-lock = True# Bind to the specified socket using default uwsgi protocol.
uwsgi-socket = %(base_dir)/run/uwsgi.sock# set the UNIX sockets’ permissions to access
chmod-socket = 666# Set internal sockets timeout in seconds.
socket-timeout = 300# Set the maximum time (in seconds) a worker can take to reload/shutdown.
reload-mercy = 8# Reload a worker if its address space usage is higher than the specified value (in megabytes).
reload-on-as = 512# respawn processes taking more than 50 seconds
harakiri = 50# respawn processes after serving 5000 requests
max-requests = 5000# clear environment on exit
vacuum = true# When enabled (set to True), only uWSGI internal messages and errors are logged.
disable-logging = True# path to where uwsgi logs will be saved
logto = %(base_dir)/log/uwsgi.log# maximum size of log file 20MB
log-maxsize = 20971520# Set logfile name after rotation.
log-backupname = %(base_dir)/log/old-uwsgi.log# Reload uWSGI if the specified file or directory is modified/touched.
touch-reload = %(base_dir)/src/# Set the number of cores (CPUs) to allocate to each worker process.
# cpu-affinity = 1# Reload workers after this many seconds. Disabled by default.
max-worker-lifetime = 300
I am trying to make everything easy with clear explanations. Cross check paths, directory name, and other inputs that you are required to replace.
我試圖通過清楚的解釋使一切變得容易。 交叉檢查路徑,目錄名稱和您需要替換的其他輸入。
We need to create the log file and run directory where our socket file will be created, that we just mentioned in our uwsgi.ini:
我們需要創建日志文件并運行目錄,該目錄將在我們的uwsgi.ini中提到:
(project_name)bunny@ip-172-31-5-231:~$ mkdir log
(project_name)bunny@ip-172-31-5-231:~$ mkdir run
(project_name)bunny@ip-172-31-5-231:~$ touch log/uwsgi.log
Make sure to change permissions for these two so that every group or user can write or execute files in these directories:
確保更改這兩個權限,以便每個組或用戶都可以在以下目錄中寫入或執行文件:
$ sudo chmod 777 /webapps/updateMe/run
$ sudo chmod 777 /webapps/updateMe/log
Now let’s try running the server using uwsgi.ini that we just created.
現在,讓我們嘗試使用剛剛創建的uwsgi.ini運行服務器。
(project_name)bunny@ip-172-31-5-231:~$ uwsgi --ini /webapps/updateMe/conf/uwsgi.ini
If everything up until now is setup correctly, then it should be running. If not, then you need to go back to check for anything you missed (like the path/project name, etc).
如果到目前為止的所有設置都正確設置,則它應該正在運行。 如果不是,那么您需要返回以檢查是否缺少任何內容(例如路徑/項目名稱等)。
To check any uswgi log you can cat or tail uwsgi.log:
要查看任何uswgi日志,您可以貓或尾巴 uwsgi.log:
(project_name)bunny@ip-172-31-5-231:~$ tail log/uwsgi.log
為uWSGI創建系統單位文件 (Create a systemd Unit File for uWSGI)
At this point if everything is cool, you can even run this command in screen and detach it — but again, this is not a good practice at all. Instead we will create a system service and let systemd (Ubuntu’s service manager) take care of it.
此時,如果一切正常,您甚至可以在屏幕上運行此命令并將其分離-再次重申,這根本不是一個好習慣。 相反,我們將創建一個系統服務,并讓systemd (Ubuntu的服務管理器)負責該服務。
切換回sudo用戶 (Switch back to sudo user)
$ sudo nano /etc/systemd/system/uwsgi.service
and copy paste code from the below gist. Don’t forget to update and crosscheck names/path that suit your app:
并從下面的要點復制粘貼代碼。 不要忘記更新和交叉檢查適合您應用程序的名稱/路徑:
[Unit]
Description=uWSGI instance to serve updateMe project
After=network.target[Service]
User=bunny
Group=webapps
WorkingDirectory=/webapps/project_name/src
Environment="PATH=/webapps/project_name/bin"
ExecStart=/webapps/project_name/bin/uwsgi --ini /webapps/project_name/conf/uwsgi.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all[Install]
WantedBy=multi-user.target
After you save the above file and close it, you can run following commands:
保存上面的文件并關閉它后,可以運行以下命令:
Reload systemctl daemon to reload systemd manager configuration and recreate the entire dependency tree
重新加載systemctl守護程序以重新加載systemd管理器配置并重新創建整個依賴關系樹
$ sudo systemctl daemon-reload
Enable uwsgi service to start on system reboot
啟用uwsgi服務以在系統重新啟動時啟動
$ sudo systemctl enable uwsgi
Start uwsgi service
啟動uwsgi服務
$ sudo service uwsgi start
Restart uwsgi service
重新啟動uwsgi服務
$ sudo service uwsgi restart
Check uwsgi service status
檢查uwsgi服務狀態
$ sudo service uwsgi status
Take a deep breath here if everything ran smoothly. We just finished setting up most hectic part of this tutorial, so you should be proud.
如果一切順利,請在這里深呼吸。 我們剛剛完成了本教程中最忙碌的部分的設置,因此您應該為此感到自豪。
Next we will setup NGINX, and then we’ll be done! I know this is taking a bit of time, but believe me — once done, you will be as happy as I will be after publishing this tutorial.
接下來,我們將設置NGINX,然后就可以完成! 我知道這會花費一些時間,但是請相信我-完成后,您將和發布本教程后一樣快樂。
在EC2上為uWSGI設置NGINX (Setting Up NGINX on EC2 for uWSGI)
NGINX is a lightweight server, and we’ll use it as a reverse proxy.
NGINX是一個輕量級的服務器,我們將其用作反向代理。
We could let uWSGI run directly on port 80, but NGINX has a lot more benefits which makes it desirable. Also NGINX natively includes support for uWSGI.
我們可以讓uWSGI直接在端口80上運行,但是NGINX有很多好處 ,因此很可取。 NGINX本身也包含對uWSGI的支持 。
聊夠了,讓我們在實例上安裝NGINX (Enough talk, let’s install NGINX on our instance)
$ sudo apt-get install nginx
Now when you go to http://your-public-ip-or-address, you will see a Nginx welcome page. This is because NGINX is listening to port 80 according to its default configuration.
現在,當您轉到http:// your-public-ip-or-address時 ,您將看到一個Nginx歡迎頁面。 這是因為NGINX正在根據其默認配置監聽端口80。
NGINX has two directories, sites-available and sites-enabled, that need our attention. sites-available stores all conf files for all available sites on that particular instance. sites-enabled stores the symbolic link for each enabled site to the sites-available directory.
NGINX有兩個目錄, 可用 站點和啟用站點, 需要我們的注意。 sites-available存儲該特定實例上所有可用站點的所有conf文件。 網站啟用 將每個啟用站點的符號鏈接存儲到sites-available目錄。
By default, there is only one conf file named default that has basic setup for NGINX. You can either modify it or create a new one. In our case, I am going to delete it:
默認情況下,只有一個名為default的conf文件,它具有NGINX的基本設置。 您可以修改它或創建一個新的。 在我們的情況下,我將其刪除:
$ sudo rm -rf /etc/nginx/sites-available/default
$ sudo rm -rf /etc/nginx/sites-enabled/default
Let’s create our nginx-uwsgi.conf file to connect the browser request to the uwsgi server we are running in site-available:
讓我們創建nginx-uwsgi.conf文件,以將瀏覽器請求連接到我們在站點可用中運行的uwsgi服務器:
$ sudo nano /etc/nginx/sites-available/nginx-uwsgi.conf
and copy the following code from the gist below:
并從下面的要點復制以下代碼:
upstream updateMe_dev {server unix:/webapps/updateMe/run/uwsgi.sock;
}server {listen 80;server_name your-IP-or-address-here;charset utf-8;client_max_body_size 128M;location /static {# exact path to where your static files are located on server # [mostly you won't need this, as you will be using some storage service for same]alias /webapps/updateMe/static_local;}location /media {# exact path to where your media files are located on server # [mostly you won't need this, as you will be using some storage service for same]alias /webapps/updateMe/media_local;}location / {include uwsgi_params;uwsgi_pass updateMe_dev;uwsgi_read_timeout 300s;uwsgi_send_timeout 300s;}access_log /webapps/updateMe/log/dev-nginx-access.log;error_log /webapps/updateMe/log/dev-nginx-error.log;
}
創建符號鏈接到啟用站點的目錄中 (Create symbolic link into sites-enabled directory for same)
$ sudo ln -s /etc/nginx/sites-available/nginx-uwsgi.conf /etc/nginx/sites-enabled/nginx-uwsgi.conf
That’s all, we’re almost there, about to finish up…
僅此而已,我們快要完成了,…
重新加載systemctl守護程序 (Reload systemctl daemon)
$ sudo systemctl daemon-reload
在系統重啟時啟用Nginx服務 (Enable nginx service on system reboot)
$ sudo systemctl enable nginx
啟動Nginx服務 (Start Nginx service)
$ sudo service nginx start
Test Nginx. It should return OK, Successful as a part of the result.
測試Nginx。 它應該返回OK,成功作為結果的一部分。
$ sudo nginx -t
If NGINX fails, you can check its last error-log or access-log on the path specified by us in its conf.
如果NGINX失敗,您可以在我們在其conf中指定的路徑上檢查其最后的錯誤日志或訪問日志。
$ tail -f /webapps/updateMe/log/nginx-error.log
$ tail -f /webapps/updateMe/log/nginx-access.log
重新啟動Nginx服務 (Restart Nginx Service)
$ sudo service nginx restart
檢查Nginx服務狀態 (Check Nginx Service status)
$ sudo service nginx status
You should now be able to reach your app at http://your-public-ip-or-address
現在,您應該可以通過http:// your-public-ip-or-address訪問您的應用
Well this is the end of this lengthy tutorial. I hope you got what you expected from it. Thanks for bearing with me.
好了,這是本篇冗長的教程的結尾。 希望您能從中得到期望。 感謝您的支持。
PS: uWSGI + NGINX + Django is highly customizable to meet any large scale requirements. That being said, core optimization still lies at application level. How you code and make use of Django ORM or Raw SQL query, etc. will help you further.
PS:uWSGI + NGINX + Django是高度可定制的,可以滿足任何大規模的需求。 話雖如此,核心優化仍位于應用程序級別。 您如何編碼和利用Django ORM或Raw SQL查詢等將進一步幫助您。
翻譯自: https://www.freecodecamp.org/news/django-uwsgi-nginx-postgresql-setup-on-aws-ec2-ubuntu16-04-with-python-3-6-6c58698ae9d3/
aws v2.2.exe