Dockerized Django chat app using gunicorn, nginx for reverse proxy (static files). I managed to get stuck trying to get the websockets to work, but I can't connect to daphne: daphne -p 8001 project.asgi:application. The app only says, "Connection refusesed for upstream localhost:8001". I'm using django-channels and redis and on local everything is working fine.
Am I missing something?
Here are some files:
nginx.conf
upstream project {
server web:8000;
}
upstream websocket {
server localhost:8001;
}
server {
listen 80;
location /ws/ {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
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;
}
location / {
proxy_pass http://project;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /home/app/web/staticfiles/;
}
}
asgi.py
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
django_asgi_app = get_asgi_application()
from channels.auth import AuthMiddlewareStack
import scrumboard.routing
application = ProtocolTypeRouter({
"http": django_asgi_app,
'websocket': AuthMiddlewareStack(
URLRouter(
scrumboard.routing.websocket_urlpatterns
)
)
})
settings.py
"""
Django settings for project project.
Generated by 'django-admin startproject' using Django 4.1.2.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.1/ref/settings/
"""
from pathlib import Path
import os
from decouple import config
# Build paths inside the project like this: BASE_DIR / 'subdir'.
from django.template.context_processors import media
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
SECRET_KEY = config("SECRET_KEY")
DEBUG = int(config("DEBUG", default=0))
# 'DJANGO_ALLOWED_HOSTS' should be a single string of hosts with a space between each.
# For example: 'DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]'
ALLOWED_HOSTS = config("DJANGO_ALLOWED_HOSTS").split(" ")
CSRF_TRUSTED_ORIGINS = ['http://localhost:1337']
CORS_ALLOWED_HOSTS = ['http://localhost:1337']
# Application definition
INSTALLED_APPS = [
'channels',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'scrumboard',
'rest_framework'
]
ASGI_APPLICATION = 'project.asgi.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer'
}
}
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'project.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'project.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": os.environ.get("SQL_ENGINE", "django.db.backends.sqlite3"),
"NAME": os.environ.get("SQL_DATABASE", BASE_DIR / "db.sqlite3"),
"USER": os.environ.get("SQL_USER", "user"),
"PASSWORD": os.environ.get("SQL_PASSWORD", "password"),
"HOST": os.environ.get("SQL_HOST", "localhost"),
"PORT": os.environ.get("SQL_PORT", "5432"),
}
}
# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = 'static/'
STATIC_ROOT = BASE_DIR / "staticfiles"
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/socket-server/', consumers.ChatConsumer.as_asgi())
]
docker-compose.yml
version: '3.8'
services:
web:
build:
context: .
dockerfile: Dockerfile.prod
command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/staticfiles
expose:
- "8000:8000"
env_file:
- ./.env.prod
depends_on:
- db
container_name: "chat_app_prod"
db:
image: postgres
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./.env.prod.db
container_name: "db_prod"
nginx:
build: nginx
volumes:
- static_volume:/home/app/web/staticfiles
- ./nginx/chat-app-cert.pem:/etc/nginx/chat-app-cert.pem
- ./nginx/chat-app-key.pem:/etc/nginx/chat-app-key.pem
ports:
- "1337:80"
- "443:443"
depends_on:
- web
redis:
image: redis
ports:
- "6379:6379"
volumes:
postgres_data:
static_volume:
Related
I built a python web framework by using django, and I want to deploy it with nginx and gunicorn. However, I keep getting prompted for error about "Not Found: /static/answer/result.png". If I didn't use nginx adnd gunicorn I wouldn't get this error. I don't know what went wrong, please help me, thank you.
(1) settings.py file:
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = '...%a..............'
DEBUG = True
ALLOWED_HOSTS = ["127.0.0.1", "192.168.43.90", "192.168.2.229"]
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
"gunicorn",
'UserProfile',
'ImageRecognition',
"KuaiChao",
"HuaXiao"
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'LPAI.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'LPAI.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
STATIC_ROOT = "static/"
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
os.path.join(BASE_DIR, "templates"),
)
(2) /etc/nginx/sites-avaiable/default file
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name 192.168.2.229;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
proxy_pass 192.168.2.229:5000;
proxy_set_header Host $http_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-Proto $scheme;
}
location /static {
autoindex on;
alias /home/guomin/resource/gitee/lapi_lz/static; # django app static file
# root /root/exampledir/static/;
}
}
(3) The command I used to start django: gunicorn LPAI.wsgi:application -w 4 -b 192.168.2.229:5000
(4) I get error: Not Found: /static/answer/EJE005/EJE005_1-1367351883672326145-1367316751137640449-result.png
Note that this image exists and its path is /home/guomin/resource/gitee/lapi_lz/static/answer/EJE005/EJE005_1-1367351883672326145-1367316751137640449-result.png
The above is all the relevant information, please help me.
After debug=False in my settings. Images from database not showing up otherwise they were. Static files are showing up real good. Even my media files were showing up before debug=False. Database has correct addresses of files but covers not showing up.
Following is the code, how I am accessing cover images.
<div class="product-top">
<img src="{{ product.cover.url }}" alt="book-image">
<h5>{{ product.title }}</h5>
</div>
my settings.py related code:
import os
import django_heroku
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
TEMP_DIR = os.path.join(BASE_DIR, 'templates')
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'abc'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['*']
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'abc#gmail.com'
EMAIL_HOST_PASSWORD = 'xyz'
EMAIL_PORT = 25
EMAIL_USE_TLS = True
DEFAULT_FROM_EMAIL = 'abc#gmail.com'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
BASE_URL = '127.0.0.1:8000'
MANAGERS = (
('abc', "abc#gmail.com"),
)
ADMINS = MANAGERS
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'debug_toolbar',
'crispy_forms',
# myapps
'myapp',
]
AUTH_USER_MODEL = 'accounts.User'
STRIPE_SECRET_KEY = 'abc'
STRIPE_PUB_KEY = 'abc'
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware',
# Simplified static file serving.
'whitenoise.middleware.WhiteNoiseMiddleware',
]
ROOT_URLCONF = 'project.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMP_DIR]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'project.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
## Password hashing (included)
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
]
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/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/3.0/howto/static-files/
STATIC_URL = '/static/'
STATIC_br = os.path.join(BASE_DIR,
'bookrepo/static')
STATIC_seller = os.path.join(BASE_DIR, 'seller/static')
STATICFILES_DIRS = [
STATIC_br, STATIC_seller
]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles/')
# MEDIA INFORMATION:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
as my terminal says after debug=false:
[23/Aug/2020 23:07:00] "GET /media/covers/product1.PNG HTTP/1.1" 404 11974
as my terminal says after debug=true:
[23/Aug/2020 23:25:15] "GET /media/covers/product1.PNG HTTP/1.1" 200 103898
It is worth noting that django itself does not serve static and media files when debug is false.You should use a reverse proxy like ha proxy or nginx if you are in production otherwise set debug to true for local development
Below is an example for nginx server block that serves your application, static and media files.
server {
server_name your_server_ip;
proxy_read_timeout 600s;
client_max_body_size 25M;
location /static {
alias /home/trello/static/;
}
location /media {
alias /home/trello/media/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
}
}
I am having a problem when I attempt to access localhost/auth/ this is possibly because of the nginx configuration or may be another other issue. The following is the result I get from nginx logs after attempting to make a request to the proxied address localhost/auth/
reverse-proxy | 0.0.0.0 - - [28/Aug/2020:08:21:47 +0000] "GET /api/ HTTP/1.1" 404 159 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
When I access http://localhost/admin/ the Admin login page renders as expected as shown below. Also at http://localhost/doc/ the redocs documentation page renders as well.
Project Structure
├── nccggbot
│ ├── chatbot/
│ └── core/
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ ├── wsgi.py
│ ├── static/
│ │ ├── admin/
│ │ ├── django_extensions/
│ │ |── drf-yasg
│ │ ├── rest_framework
│ │
│ ├── Dockerfile
│ ├── manage.py
│ ├── requirements.txt
│
│
├──reverse_proxy/
│ ├── default.conf
│ └── Dockerfile
├──docker-compose-deploy.yml
├──README.md
core/urls.py
from django.contrib import admin
from django.urls import include,path
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from rest_framework import permissions
from django.conf import settings
from django.conf.urls.static import static
schema_view = get_schema_view(
openapi.Info(
title="NCCG ChatBot API",
default_version='v1.0.0',
description="The nccg chatbot rest API",
),
public=True,
permission_classes=(permissions.AllowAny,),
)
urlpatterns = [
path('admin/', admin.site.urls),
path('doc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
path('api-auth/', include('rest_framework.urls')),
path('api/', include('chatbot.urls'))
]
settings.py
"""
Django settings for core project.
Generated by 'django-admin startproject' using Django 3.1.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent
DEBUG = bool(int(os.environ.get("DEBUG", default=0)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get("SECRET_KEY")
ALLOWED_HOSTS = ['*']
# ALLOWED_HOSTS_ENV = os.environ.get('ALLOWED_HOSTS')
# if ALLOWED_HOSTS_ENV:
# ALLOWED_HOSTS.extend(ALLOWED_HOSTS_ENV.split(','))
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'chatterbot.ext.django_chatterbot',
'rest_framework',
'drf_yasg',
'chatbot'
]
# ChatterBot settings
CHATTERBOT = {
'name': 'NCCG Support Bot',
'django_app_name': 'django_chatterbot'
}
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'core.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'core.wsgi.application'
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
}
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
print(DEBUG)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite3',
}
}
# if DEBUG is False:
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': BASE_DIR / 'db.sqlite3',
# }
# }
# else:
# DATABASES = {
# "default": {
# "ENGINE": os.environ.get("SQL_ENGINE", "django.db.backends.sqlite3"),
# "NAME": os.environ.get("SQL_DATABASE", os.path.join(BASE_DIR, "db.sqlite3")),
# "USER": os.environ.get("SQL_USER", "user"),
# "PASSWORD": os.environ.get("SQL_PASSWORD", "password"),
# "HOST": os.environ.get("SQL_HOST", "localhost"),
# "PORT": os.environ.get("SQL_PORT", "5432"),
# }
# }
# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.1/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/3.1/howto/static-files/
STATIC_URL = '/static/static/'
MEDIA_URL = '/static/media/'
STATIC_ROOT = '/vol/web/static'
MEDIA_ROOT = '/vol/web/media'
# STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),]
NGINX conf file
upstream webserver {
server nccgbot-service:8000;
}
server {
listen 80;
gzip on;
location /auth {
proxy_pass http://webserver/api-auth;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
client_max_body_size 100M;
}
location /doc {
proxy_pass http://webserver/doc;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
client_max_body_size 100M;
}
location / {
proxy_pass http://webserver;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
client_max_body_size 100M;
}
location /static {
autoindex on;
alias /vol/static;
}
}
Docker compose file
version: '3.7'
services:
# Chat bot
nccgbot-service:
container_name: nccgbot-service
image: nccgbot-service
build:
context: ./nccgbot_service
command: sh -c "python manage.py makemigrations && python manage.py collectstatic --no-input && python manage.py migrate && gunicorn core.wsgi:application --workers 2 --bind 0.0.0.0:8000"
volumes:
- static_data:/vol/web
env_file:
- ./.env
expose:
- "8000"
restart: on-failure
# proxies requests to internal services
reverse_proxy:
build:
context: ./reverse_proxy
restart: always
image: reverse-proxy
container_name: reverse-proxy
volumes:
- static_data:/vol/static
ports:
- "80:80"
depends_on:
- nccgbot-service
volumes:
static_data:
chatbot/urls.py
from django.conf.urls import url
from chatbot.views import ChatterBotApiView
urlpatterns = [
url(r'^chatbot/', ChatterBotApiView.as_view(), name='chatbot'),
]
**Browser output when I access localhost/api-auth **
rest_framework.urls does not have an index view:
urlpatterns = [
url(r'^login/$', views.LoginView.as_view(template_name='rest_framework/login.html'), name='login'),
url(r'^logout/$', views.LogoutView.as_view(), name='logout'),
]
So /auth/login should work. Also, it's not going to do what you think it does. This serves up Django's standard login and logout views and doesn't authenticate via REST. Look at third party packages for that.
And look at Django Vue Auth Demo for a discussion of some of the common mistakes and pitfalls when authenticating via REST using a detached frontend.
I am running Django 2.0 using gunicorn on nginx server. All my pages are not reflecting the changes immediately. How to stop caching
the below are my files:
nginx.conf
server {
listen 80;
server_name sample.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/testapp/testapp_project/test_artciles;
}
location /media/ {
root /home/testapp/testapp_project/test_artciles;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/testapp/testapp_project/test_artciles.sock;
}
}
Django settings.py
import os
from django.contrib import messages
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = 'ssdjhasjdkhjaskdhkajsdhkjasdhkjh'
DEBUG = True
ALLOWED_HOSTS = ['xx.xxx.xx.xxx','127.0.0.1']
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'django_extensions',
# local apps
'articles',
'fcm_django',
'corsheaders',
'rest_framework',
)
MIDDLEWARE = (
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'webarticles.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(os.path.join(BASE_DIR, 'templates')),
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'webarticles.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'test.sqlite3'),
}
}
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Asia/Kolkata'
USE_I18N = True
USE_L10N = True
USE_TZ =True
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'frontend'),
)
CORS_ORIGIN_WHITELIST = ('xx.xxx.xx.xxx','127.0.0.1')
I am sure its something to do with the server because when i ran this code in localhost on my own laptop before transferring to server, things are reflecting immediately.
You should restart gunicorn to update working version after you changed code on server:
sudo systemctl restart gunicorn
or you can use --reload mode that will update gunicorn once code changed:
gunicorn --workers=2 test:app --reload
You can read about it on docs https://docs.gunicorn.org/en/stable/settings.html#reload
If you are talking about server caching, then here are the steps worked for me:
My implementation details are
gunicorn 19.9.0,
Django 1.11.16,
nginx version: nginx/1.10.3,
Os (Ubuntu)
Gunicorn is not caching already unless you have installed and enabled https://pypi.org/project/gunicorn_cache/
Disabling django caching,
from django.views.decorators.cache import never_cache
#never_cache
def generating the cached data/results():
Disabling ngnix caching
location todisablecaching {
proxy_no_cache 1;
proxy_cache_bypass 1;
...
}
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_no_cache,
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_bypass
I hope it work for you as well.
I am almost done building my website but while creating an autogenerating slug in Django admin, I found it to be unresponsive. When i looked at the console of my browser i see a lot of JS error warnings. The nginx is correctly sending the css files, but there seems to be issues with respect to some admin js files. It is unable to read files in the admin/js/vendor/* . Any help or advise would be greatly appreciated.
#settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'Blog',
]
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'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 = 'Blog.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
'APP_DIRS': True,
'OPTIONS': {
'debug': DEBUG,
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
ROOT_URLCONF = 'django_project.urls'
WSGI_APPLICATION = 'django_project.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'django',
'USER': 'django',
'PASSWORD': 'eJf9IHxaMe',
'HOST': 'localhost',
'PORT': '',
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.6/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.6/howto/static-files/
STATIC_URL = '/static/'
#STATIC_ROOT = os.path.join(BASE_DIR,"static")
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
#'/var/www/static/',
]
STATIC_ROOT = '/home/django/django_project/django_project/static'
MEDIA_URL = '/media/'
MEDIA_ROOT = '/home/django/django_project/django_project/media'
nginx
upstream app_server {
server 127.0.0.1:9000 fail_timeout=0;
}
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.html index.htm;
client_max_body_size 4G;
server_name _;
keepalive_timeout 5;
# Your Django project's media files - amend as required
location /media {
alias /home/django/django_project/django_project/media;
}
# your Django project's static files - amend as required
location /static {
alias /home/django/django_project/django_project/static;
}
# Proxy the static assests for the Django Admin panel
location /static/admin {
alias /usr/lib/python2.7/dist-packages/django/contrib/admin/static/admin/;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
Console Error
Failed to load resource: the server responded with a status of 404 (Not Found)
http://myipaddress/static/admin/js/vendor/xregexp/xregexp.min.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://myipaddress/static/admin/js/vendor/jquery/jquery.js Failed to load resource: the server responded with a status of 404 (Not Found)
jquery.init.js:7 Uncaught ReferenceError: jQuery is not defined(anonymous function) # jquery.init.js:7
actions.js:2 Uncaught TypeError: Cannot read property 'fn' of undefined(anonymous function) # actions.js:2(anonymous function) # actions.js:139
prepopulate.js:2 Uncaught TypeError: Cannot read property 'fn' of undefined(anonymous function) # prepopulate.js:2(anonymous function) # prepopulate.js:34
http://myipaddress/static/admin/js/vendor/xregexp/xregexp.min.js Failed to load resource: the server responded with a status of 404 (Not Found)
myipaddress Uncaught TypeError: $ is not a function(anonymous function) # myipaddress/:220(anonymous function) # myipaddress/:234
myipaddress/:259 Uncaught TypeError: $ is not a function