环境:
python3
开发环境有网络,生产环境无网络
思路:
在开发环境创建python的虚拟环境,在虚拟环境中pip install需要的包,后将虚拟环境移到生产环境(需要做一些修改)
我的python虚拟环境名: env
项目名: mainserver
详细:
创建虚拟环境:mkvirtualenv -p python3 env
workon env 安装项目需要的包:
pip3 install Django==1.11.28
pip3 install gunicorn==19.8.1
pip3 install qrcode==6.1
虚拟环境迁移:
我是将虚拟环境放到了项目目录下,项目方到了/opt目录:/opt/mainserver
目录结构:
├── mainserver
├── conf
│ └── mainserver.conf
├── c_so
│ └── gen.so
├── db
│ └── mainDB.sqlite3
├── env # 虚拟环境
│ ├── bin
│ ├── lib
│ ├── lib64
│ ├── pyvenv.cfg
│ └── share
├── logs
│ ├── gunicorn_access.log
│ ├── gunicorn_error.log
│ └── mainhub.log
├── mainserver
│ ├── gunicorn_conf.py
│ ├── manage.py
│ ├── mainserver
│ ├── __pycache__
│ ├── stup-sqlite.py
│ ├── users
│ └── utils
├── pids
│ └── main.pid
├── README.txt
├── main.sh
└── stup-sqlite.sh
需要修改虚拟环境中的 activate、pip3、gunicorn 文件
activate:
vim /opt/mainserver/env/bin/activate
找到 VIRTUAL_ENV,大概在47行,值改为迁移过来的虚拟环境目录
VIRTUAL_ENV='opt/mainserver/env'
作用是,通过命令 source /opt/mainserver/env/bin/activate 就能进到虚拟环境中
[root@host opt]# source /opt/mainserver/env/bin/activate
(env) [root@host-172-30-81-226 opt]#
# 可以看到,进入到了 env环境
pip3:
vim /opt/mainserver/env/bin/pip3.py
将头中指定使用的python,改为你虚拟环境中的python
#!/opt/mainserver/env/bin/python3 # 修改此行
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
gunicorn:
vim /opt/mainserver/env/bin/gunicorn.py
将头中指定使用的python,改为你虚拟环境中的python
#!/opt/mainserver/env/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from gunicorn.app.wsgiapp import run
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(run())
修改后就可以使用 gunicorn -c gunicorn_conf.py mainserver.wsgi:application 来启动项目
若出现 无 gunicorn 命令,就是配置没有修改对
其他包
我安装了 qrcode 包,安装后可以通过命令 qr "123" > 123.png 生成二维码图片,
若像上面那样迁移了虚拟环境,也需要修改 qr.py
vim /opt/mainserver/env/bin/qr.py
#!/opt/mainserver/env/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from qrcode.console_scripts import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
在迁移的虚拟环境中安装包
1.按照上面的方式修改完相关配置
2.指定python的包安装路径为咱们迁移的env
export PYTHONPATH=/opt/mainserver/env/lib/python3.5/site-packages
3.指定使用咱们迁移的env里的python
export PATH=$PATH:$HOME/bin:/opt/mainserver/env/bin/python3.5
4.进入env环境,就可以通过pip3 install 下载包了
source /opt/mainserver/env/bin/activate
配置项目一键启动
gunicorn_conf.py
# -*- coding: utf-8 -*-
# gunicorn_config.py
import logging
import logging.handlers
from logging.handlers import WatchedFileHandler
import os
import multiprocessing
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
LOG_DIR_PATH = os.path.join(os.path.dirname(BASE_DIR), "logs")
if not os.path.exists(LOG_DIR_PATH):
os.makedirs(LOG_DIR_PATH)
bind = '0.0.0.0:8000' #绑定ip和端口号
backlog = 512 #监听队列
# chdir = '/home/test/server/bin' #gunicorn要切换到的目的工作目录
timeout = 30 #超时
worker_class = 'sync' #使用gevent模式,还可以使用sync 模式,默认的是sync模式
# workers = multiprocessing.cpu_count() * 2 + 1 #进程数
workers = 2 #进程数
threads = 2 #指定每个进程开启的线程数
LOG_DIR_PATH = os.path.join(os.path.dirname(BASE_DIR), "logs")
loglevel = 'info' #日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'
accesslog = "{}/gunicorn_access.log".format(LOG_DIR_PATH) #访问日志文件
errorlog = "{}/gunicorn_error.log".format(LOG_DIR_PATH) #错误日志文件
main.sh
#!/bin/bash
## service name
curPath=$(readlink -f "$(dirname "$0")")
#项目的目录
SERVICE_DIR=${curPath}/mainserver
#服务的名字
SERVICE_NAME=mainserver
#gunicorn配置
gunicorn_exe=${curPath}/env/bin/gunicorn
SERVICE_CONF=gunicorn_conf.py
#pid存放的位置
PID=${curPath}/pids/main.pid
#python env
export PYTHONPATH=${curPath}/env/lib/python3.5/site-packages
source ${curPath}/env/bin/activate
export PATH=$PATH:$HOME/bin:${curPath}/env/bin/python3
cd $SERVICE_DIR
start(){
#gunicorn -c gunicorn_conf.py nfs-license-mainserver.wsgi:application
#echo $! > $SERVICE_DIR/$PID
#nohup gunicorn -c gunicorn_conf.py nfs-license-mainserver.wsgi:application>/dev/null 2>&1 &
#$PYTHON3 ${$gunicorn_exe} -c gunicorn_conf.py nfs-license-mainserver.wsgi:application>
$PYTHON $gunicorn_exe -c gunicorn_conf.py nfs-license-mainserver.wsgi:application>/dev/null 2>&1 &
echo $! > $PID
echo "*** start $SERVICE_NAME ***"
}
stop(){
#kill `cat $SERVICE_DIR/$PID`
#rm -rf $SERVICE_DIR/$PID
kill `cat $PID`
rm -rf $PID
echo "*** stop $SERVICE_NAME ***"
sleep 2
P_ID=`ps -ef | grep -w "$SERVICE_NAME" | grep -v "grep" | awk '{print $2}'`
if [ "$P_ID" == "" ]; then
echo "*** $SERVICE_NAME process not exists or stop success ***"
else
echo "*** $SERVICE_NAME process pid is:$P_ID ***"
echo "*** begin kill $SERVICE_NAME process,kill is:$P_ID ***"
kill -9 $P_ID
fi
}
f_usage() {
echo "USAGE: restart [options]"
echo "OPTIONS:"
echo " start"
echo " stop "
echo " restart"
}
case "$1" in
"start")
start
;;
"stop")
stop
;;
"restart")
stop
sleep 2
start
echo "*** restart $SERVICE_NAME ***"
;;
*)
f_usage
;;
esac
exit 0
./main.sh start
./main.sh stop
./main.sh restart
nginx
user root;
events {
worker_connections 1024; ## Default: 1024
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 82;
server_name 172.30.81.xxx;
proxy_set_header X-Forwarded-For $remote_addr;
server_tokens off;
# 配置后端资源
location /api {
proxy_pass http://127.0.0.1:8000;
proxy_pass_header Authorization;
proxy_pass_header WWW-Authenticate;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header X-Forwarded-Host $server_name;
proxy_read_timeout 1200s;
# used for view/edit office file via Office Online Server
client_max_body_size 0;
access_log /var/log/nginx/nfs-license-main.access.log;
error_log /var/log/nginx/nfs-license-main.error.log;
}
# 配置静态资源
location / {
#proxy_set_header X-Forwarded-Proto https;
#root /root/nfs-license/nfs-license-mainweb/dist
alias /opt/mainweb/dist/; #静态资源路径
}
location /media {
#proxy_set_header X-Forwarded-Proto https;
#root /root/nfs-license/nfs-license-web/dist
alias /opt/maintserver/media/;
}
}
}