在gninx上使用Django设置套接字

时间:2016-09-12 12:45:04

标签: python django sockets nginx redis

我在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不应该是一个复杂的错误,但经过多天的修复后,我不知道问题是什么,以及我是否正常。

2 个答案:

答案 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()命令,返回文件描述符检出人员套接字。

相关问题