我在nginx上运行了一个Django应用程序。这个应用程序使用套接字(据我所知)应该被代理。所以我在配置nginx和其他东西时遇到了麻烦。相同的应用程序在Apache / 2.4.7上运行正常,所以我认为这不是编程错误。
套接字使用基于Django-Channels,后端与Channels getting started的代码非常相似。
对于服务器配置,我使用了this手册。
一开始我只有一个问题:在套接字创建时我得到了200个请求答案而不是101个。经过多次操作(配置和更新的版本安装)和信息收集后,我来到了现状:
我分别为套接字启动uwsgi:
uwsgi --virtualenv /home/appname/env/ --http-socket /var/run/redis/redis.sock --http-websock --wsgi-file /home/appname/appname/appname/wsgi.py
关于套接字创建的这一步var socket = new WebSocket("ws://appname.ch/ws/64");
我得到了
WebSocket connection to 'ws://appname.ch/ws/64' failed: Error during WebSocket handshake: Unexpected response code: 502
并确定
2016/09/12 12:00:26 [crit] 30070#0: *2141 connect() to unix:/var/run/redis/redis.sock failed (13: Permission denied) while connecting to upstream, client: 140.70.82.220, server: appname.ch,, request: "GET /ws/64 HTTP/1.1", upstream: "http://unix:/var/run/redis/redis.sock:/ws/64", host: "appname.ch"
在nginx错误日志中。
chmod 777 /var/run/redis/redis.sock
后我得到回应
WebSocket connection to 'ws://appname.ch/ws/64' failed: Error during WebSocket handshake: Unexpected response code: 404
和uwsgi
[pid: 6572|app: 0|req: 1/1] 0.0.0.0 () {46 vars in 916 bytes} [Mon Sep 12 12:01:29 2016] GET /ws/64 => generated 3357 bytes in 24 msecs (HTTP/1.1 404) 2 headers in 80 bytes (1 switches on core 0)
nginx.conf文件
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
redis.conf
daemonize yes
pidfile /var/run/redis/redis-server.pid
port 6379
unixsocket /var/run/redis/redis.sock
unixsocketperm 777
timeout 0
loglevel notice
logfile /var/log/redis/redis-server.log
databases 16
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename dump.rdb
dir /var/lib/redis
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
/ etc / nginx / sites-enabled / appname
server {
listen 80;
server_name appname.ch, 177.62.206.170;
#charset koi8-r;
client_max_body_size 8M;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
include uwsgi_params;
uwsgi_pass unix:///home/appname/appname/app.sock;
#add_header Access-Control-Allow-Origin *;
}
location /ws/ {
#proxy_redirect off;
proxy_pass http://unix:/var/run/redis/redis.sock;
#proxy_http_version 1.1;
#proxy_set_header Upgrade $http_upgrade;
#proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
location /static {
alias /home/appname/appname/static_files;
}
location /media {
alias /home/appname/appname/media;
}
}
uwsgi.ini
[uwsgi]
chdir=/home/appname/appname
env=DJANGO_SETTINGS_MODULE=appname.settings
wsgi-file=appname/wsgi.py
master=True
pidfile=/home/appname/appname/appname-master.pid
vacuum=True
max-requests=5000
daemonize=/home/appname/appname/uwsgi.log
socket=/home/appname/appname/app.sock
virtualenv=/home/appname/env
uid=appname
gid=appname
Django app settings.py
"""
Django settings for appname project.
For more information on this file, see
https://docs.djangoproject.com/en/1.7/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.7/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ''
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ALLOWED_HOSTS = ['.appname.ch', '177.62.206.170', '127.0.0.1']
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'customers',
'projects',
'moodboard',
'channels',
'debug_toolbar',
'rest_framework',
'appname',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'appname.urls'
WSGI_APPLICATION = 'appname.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static_files'),
)
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'templates'),
)
AUTH_PROFILE_MODULE = 'customers.Customer'
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
LOGIN_REDIRECT_URL = '/accounts/home'
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgi_redis.RedisChannelLayer",
"CONFIG": {
"hosts": [("localhost", 6379)],
},
"ROUTING": "appname.routing.channel_routing",
},
}
应用网址
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.contrib.auth import views as auth_views
from projects.views import ProjectViewSet
from customers.views import UserHomeView, RegistrationView, CustomerViewSet, UserViewSet
from moodboard.views import MoodBoardViewSet, BoardItemViewSet, BoardTextViewSet, ShareMoodBoardItem, LiveViewSet
from rest_framework import routers
from django.conf import settings
from django.conf.urls.static import static
router = routers.DefaultRouter()
router.register(r'projects', ProjectViewSet)
router.register(r'moodboards', MoodBoardViewSet)
router.register(r'items', BoardItemViewSet)
router.register(r'texts', BoardTextViewSet)
router.register(r'share', ShareMoodBoardItem)
router.register(r'customers', CustomerViewSet)
router.register(r'users', UserViewSet)
router.register(r'live', LiveViewSet)
urlpatterns = patterns('',
url(r'^$', 'appname.views.home', name='landing_page'),
url(r'^api/', include(router.urls)),
url(r'^accounts/login/$', auth_views.login, name='login'),
url(r'^accounts/logout/$', auth_views.logout, name='logout'),
url(r'^accounts/home/$', UserHomeView.as_view(), name='home'),
url(r'^accounts/register/$', RegistrationView.as_view(), name='registration'),
url(r'^admin/', include(admin.site.urls)),
url(r'^customers/', include('customers.urls')),
url(r'^projects/', include('projects.urls')),
url(r'^moodboard/', include('moodboard.urls')),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
)
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)root
nginx version: 1.6.2
Redis server version: 2.4.14
uwsgi version: 2.1
Django version: 1.8.0 'final'
Python version: 2.7.3
似乎404不应该是一个复杂的错误,但经过多天的修复后,我不知道问题是什么,以及我是否正常。
答案 0 :(得分:0)
首先,不要尝试手动创建袜子。 只需设置一个路径,它就会自动创建。
这是示例nginx和uwsgi conf:
server {
root /your/djang/app/main/folder/;
# the port your site will be served on
listen 80;
server_name your-domain.com *.your-domain.com # if you have subdomains
charset utf-8;
access_log /path/to/logs/if/you/have/access_log.log
error_log /path/to/logs/if/you/have/error_log.log
# max upload size
client_max_body_size 1G;
location /media/ {
alias /path/to/django/media/if/exist/;
}
location /static/ {
alias /path/to/django/static/if/exist/;
}
# Note three slash
location / {
uwsgi_pass unix:///home/path/to/sock/file/your-sock.sock
}
}
这个cna是你的uwsgi配置文件
# suprasl_uwsgi.ini file
[uwsgi]
uid = www-data
gid = www-data
chmod-socket = 755
chown-socket = www-data
# Django-related settings
# the base directory (full path)
chdir = /your/djang/app/main/folder/
# Django's wsgi file
wsgi-file = /your/djang/app/main/folder/main-folder/wsgi.py;
# the virtualenv (full path)
home = /your/env/folder/;
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 2
# the socket (use the full path to be safe
socket = /home/path/to/sock/file/your-sock.soc
logto = /path/to/logs/if/you/have/uwsgi_logs.log
您只需运行此命令:
uwsgi --ini your_uwsgi_file.ini
# - - 选项用于指定文件
答案 1 :(得分:0)
如果您打算手动创建套接字,则可以使用python。 试试:
python -c "import socket as s; sock = s.socket(s.AF_UNIX); sock.bind('/tmp/test.sock')"
但这不会创建套接字。如果套接字在Web服务器请求时由应用程序创建,则由应用程序创建。
所以我们只需要声明我们的nginx.conf文件映射
location /{
include uwsgi_params;
uwsgi_pass unix:///to/where/you wish/the/file.sock;
}
服务器将运行socket()命令,返回文件描述符检出人员套接字。