ubuntu18 apache2 wsgi django pyenv virtualenv 搭建 https websocket 网站
部署django项目步骤比较繁琐。
- https双向认证 :服务器、客户端双向认证,通过安装自签名证书互相验证身份;
- websocket :使用channels库实现,再套一层ssl增加安全性;
- apache2+wsgi+虚拟环境 :wsgi进程守护,由于项目中改动了celery源码,需要独立虚拟环境。
文章目录
一、ubuntu环境
win10系统,使用vmware安装了ubuntu18服务器版,为方便项目部署,共享了d盘。
注意:挂载不能使用open-vm-tools,不然只有超级用户能访问挂载目录
VMware->虚拟机->安装VMware Tools
解压VMwareTools-xxx.tar.gz运行vmware-install.pl
sudo mount -t iso9660 /dev/cdrom /mnt
./vmware-install.pl
本地源
如果部署环境没有网络,需要创建本地源
在开发环境执行下列命令,制作离线包
sudo mkdir /offlinePackage
sudo cp -r /var/cache/apt/archives /offlinePackage
sudo chmod 777 -R /offlinePackage/
sudo apt-get install dpkg-dev
sudo dpkg-scanpackages /offlinePackage/archives/ /dev/null |gzip >/offlinePackage/Packages.gz
sudo cp /offlinePackage/Packages.gz /offlinePackage/archives/Packages.gz
tar cvzf offlinePackage.tar.gz /offlinePackage
在离线部署环境,设置本地源生效
sudo tar -xvf offlinePackage.tar.gz -C /
sudo vim /etc/apt/sources.list
# 在sources.list中添加下行,并注释掉其他内容
deb file:/// offlinePackage/
# 执行update命令使本地源生效
sudo apt-get update ---allow-insecure-repositories true
--allow-unauthenticated
# 可能需要这个命令
apt-get update -f
二、pyenv pyenv-virtualenv python环境
使用虚拟环境可以多个不同环境的项目共存
1. 安装
官方文档:pyenv,pyenv-virtualenv
安装需要使用以下命令
# 从github克隆项目
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtual
# 编辑.bash_profile
sudo vim ~/.bash_profile
# 在~/.bash_profile中添加如下代码
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
eval "$(pyenv virtualenv-init -)"
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# :wq!保存
exec "$SHELL"
# 重启shell
2. 使用
使用前可能需要安装这些库,python编译安装的依赖
sudo apt-get install -y zlib1g zlib1g-dbg zlib1g-dev gcc
使用pyenv install可以安装python不同版本,例如使用3.6.6
注意:–enable-shared 选项是使用共享库,否则不能安装mod_wsgi
env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.6.6
#可能需要安装dev包
pyenv install 3.6-dev
再使用virtualenv创建虚拟环境
#创建
pyenv virtualenv 3.6.6 project_venv
#激活进入虚拟环境
pyenv activate project_venv
安装库
#开发环境执行
pip freeze >requirements.txt
pip download -r requirements.txt -d pippackage#如果部署环境无网络
#虚拟环境执行
pip install -r requirements.txt
pip install --no-index --find-links=pippackage -r requirements.txt#如果部署环境无网络
三、apache2安装和wsgi配置
安装apache2
sudo apt-get install apache2 apache2-dev -y
编辑/etc/apache2/ports.conf
增加端口监听
# sudo vim /etc/apache2/ports.conf
Listen 8002 #websocket ssl代理端口
Listen 8889 #网站端口
Listen 9001 #网站 ssl代理端口
在虚拟环境中安装mod_wsgi
pip install mod_wsgi
# 安装完mod_wsgi需执行命令(可能需在python的bin文件夹下执行)
mod_wsgi-express module-config
将输出第一行 LoadModule wsgi_module “xxxxxxxxx” 复制
加到/etc/apache2/mods-available/wsgi.load中,再执行a2enmod
sudo a2enmod wsgi
四、django项目部署
1. 准备
静态文件
在项目目录下执行
python manage.py collectstatic
证书制作
- 制作ca根证书和server证书
OpenSSL生成CA证书及终端用户证书 - 制作客户端证书
#!/bin/bash
#使用类C风格for循环输出0~52
for ((index = 0; index <= 52; index++))
do
echo "$index"
openssl genrsa -out $index"_ca.key" 4096
openssl req -new -sha256 -out $index"_ca.csr" -key $index"_ca.key" -config ca.conf -batch
openssl x509 -req -days 3650 -in $index"_ca.csr" -signkey $index"_ca.key" -out $index"_ca.crt"
#1.生成私钥
openssl genrsa -out $index"_client_private.key" 2048
#3. 生成用户证书请求文件
openssl req -new -days 3650 -key $index"_client_private.key" -out $index"_client.csr" -config client.conf -batch
#4.ca对用户证书签名
openssl x509 \
-req \
-days 3650 \
-CA $index"_ca.crt" \
-CAkey $index"_ca.key" \
-CAcreateserial \
-in $index"_client.csr" \
-out $index"_client.crt" \
-extensions req_ext \
-extfile client.conf
#5. 生成p12
openssl pkcs12 -export -clcerts -in $index"_client.crt" -inkey $index"_client_private.key" -out $index"_client.p12" -password pass:csm_20180905
done
2. https部署
项目可以分成两个网站,网站本体和https代理,这样方便控制访问者身份。
ProxyRequests off 选项不要开启,否则任何人可以使用你的服务器做正向代理
文件中的path/to/project、path/to/certificat和username等路径,按需替换
a. 本体配置文件
# sudo vim /etc/apache2/sites-available/project.conf
<VirtualHost *:8889>
Alias /media/ /mnt/hgfs/path/to/project/media/#替换
Alias /static/ /mnt/hgfs/path/to/project/static/#替换
<Directory /mnt/hgfs/path/to/project/media/>#替换
Require all granted
</Directory>
<Directory /mnt/hgfs/path/to/project/static/>#替换
Require all granted
</Directory>
WSGIDaemonProcess my_project python-home=/home/username/.pyenv/versions/project_venv python-path=/mnt/hgfs/path/to/project#替换
WSGIProcessGroup my_project
WSGIScriptAlias / /mnt/hgfs/path/to/project/project/wsgi.py #替换
<Directory /mnt/hgfs/path/to/project>#替换
Require all granted
</Directory>
</VirtualHost>
b. 代理配置文件
# sudo vim /etc/apache2/sites-available/project_proxy.conf
<VirtualHost *:9001>
# ServerName 127.0.0.1
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*) https://%{SERVER_NAME}$1 [L,R]
SSLEngine on
SSLProtocol +TLSv1.1 +TLSv1.2
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES
SSLCertificateFile path/to/certificat/server.crt#替换
SSLCertificateKeyFile path/to/certificat/server.key#替换
SSLCACertificateFile path/to/certificat/client1_ca.crt#替换
SSLVerifyClient require
ProxyPreserveHost on
ProxyPass / http://127.0.0.1:8889/
ProxyPassReverse / http://127.0.0.1:8889/
</VirtualHost>
3. websocket部署
websocket 需要通过python manage.py runserver 0.0.0.0:8003 运行,因为apache好像不支持asgi
配置文件
# sudo vim /etc/apache2/sites-available/wss_proxy.conf
<VirtualHost *:8002>
ServerName 127.0.0.1
RewriteEngine On
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule ^(.*) ws://%{SERVER_NAME}$1 [P,L]
SSLEngine on
SSLProtocol TLSv1.2
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES
SSLHonorCipherOrder on
SSLCertificateFile /path/to/certificat/server.crt
SSLCertificateKeyFile /path/to/certificat/server.key
ProxyPass / ws://127.0.0.1:8003/
</VirtualHost>