因為我的個人網站 restran.net 已經啟用,博客園的內容已經不再更新。請訪問我的個人網站獲取這篇文章的最新內容,CentOS 環境下基於 Nginx uwsgi 搭建 Django 站點
以下用一個網站 ocean_monitor 舉例
MySQL 安裝與配置
安裝
MariaDB is shipped in the CentOS repo as of CentOS 7 instead of mysql.
if you still want to install mysql you need to add mysql rpm dependency into your yum repo.
sudo yum -y install mariadb-server mariadb-devel mariadb
sudo systemctl start mariadb.service
sudo systemctl enable mariadb.service
配置
登錄
mysql -u root -p
創建用戶
CREATE USER ocean_monitor IDENTIFIED BY 'ocean_monitor_pwd';
上面建立的用戶可以在任何地方登陸。如果要限制在固定地址登陸,比如 localhost 登陸:
CREATE USER ocean_monitor@localhost IDENTIFIED BY 'ocean_monitor_pwd';
創建數據庫
# 使用utf8編碼,否則中文會有問題
CREATE DATABASE ocean_monitor character set utf8;
授權 ocean_monitor 用戶擁有 ocean_monitor 數據庫的所有權限
grant all on ocean_monitor.* to ocean_monitor identified by 'ocean_monitor_pwd';
如果是限制在 localhost 登錄的,則使用
grant all on ocean_monitor.* to ocean_monitor@localhost identified by 'ocean_monitor_pwd';
使用 PIP 安裝依賴
為mysql-python安裝依賴,這樣才能編譯安裝
如果是Ubuntu用戶
sudo apt-get install build-essential python-dev libmysqlclient-dev python-mysqldb
如果是Centos用戶
yum install gcc python-devel
安裝所有的依賴
# requirements.txt 是 django 項目目錄下,填寫的依賴包信息
pip install -r requirements.txt
測試 uWSGU
創建一個測試文件
# test.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return ["Hello World"] # python2
#return [b"Hello World"] # python3
然后,Run uWSGI:
uwsgi --http :8000 --wsgi-file test.py
如果出現錯誤,!!! no internal routing support, rebuild with pcre support !!!
sudo apt-get install libpcre3 libpcre3-dev
sudo pip uninstall uwsgi
sudo apt-get remove uwsgi
sudo pip install uwsgi
打開下面url,瀏覽器上應該顯示hello world
http://example.com:8000
如果顯示正確,說明下面3個環節是通暢的:
the web client <-> uWSGI <-> Python
測試Django
我看別人用的是 --module mysite.wsgi,但是建 Django項目時,並沒有生成這個文件,這里十分奇怪。因此,使用 Django 生成的 wsgi.py
uwsgi --http :8000 --wsgi-file wsgi.py
如果顯示正確,說明下面3個環節是通暢的:
the web client <-> uWSGI <-> Django
Nginx 安裝與配置
Nginx 安裝
http://cantgis.blog.51cto.com/5788192/1540004
配置站點
vim /etc/nginx/conf.d/ocean_monitor.conf
添加配置信息
# ocean_monitor.conf
# the upstream component nginx needs to connect to
upstream django_ocean_monitor {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
# for a web port socket (we'll use this first)
server 127.0.0.1:8108;
}
# configuration of the server
server {
# the port your site will be served on
listen 8008;
# the domain name it will serve for
# substitute your machine's IP address or FQDN
# Django 的 settings.py 文件中的 ALLOWED_HOSTS 要加上這里設置的 server_name
server_name localhost;
charset utf-8;
gzip on;
gzip_min_length 1000;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 3;
gzip_vary on;
# 禁用對 IE 6 使用 gzip 壓縮
gzip_disable "MSIE [1-6]\.";
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/xml+rss application/json;
## Individual nginx logs
access_log /var/log/nginx/ocean_monitor_access.log;
error_log /var/log/nginx/ocean_monitor_error.log;
# max upload size
client_max_body_size 8M; # adjust to taste
# Django media
location /media {
# your Django project's media files - amend as required
alias /home/python/ocean_monitor/media;
}
location /static {
# your Django project's static files - amend as required
alias /home/python/ocean_monitor/static;
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django_ocean_monitor;
# the uwsgi_params file you installed
# 增加 nginx 配置, uwsgi_params 文件在 /etc/nginx/ 目錄下
include /etc/nginx/uwsgi_params;
}
}
測試 nginx 的配置文件的語法是否正確
sudo nginx -t
重啟 nginx
service nginx restart
Django 配置
settings.py 配置
設置 ALLOWED_HOSTS
Django gives Bad Request (400) when DEBUG = False
The ALLOWED_HOSTS list should contain fully qualified host names, not urls. Leave of the port and the protocol. If you are using 127.0.0.1, I'd add localhost to the list too
ALLOWED_HOSTS = [
# 加上本機的IP地址
'192.168.137.146',
'127.0.0.1',
'localhost'
]
You could also use * to match any host:
ALLOWED_HOSTS = ['*']
設置 DATABASES
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'ocean_monitor',
'USER': 'ocean_monitor',
'PASSWORD': 'ocean_monitor_pwd',
'HOST': 'localhost',
'PORT': '3306',
}
}
初始化數據庫
python manage.py syncdb
啟動一下,測試 Django 有沒有問題
python manage.py runserver 0.0.0.0:8080
uWSGI 配置文件
在 Django 項目的根目錄添加 uwsgi.ini 文件
# uwsgi.ini file
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /home/python/ocean_monitor
# Django's wsgi file
wsgi-file = /home/python/ocean_monitor/ocean_monitor/wsgi.py
# module = index.wsgi:application
# the virtualenv (full path)
# home = /path/to/virtualenv
daemonize = /home/python/ocean_monitor/ocean_monitor.log
# process-related settings
# master
master = true
pidfile = /tmp/ocean_monitor_master.pid
# maximum number of worker processes
processes = 3
# the socket (use the full path to be safe
# socket = /home/python/ocean_monitor/ocean_monitor.sock
socket = 127.0.0.1:8108
# ... with appropriate permissions - may be needed
chmod-socket = 664
# clear environment on exit
vacuum = true
uwsgi 啟動與結束
# 啟動
uwsgi --ini uwsgi.ini
# 重啟
uwsgi --reload /tmp/ocean_monitor_master.pid
# 結束
uwsgi --stop /tmp/ocean_monitor_master.pid
如果出現錯誤 signal_pidfile()/kill(): No such process [core/uwsgi.c line 1627],是由於 ocean_monitor_master.pid 的進程ID不正確,修改/tmp/ocean_monitor_master.pid為正確的pid就可以。
使用如下命令,查詢指定端口的進程id
sudo netstat -ap | grep 8108
修改 /tmp/ocean_monitor_master.pid 的進程id值
vim /tmp/ocean_monitor_master.pid
使用 supervisor 啟動 celery-worker 及 celery-beat
安裝 supervisor
安裝
pip install supervisor
安裝方法請參考
http://www.iitshare.com/supervisord-manage-process.html
生成配置文件
安裝好supervisor之后,默認是沒有生成配置文件的。可以通過以下命令生成配置文件
echo_supervisord_conf > /etc/supervisord.conf
啟動
supervisord -c /etc/supervisord.conf # 到指定路徑下去找配置文件
如果出現
another program is already listening on a port that one of our HTTP servers is configured to use
sudo unlink /etc/supervisor.sock
然后再次運行
supervisord -c /etc/supervisord.conf
supervisor 管理
supervisor 安裝完成后有兩個可用的命令行 supervisor 和 supervisorctl,命令使用解釋如下:
supervisord,初始啟動Supervisord,啟動、管理配置中設置的進程。
supervisorctl stop programxxx,停止某一個進程(programxxx),programxxx為[program:chatdemon]里配置的值,這個示例就是chatdemon。
supervisorctl start programxxx,啟動某個進程
supervisorctl restart programxxx,重啟某個進程
supervisorctl stop groupworker: ,重啟所有屬於名為groupworker這個分組的進程(start,restart同理)
supervisorctl stop all,停止全部進程,注:start、restart、stop都不會載入最新的配置文件。
supervisorctl reload,載入最新的配置文件,停止原有進程並按新的配置啟動、管理所有進程。
supervisorctl update,根據最新的配置文件,啟動新配置或有改動的進程,配置沒有改動的進程不會受影響而重啟。
注意:顯示用stop停止掉的進程,用reload或者update都不會自動重啟。
設置配置文件
vim /etc/supervisord.conf
在文件最后添加如下信息
[program:ocean_monitor_celery_worker]
process_name = ocean_monitor_celery_worker
command=python /home/python/ocean_monitor/manage.py celery worker --loglevel=info
directory=/home/python/ocean_monitor
autorestart=true
redirect_stderr=true
stdout_logfile = /var/log/supervisord/ocean_monitor_celery_worker.log
loglevel=info
[program:ocean_monitor_celery_beat]
process_name = ocean_monitor_celery_beat
command=python /home/python/ocean_monitor/manage.py celery beat --loglevel=info
directory=/home/python/ocean_monitor
autorestart=true
redirect_stderr=true
stdout_logfile = /var/log/supervisord/ocean_monitor_celery_beat.log
loglevel=info
用 supervisor 運行前,可以先在命令行下啟動測試一下
python manage.py celery beat --loglevel=info
python manage.py celery worker --loglevel=info
啟動
# 根據最新的配置文件,啟動新配置或有改動的進程
# 配置沒有改動的進程不會受影響而重啟
supervisorctl update
防火牆設置及 SELinux 問題
設置防火牆開放端口(iptables)
/sbin/iptables -I INPUT -p tcp --dport 8008 -j ACCEPT
nginx permission denied 問題
因為忘記了 selinux 的問題,導致 trouble shooting 耽誤了不少時間。
由於SELinux的問題,會導致nginx nginx permission denied 的問題,需要將 selinux 關閉。
查看SELinux狀態:
# 如果SELinux status參數為enabled即為開啟狀態
/usr/sbin/sestatus -v
也可以用 getenforce 這個命令檢查
關閉SELinux
# 只是臨時關閉(不用重啟機器),重啟后問題仍然出現
# 設置SELinux 成為permissive模式
setenforce 0
# setenforce 1 # 設置SELinux 成為enforcing模式
永久關閉,需要通過修改配置文件,但是需要重啟機器:
vim /etc/selinux/config
將SELINUX=enforcing 改為 SELINUX=disabled,重啟機器即可
shutdown -r now