sudo
配置权限。 你可以学习如何通过我们的运行设置此服务器初始设置指南 。
我们将在两个不同的虚拟环境中安装Django。这将允许您的项目及其需求单独处理。我们将创建两个示例项目,以便我们可以在多项目环境中运行这些步骤。
一旦我们有应用程序,我们将安装和配置uWSGI应用程序服务器。这将作为我们的应用程序的接口,它将客户端请求使用HTTP转换为我们的应用程序可以处理的Python调用。然后,我们将在uWSGI之前设置Nginx,以利用其高性能连接处理机制和易于实现的安全特性。
让我们开始吧。
virtualenv
,它可以创造Python的虚拟环境,并virtualenvwrapper
,它增加了一些实用性改进了virtualenv
工作流程。
我们将同时安装使用这些组件的pip
,Python的包管理器。我们可以从Debian仓库安装这个实用程序。
如果您在使用Python 2,建筑类型你的Django项目:
sudo apt-get update
sudo apt-get install python-pip
如果您正在使用Python 3,键入:
sudo apt-get update
sudo apt-get install python3-pip
现在,您已经pip
安装,我们可以安装virtualenv
和virtualenvwrapper
全球。
如果您正在使用Python 2,请键入:
sudo pip install virtualenv virtualenvwrapper
如果您正在使用Python 3,键入:
sudo pip3 install virtualenv virtualenvwrapper
安装这些组件,现在我们可以用它需要与合作的信息来配置我们的外壳virtualenvwrapper
脚本。 我们的虚拟环境都将在我们称为home文件夹放在一个目录内的Env
以方便访问。 这是通过一个叫做环境变量配置WORKON_HOME
。我们可以将其添加到我们的shell初始化脚本中,并且可以获取虚拟环境包装器脚本。
如果您正在使用Python 3和pip3
命令,你将有一个额外的行添加到您的shell初始化脚本,以及:
echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc
无论您使用的是哪个版本的Python,都需要运行以下命令:
echo "export WORKON_HOME=~/Env" >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
现在,请提供shell初始化脚本,以便您可以在当前会话中使用此功能:
source ~/.bashrc
您现在应该有一个名为目录Env
中的个人文件夹,将举行虚拟环境的信息。
virtualenvwrapper
脚本对提供给我们。
通过键入以下内容创建您的第一个虚拟环境与您的第一个网站或项目的名称:
mkvirtualenv firstsite
这将创建一个虚拟环境,安装Python和pip
在其中,并激活了环境。 您的提示将更改,以指示您现在在新的虚拟环境中操作。 它看起来是这样的: ( firstsite ) user @ hostname :~$
。 括号中的值是您的虚拟环境的名称。 通过安装任何软件pip
现在将安装到虚拟环境,而不是全局系统。这允许我们在每个项目的基础上隔离我们的包。
我们的第一步是安装Django本身。我们可以使用pip
这个没有sudo
,因为我们在我们的虚拟环境中进行本地安装这样的:
pip install django
安装Django后,我们可以通过键入以下内容创建我们的第一个示例项目:
cd ~
django-admin.py startproject firstsite
这将创建一个名为firstsite
你的home目录中。这是一个用于处理项目各个方面的管理脚本和用于容纳实际项目代码的同名的另一个目录。
移动到第一级目录,以便我们可以开始设置我们的示例项目的最低要求。
cd ~/firstsite
首先迁移数据库以初始化我们的项目将使用的SQLite数据库。如果您愿意,可以为应用程序设置备用数据库,但这不在本指南的范围之内:
./manage.py migrate
您现在应该有一个名为数据库文件db.sqlite3
在项目目录。现在,我们可以通过键入以下内容创建管理用户:
./manage.py createsuperuser
您必须选择用户名,提供联系人电子邮件地址,然后选择并确认密码。
接下来,使用文本编辑器打开项目的设置文件:
nano ~/firstsite/firstsite/settings.py
通过查找开始ALLOWED_HOSTS
指令。 这定义了地址或域名的白名单可用于连接到Django实例。 任何传入的请求与主机头不在此名单将引发异常。 Django要求您设置此项以防止某类安全漏洞。
在方括号中,列出与您的Django服务器相关联的IP地址或域名。每个项目都应在引号中列出,条目用逗号分隔。如果您希望请求整个域和任何子域,请在该条目的开头添加一个句点。在下面的代码段中,有几个注释掉的示例用于演示:
. . .
# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . .]
由于我们将设置Nginx为我们的网站服务,我们需要配置一个目录,它将保存我们网站的静态资产。这将允许Nginx直接服务这些,这将对性能产生积极的影响。我们将告诉Django将这些变成一个名为static
在我们的项目的基础目录。将此行添加到文件的底部以配置此行为:
. . .
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
保存并在完成后关闭文件。现在,收集我们网站的静态元素,并通过键入以下内容将其放在该目录中:
./manage.py collectstatic
您可以键入“是”以确认操作并收集静态内容。将有一个名为新目录static
在您的项目目录。
您可能必须调整防火墙设置,以允许流量到我们的Django开发服务器,我们将在端口8080上运行。
如果你正在运行一个ufw
防火墙,您可以通过键入允许通信端口8080:
sudo ufw allow 8080
如果您正在运行iptables
相反,你需要确切的命令取决于您当前的防火墙配置。 对于大多数配置 ,这个命令应该工作:
sudo iptables -I INPUT -p tcp --dport 8080 -j ACCEPT
有了这一切,我们可以通过临时启动开发服务器来测试我们的项目。要启动开发服务器,请键入:
./manage.py runserver 0.0.0.0:8080
这将在端口启动开发服务器8080
。 访问您的服务器的域名或IP地址,随后8080
在浏览器中:
http://server_domain_or_IP:8080
您应该看到如下所示的页面:
/admin
在浏览器的地址栏中的URL的末尾,你会被带到管理员登录页面:
createsuperuser
命令,登录到服务器。然后,您将可以访问管理界面:
cd ~
mkvirtualenv secondsite
pip install django
新的环境将被创建和改变,让你以前的虚拟环境。这个Django实例完全独立于您配置的另一个实例。这允许您独立管理它们并根据需要进行自定义。
创建第二个项目并移动到项目目录:
django-admin.py startproject secondsite
cd ~/secondsite
初始化数据库并创建管理用户:
./manage.py migrate
./manage.py createsuperuser
打开设置文件:
nano ~/secondsite/secondsite/settings.py
设置ALLOWED_HOSTS
你的第二个项目的域名,服务器的IP地址,或两者兼而有之,就像你的第一个项目做的:
ALLOWED_HOSTS = ['second_project_domain_or_IP', 'another_domain_or_IP', . . .]
添加静态文件的位置,就像在上一个项目中所做的那样:
. . .
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
保存并关闭文件。现在,通过键入以下内容将静态元素收集到该目录中:
./manage.py collectstatic
最后,启动开发服务器测试网站:
./manage.py runserver 0.0.0.0:8080
您应该检查常规网站:
http://server_domain_or_IP:8080
也登录管理网站:
http://server_domain_or_IP:8080/admin
当您确认一切正常工作时,在终端中键入CTRL-C以停止开发服务器。
deactivate
如果您需要再次在任一个Django站点上工作,您应该重新激活其各自的环境。你可以通过使用workon
命令:
workon firstsite
要么:
workon secondsite
再次,在您的网站上完成工作后停用:
deactivate
sudo apt-get install python-dev
如果你已经使用Python 3,键入:
sudo apt-get install python3-dev
现在,发展的文件都可以,我们可以通过安装在全球uWSGI pip
。
如果您正在使用Python 2,请键入:
sudo pip install uwsgi
如果您正在使用Python 3,键入:
sudo pip3 install uwsgi
我们可以通过传递其中一个站点的信息来快速测试此应用程序服务器。例如,我们可以通过键入以下内容来告诉它服务我们的第一个项目:
uwsgi --http :8080 --home /home/sammy/Env/firstsite --chdir /home/sammy/firstsite -w firstsite.wsgi
在这里,我们已经告诉uWSGI使用我们位于我们的虚拟环境的~/Env
目录,改变我们项目的目录,并使用wsgi.py
存储在我们内心中的文件firstsite
目录服务文件。 对于我们的演示,我们告诉它要服务于HTTP端口8080
。 如果你到服务器的域名,或在浏览器中,然后通过IP地址:8080
,你将再次看到你的网站(静态元素在/admin
界面,如CSS,将无法工作)。当您完成测试此功能时,在终端中键入CTRL-C。
/etc/uwsgi/sites
来存储配置文件。在创建目录后移动到目录:
sudo mkdir -p /etc/uwsgi/sites
cd /etc/uwsgi/sites
在这个目录中,我们将放置我们的配置文件。我们需要一个配置文件为我们正在服务的每个项目。该uWSGI过程可能需要配置文件在各种格式,但是我们会用.ini
文件,由于其简单。
为您的第一个项目创建一个文件,并在文本编辑器中打开它:
sudo nano firstsite.ini
在内部,我们必须从开始[uwsgi]
节标题。 我们所有的信息将在这个标题下面。 我们还将使用变量来使我们的配置文件更可重用。 头后,设置了一个名为变量project
与第一个项目的名称。 添加一个变量,名为uid
它保存您的sudo
用户名。
我们还将添加一个名为变量base
的路径到用户的主目录。 这会从我们使用设定的用户名来构建%(variable_name)
语法。这将被读取配置时的变量的值替换:
[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)
接下来,我们需要配置uWSGI,以便它能正确处理我们的项目。我们需要通过设置移动到根项目目录chdir
选项。我们可以使用相同的变量语法组合主目录和项目名称。
以类似的方式,我们将指出我们项目的虚拟环境。通过设置模块,我们可以准确地指示如何与我们的项目(通过导入“应用程序”,从可调用接口wsgi.py
项目目录中的文件)。这些项目的配置将如下所示:
[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)
# Next, add the lines below
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
我们要创建一个有5个工人的主进程。我们可以这样做:
[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
# Next, add these lines
master = true
processes = 5
接下来,我们需要指定uWSGI应该如何监听连接。在我们的uWSGI测试中,我们使用HTTP和网络端口。但是,由于我们将使用Nginx作为反向代理,我们有更好的选择。
而不是使用网络端口,因为所有组件都在单个服务器上运行,我们可以使用Unix套接字。这更安全,并提供更好的性能。这种socket将不会使用HTTP,而是将实施uWSGI的uwsgi
协议,它是一种快速二进制协议被设计用于与其他服务器进行通信。 Nginx的可以本地代理使用uwsgi
协议,所以这是我们最好的选择。
我们还将修改套接字的所有权和权限,因为我们将给予Web服务器写访问权限。我们将设置vacuum
,以便socket文件将在该服务停止时自动清理选项:
[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
master = true
processes = 5
# Finish off the configuration with the following lines
socket = /run/uwsgi/%(project).sock
chown-socket = %(uid):www-data
chmod-socket = 660
vacuum = true
有了这个,我们的第一个项目的uWSGI配置就完成了。保存并关闭文件。
使用变量设置文件的优点是它使它非常简单的重用。复制第一个项目的配置文件以用作第二个配置文件的基础:
sudo cp /etc/uwsgi/sites/firstsite.ini /etc/uwsgi/sites/secondsite.ini
使用文本编辑器打开第二个配置文件:
sudo nano /etc/uwsgi/sites/secondsite.ini
我们只需要更改此文件中的单个值,以使其适用于我们的第二个项目。修改project
与你使用你的第二个项目的名称变量:
[uwsgi]
project = secondsite
uid = sammy
base = /home/%(uid)
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
master = true
processes = 5
socket = /run/uwsgi/%(project).sock
chown-socket = %(uid):www-data
chmod-socket = 660
vacuum = true
保存并在完成后关闭文件。你的第二个项目现在应该准备好了。
/etc/systemd/system
目录中,其中用户创建单元文件保存。 我们将调用我们的文件uwsgi.service
:
sudo nano /etc/systemd/system/uwsgi.service
先从[Unit]
部分,它是用来指定的元数据和订购信息。我们将在这里简单地描述我们的服务:
[Unit]
Description=uWSGI Emperor service
接下来,我们将打开[Service]
部分。 我们将使用ExecStartPre
指令设置我们需要运行我们的服务器的作品。 这将确保该/run/uwsgi
目录中创建,我们的普通用户与拥有它www-data
组作为组所有者。 两者mkdir
的-p
标志和chown
命令返回成功,即使没有需要他们的操作。这是我们想要的。
对于实际的启动命令,由指定的ExecStart
指令,我们将指向uwsgi
可执行文件。 我们会告诉它以“皇帝模式”下运行,使其能够管理多个应用程序中使用它找到的文件/etc/uwsgi/sites
。 我们还将添加systemd所需的部分以正确管理进程。 这些是从uWSGI文档采取这里 。
[Unit]
Description=uWSGI Emperor service
[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown sammy:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
现在,我们需要做的是添加[Install]
部分。这允许我们指定何时应该自动启动服务。我们将把我们的服务绑定到多用户系统状态。每当系统设置为多个用户(正常操作条件)时,我们的服务将被激活:
[Unit]
Description=uWSGI Emperor service
[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown sammy:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
[Install]
WantedBy=multi-user.target
完成后,保存并关闭文件。
我们将无法在这一点上成功启动该服务,因为它依赖于www-data
的用户是可用的。我们将不得不等待启动uWSGI服务,直到Nginx安装后。
sudo apt-get install nginx
一旦Nginx安装,我们可以为每个项目创建一个服务器块配置文件。从第一个项目开始,通过创建服务器块配置文件:
sudo nano /etc/nginx/sites-available/firstsite
在里面,我们可以通过指示我们的第一个项目应该可访问的端口号和域名来启动我们的服务器块。我们假设您有一个域名:
server {
listen 80;
server_name firstsite.com www.firstsite.com;
}
接下来,如果找不到favicon,我们可以告诉Nginx忽略错误。我们还将它指向我们的静态文件目录的位置,我们收集我们的网站的静态元素:
server {
listen 80;
server_name firstsite.com www.firstsite.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/sammy/firstsite;
}
}
接下来,我们可以创建一个捕获位置块,将所有其他查询直接传递到我们的应用程序。我们将包括uwsgi
在发现参数/etc/nginx/uwsgi_params
并通过流量的uWSGI服务器设置了socket:
server {
listen 80;
server_name firstsite.com www.firstsite.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/sammy/firstsite;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/firstsite.sock;
}
}
这样,我们的第一个服务器块就完成了。您可以保存并退出文件。
我们将使用它作为我们的第二个项目的Nginx配置文件的基础。立即复制:
sudo cp /etc/nginx/sites-available/firstsite /etc/nginx/sites-available/secondsite
在文本编辑器中打开新文件:
sudo nano /etc/nginx/sites-available/secondsite
在这里,你将不得不改变任何参考firstsite
与参考secondsite
。 您还必须修改server_name
,以便您的第二个项目是为了响应不同的域名。当你完成后,它将看起来像这样:
server {
listen 80;
server_name secondsite.com www.secondsite.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/sammy/secondsite;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/secondsite.sock;
}
}
保存并在完成后关闭文件。
接下来,链接您的新的配置文件来的Nginx的sites-enabled
目录,使他们:
sudo ln -s /etc/nginx/sites-available/firstsite /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/secondsite /etc/nginx/sites-enabled
通过键入以下内容检查配置语法:
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
如果未检测到语法错误,您可以重新启动Nginx服务以加载新配置:
sudo systemctl restart nginx
如果你记得早些时候,我们从来没有真正启动uWSGI服务器。现在通过键入:
sudo systemctl start uwsgi
我们需要再次调整防火墙。我们不再需要端口8080打开,因为我们代理通过Nginx,所以我们可以删除该规则。然后我们可以添加一个异常,以允许流量到Nginx进程。
如果你正在使用ufw
,您可以通过键入做到这一点:
sudo ufw delete allow 8080
sudo ufw allow 'Nginx Full'
如果您在使用iptables
,适当的命令会是这个样子:
sudo iptables -D INPUT -p tcp --dport 8080 -j ACCEPT
sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT
现在您应该可以访问他们各自的域名访问您的两个项目。公共和管理接口都应按预期工作。
如果这样做顺利,您可以通过键入以下命令,使这两个服务在启动时自动启动:
sudo systemctl enable nginx
sudo systemctl enable uwsgi
关注云架构公众号
Linux入门
QQ交流群:308781113