django ckeditor upload not working in production - django

django settings:
CKEDITOR_BROWSE_SHOW_DIRS = True
CKEDITOR_RESTRICT_BY_USER = True
CKEDITOR_RESTRICT_BY_DATE = False
CKEDITOR_UPLOAD_PATH = 'uploads/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
MEDIA_ROOT = os.path.join(BASE_DIR, "attachments")
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'staticfiles'), )
STATIC_URL = f"{FORCE_SCRIPT_NAME}/backend/static/"
MEDIA_URL = f"{FORCE_SCRIPT_NAME}/backend/attachments/"
urls:
urlpatterns = [
path('admin/filebrowser/', site.urls),
path("grappelli/", include("grappelli.urls")),
path('admin/', admin.site.urls),
path("api/", include(api_urlpatterns)),
path('ckeditor/', include('ckeditor_uploader.urls')),
]
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT,
show_indexes=settings.DEBUG)
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT,
show_indexes=settings.DEBUG)
if settings.DEBUG:
import debug_toolbar
urlpatterns = [
path("__debug__/", include(debug_toolbar.urls)),
] + urlpatterns
nginx:
location /project_name/ {
set $service project_name;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://$service;
client_max_body_size 16m;
}
In dev all works, upload and browse, but in prod with not (AH00128: File does not exist: /var/www/html/project_name/ckeditor/upload). I try add alias/root to nginx config, change ckeditor path to re_path(r'^ckeditor/', include('ckeditor_uploader.urls')) and still nothing( Not only upload, browse too not working
For example filebrowse works, but not ckeditor. I dont know a reason why.

Add in projects apache settings in service.conf -> WSGIScriptAliasMatch ckeditor alias:
WSGIScriptAliasMatch ^/${SERVICE}/((admin|api|grappelli|ckeditor)/.*)$ /${SERVICE}/backend/${PROJECT}/wsgi.py/$1
Now works.

Related

django-private-storage configuration in nginx and Docker

I am trying to use django-private-storage package to protect a model's file from being accessed
or downloaded by users who are not owners of the file.
I was able to do it successfully in development (using python manage.py runserver)
In development, I am using nginx configured via docker.
I can create objects with both FileField and PrivateFileField. My problem is accessing the urls associated with a PrivateFileField.
The mediafiles are being served as expected (e.g. when I access the url of a FileField), but I get a "404 Not Found" error from nginx when I access the url of a PrivateFileField.
My hunch is that the server response is not properly configured to have a 'X-Accel-Redirect' data,
thus treating the response not internal.
If I remove the line "internal;" in my nginx.conf for the private-data location, the PrivateFile is served
properly, although, now, it is not private.
location /private-data/ {
internal; #<------ the PrivateFile can be accessed if this line is removed
alias /home/app/web/private-data/;
}
Also, I am sure that the private file was saved in /home/app/web/private-data
Am I missing out something in the implementation?
Thanks in advance.
Additional info:
nginx version: 1.17.4
django-private-storage version: 2.2.2
My production setup follows this:
https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/
FILES -----------------------------------
docker-compose.prod.yml
version: '3.7'
services:
web:
build:
context: ./web_app
dockerfile: Dockerfile.prod
command: gunicorn notify_django_project.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
- private_volume:/home/app/web/private-data
expose:
- 8000
env_file:
- ./.env.prod
depends_on:
- db
db:
image: postgres:12.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./.env.prod.db
nginx:
build: ./nginx
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
- private_volume:/home/app/web/private-data
ports:
- 1337:80
depends_on:
- web
volumes:
postgres_data:
static_volume:
media_volume:
private_volume:
nginx.conf
upstream django_project {
server web:8000;
}
server {
listen 80;
location / {
proxy_pass http://django_project;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /staticfiles/ {
alias /home/app/web/staticfiles/;
}
location /mediafiles/ {
alias /home/app/web/mediafiles/;
}
location /private-data/ {
internal;
alias /home/app/web/private-data/;
}
}
settings.py
INSTALLED_APPS = [
...
'private_storage',
....
]
PRIVATE_STORAGE_ROOT = os.path.join(BASE_DIR, "private-data")
PRIVATE_STORAGE_AUTH_FUNCTION = 'private_storage.permissions.allow_authenticated'
PRIVATE_STORAGE_INTERNAL_URL = '/private-data/'
PRIVATE_STORAGE_SERVER = 'nginx'
models.py
class Message(models.Model):
id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False)
subject = models.CharField(max_length=255)
attachment = models.FileField(upload_to=get_attachment_save_path, null=True, blank=True)
private_attachment = PrivateFileField(upload_subfolder=get_private_attachment_save_path, null=True, blank=True)
urls.py
urlpatterns = [
...
path('private-data/<str:code>/<int:year>/<str:subdir>/<uuid:pk>/<str:filename>', DownloadPrivateFileView.as_view(), name="file_download"),
url('^private-data/', include(private_storage.urls)),
...
]
views.py
#method_decorator(login_required, name='dispatch')
class DownloadPrivateFileView(PrivateStorageDetailView):
model = Message
model_file_field = 'private_attachment'
def can_access_file(self, private_file):
# When the object can be accessed, the file may be downloaded.
# This overrides PRIVATE_STORAGE_AUTH_FUNCTION
# grant_access checks private_file ownership
grant_access = grant_note_access(private_file.request, message=self.get_object())
return grant_access
Iam in the testing phase with this library too!
I did not use these lines that indicated, which serves to speed up uploading large files.
without these settings and debug = False, everything worked correctly.
Take the test please.
Sorry for the Translation, I don't speak English
My conf for my site in nginx mysite.conf
server {
listen 80;
server_name mysite.com.br;
return 301 https://mysite.com.br$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mysite.com.br;
location ~ ^/.well-known{
root /var/www/myapp;
}
location / {
proxy_pass http://127.0.0.1:6010; # My container is at port 3020
}
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
# Certificate free letsencrypt
ssl_certificate /etc/letsencrypt/live/mysite.com.br/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysite.com.br/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Strict-Transport-Security "max-age=63072000" always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
}
My setting.py for django:
MEDIA_ROOT = os.path.join(BASE_DIR, 'anexosapp') # Folder for files private app
MEDIA_URL = '/docs/'
# Conf for django-private-storage
INSTALLED_APPS += (
'private_storage',
)
PRIVATE_STORAGE_ROOT = os.path.join(BASE_DIR, 'anexosapp/')
PRIVATE_STORAGE_AUTH_FUNCTION = 'private_storage.permissions.allow_authenticated' # allow user authenticated
# settings for static server over whitenoise
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static"), ]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'
urls.py app main:
urlpatterns += [
path('private-media/', include(private_storage.urls)),
]
The file access url looks like this
https : //mysite.com.br/private-media/docs/namefile.pdf
If anyone finds errors, tips for improving the settings, please indicate! Thank you
I just removed from nginx.conf location that refers to private media like so:
upstream "my domain" {
server web:8000;
}
server {
listen 80;
location / {
proxy_pass http://"my domain";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /staticfiles/ {
alias /home/app/web/staticfiles/;
}
location /mediafiles/ {
alias /home/app/web/mediafiles/;
}
#location /privatefiles/ {
# alias /home/app/web/privatefiles/;
#}
# Error & Access logs
error_log /home/app/logs/error.log error;
access_log /home/app/logs/access.log;
client_max_body_size 128m;
}
Don't forget to set DEBUG = False, then it should worked perfectly. Every time I tried to access to private media without login in, it redirected me to login page.
This is my settings.py
...
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
STATIC_URL = "/staticfiles/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
MEDIA_URL = "/mediafiles/"
MEDIA_ROOT = os.path.join(BASE_DIR, "mediafiles")
PRIVATE_STORAGE_ROOT = os.path.join(BASE_DIR, "privatefiles")
PRIVATE_STORAGE_AUTH_FUNCTION = 'private_storage.permissions.allow_authenticated'
...
and my main urls.py
from django.conf.urls.static import static
from django.conf.urls import url
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
import private_storage.urls <--- this is for private storage
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('core.urls')),
path('rubric/', include('rubric.urls')),
path('warehouse/', include('warehouse.urls')),
path('preoffers/', include('preoffers.urls')),
path('offers/', include('offers.urls')),
url('^privatefiles/', include(private_storage.urls)) <--- this is for private storage
]
if settings.DEBUG:
urlpatterns += static(
settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(
settings.STATIC_URL, document_root=settings.STATIC_ROOT)
'internal' param tells nginx it's not accessible from the outside.
We access application and then redirect to nginx
settings.py
PRIVATE_STORAGE_ROOT = os.path.join(BASE_DIR, 'private-media')
PRIVATE_STORAGE_AUTH_FUNCTION = 'private_storage.permissions.allow_staff'
PRIVATE_STORAGE_SERVER = 'nginx'
PRIVATE_STORAGE_INTERNAL_URL = '/private-x-accel-redirect/'
nginx
location /private-x-accel-redirect/ {
internal;
alias /var/www/private-media/;
}

Django on Nginx subdirectory redirects to root

I have Django 2.2 and am trying to serve it to http://myserver.com/application using Nginx proxy pass.
If I try and go to myserver.com/application/admin I get redirect to myserver.com/admin immediately.
Is this a setting I should be specifying in Nginx or in Django to avoid this? Django is running in gunicorn, see Nginx.conf:
location /static {
alias /home/simernes/workspace/django_server/env/static;
}
location /application {
proxy_pass http://localhost:8000/;
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-Proto http;
proxy_buffer_size 128k;
proxy_buffers 8 128k;
proxy_busy_buffers_size 256k;
}
Finally, this is what my urls.py looks like in a project folder "backend":
from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
FORCE_SCRIPT_NAME="/application"
STATIC_ROOT="/home/simernes/workspace/django_server/env/static/"
app_name='backend'
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^', include('api.urls', namespace='api')),
]
Furthermore, when I go to the root of myserver.com/application I get an error of 404 not found and:
Using the URLconf defined in backend.urls, Django tried these URL patterns, in this order:
admin/
^ auth$ [name='auth']
The current path, /, didn't match any of these.
Which is not what I expected, as I am configuring to show the urls available in my api app (see urls.py below), but it's not my main concern with this question so I'm just including it for broader context.
I have another app folder called api with urls also, which is the one being included in backend:
from django.conf.urls import url
from rest_framework.authtoken import views as drf_views
app_name="api"
urlpatterns = [
url(r'auth$', drf_views.obtain_auth_token, name='auth'),
]
Thanks in advance for any responses, they will be greatly appreciated.
You need to also override LOGIN_URL, STATIC_URL, LOGIN_REDIRECT_URL and any other settings that require a path

how to serve media files in django app nginx server?

I am testing my django app in production mode (debug=false) using nginx, gunicorn, postgresql.
Though I am able to render static files, I am unable to access files stored in 'media' folder.
In my settings.py following are the variables set:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# also tried another combination: MEDIA_ROOT = 'media'
Also in urls.py the MEDIA_ROOT settings are as follows:
urlpatterns = [
path('admin/', admin.site.urls),
path('venter/', include('appname.urls')),
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
And in my /etc/nginx/sites-available/ file I have the following settings:
server {
listen 80;
server_name website.com www.website.com ;
location = /favicon.ico { access_log off; log_not_found off; }
location /static {
root /home/a/btawebsite;
}
location /media/ {
root /home/a/btawebsite;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/a/myproject.sock;
}
}
However while rendering the xlsx file stored in my django database as follows it throws me NOT found error.
{{file.output_file.url}}
I have tried every combination of configurations required for rendering MEDIA files but unable to achieve the outcome.
Thanks.
UPDATE: following changes to be made in settings.py
MEDIA_URL = '/'
MEDIA_ROOT = 'media'
If everything in django settings is properly configured you just need to add the following in the nginx conf:
location /media {
alias /home/user/django_app/media; #(locaion of your media folder)
}
In your settings.py write like this
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # root for media files
MEDIA_URL = "/media/"
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
FORCE_SERVE_STATIC = True
DEBUG=False
In your urls.py change like this
if settings.DEBUG:
urlpatterns += static(
settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
elif getattr(settings, 'FORCE_SERVE_STATIC', False):
settings.DEBUG = True
urlpatterns += static(
settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(
settings.STATIC_URL, document_root=settings.STATIC_ROOT)
settings.DEBUG = False
In your nginx.conf file change the root to your media folder
location /media/ {
root /home/nazmi/workspace/portal/media/ (url for your media folder);
}
First of all, remove the +static() from your urls.py. That's not correct for production, only for development.
In your nginx configuration, location = /media/ only applies for exact
matches, not locations starting with /media/. Remove the =.

Ubuntu server, Django 1.11.4, gunicorn, nginx can not find css files

Got problem with static css. I already did collectstatic.
Css works fine if run
./manage.py runserver 0.0.0.0:8000
but can not be found if run
gunicorn --bind 0.0.0.0:8000 hotel_main.wsgi:application
same situation with Dajango admin
settings.py
STATIC_URL = '/static/'
STATIC_ROOT = "/opt/static/"
STATICFILES_DIRS = [
('static', os.path.join(BASE_DIR, 'hotel_site/static'),),
('static', os.path.join(BASE_DIR, 'static'),),
]
Urls.py
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.conf import settings
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^ckeditor/', include('ckeditor_uploader.urls')),
url(r'^', include('hotel_site.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Nginx file
upstream 78.155.199.17 {
server localhost:8000 fail_timeout=0;
}
server {
listen 80;
server_name 78.155.199.17;
return 301 78.155.199.17$request_uri;
}
server {
listen 80;
server_name 78.155.199.17;
location /static/ {
root /opt/;
}
location /media/ {
root /root/;
}
location / {
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_pass 78.155.199.17;
}
}
Project tree
opt/
└─ static/
├─admin/
├─ckeditor/
└─static/
└─foundation/
root/
└─ ramn_hotel/
Recently did as here. It worked as it should.

Static files not showing up on live server

Running Django 1.8.4
Static files have been working on local. I've uploaded the project to a VPS and everything is working except the static files.
Settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = 'staticfiles'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
Example CSS files reference in template
<link href="{% static "css/bootstrap.min.css" %}" rel="stylesheet">
sudo nano /etc/nginx/sites-available/soundshelter
server {
server_name MYSERVER;
access_log off;
location /static/ {
alias /opt/soundshelter/soundshelter/static/; #this is the valid location
}
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
}
}
Urls.py
from django.conf.urls import patterns, url,include
from soundshelterapp import views
urlpatterns = patterns('soundshelterapp.views',
url(r'^$', views.home, name='home'),
url(r'^release/(?P<release_id>\d+)$', views.release, name='release'),
url(r'^genre/(.*)$', views.genre, name='genre'),
url(r'^label/(.*)$', views.label, name='label_no_country'),
url(r'^artist/(.*)$', views.artist, name='all_artists'),
url(r'^recommendations/(.*)$', views.recommendations, name='user'),
url(r'^personalised$', views.personalised, name='name'),
url(r'^social/', include('social.apps.django_app.urls', namespace='social')),
url(r'^login/$', 'login',name='login'),
url(r'^logout/$', 'logout',name='logout'),
url(r'^save_release/$', views.save_release, name='save_release'),
url(r'^unsave_release/$', views.unsave_release, name ='unsave_release'),
)
To avoid hardcoding, you can set STATIC_ROOT this way:
STATIC_ROOT = os.path.join (os.path.dirname(BASE_DIR), "staticfiles", "static")
So your static files for production will be in a directory near your project's folder. Moreover you can do the same stuff with MEDIA_ROOT.
MEDIA_ROOT = os.path.join (os.path.dirname(BASE_DIR), "staticfiles", "media")
Thanks Hedde van der Heide for the solution
Setting STATIC_ROOT to the actual location of the files worked
e.g.
STATIC_ROOT = "/var/www/example.com/static/"
https://docs.djangoproject.com/en/1.8/howto/static-files/#deployment
Do render a static file in your live website, you have to add the below code in your setting file.
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
# Static files (CSS, JavaScript, Images)
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles')
STATIC_URL = '/static/'
# Extra places for collect static to find static files.
STATICFILES_DIRS = (
os.path.join(PROJECT_ROOT, 'static'),
)
Also add this in your INSTALLED APPS,
INSTALLED_APPS =
['django.contrib.staticfiles',]