Traefik and Django on a Subpath - django

Following setup I want to achieve inside Docker with Traefik and Django:
http://domain/app1
http://domain/app2
My docker-compose.yml contains the following labels for the containers:
traefik.http.routers.app1.rule=Host(`my.host.de`) && PathPrefix(`/app1`)
traefik.http.routers.app1.middlewares=app1
traefik.http.middlewares.app1.headers.customresponseheaders.SCRIPT_NAME=/app1
I did the same for app2.
In the settings.py of both apps I set: FORCE_SCRIPT_NAME = env('FORCE_SCRIPT_NAME', default=None) which then should get resolved via the ENV File where I have FORCE_SCRIPT_NAME=/app1.
On Django side I always get a 404 with the message that this path does not exist and I should choose from an existing one.
Django recognizes the URL as http://my.host.de/app1 and tells me The current path, app1, didn't match any of these.
EDIT: Since my setup is thought to be both for dev and prod envs, I am using the Django built in server as well as Gunicorn for Running the Django apps.

If you want to pass a SCRIPT_NAME header to django, you have to use customrequestheaders instead of customresponseheaders when creating the middleware

Related

Django + GUnicorn ASGI with SCRIPT_NAME

I have a Django application running with a gunicorn ASGI server and an NGINX reverse proxy for serving static content. All are packaged within a docker container.
Now I want to serve this container behind a reverse proxy with a path prefix, e.g. "mydomain.com/djangoapp/". The problem is, that Django doesn't know it's hosted under a subpath, and for example, the Django admin application then always redirects to the root path "/" instead of "/djangoapp/".
I already read that there are several settings that handle this problem.
I tried setting the "FORCE_SCRIPT_NAME" in the Django settings directly to "/djangoapp". It worked for the admin login page, but after clicking the login button it redirected to the wrong root "/".
I tried setting the "SCRIPT_NAME" environment variable of the gunicorn server to "/djangoapp". It did not apply at all.
I'm running now out of ideas on what else to try. Does anybody else have a solution for this problem?
FORCE_SCRIPT_NAME should work. For the post-login redirect you need to properly set LOGIN_REDIRECT_URL

Django restarts when changing file that does not belong to the project

The problem is django server is restarting when I change the settings.py, that does not belong to my django project.
Here is the folder structure.
- project
- django-conf
- settings.py
- urls.py
- ...
- apps
- apps1
- ...
- scrapy-setting
- settings.py <------- file to be updated
When I update the scrapy-setting/settings.py django server will reload.
I don't know why.
In my django config, there is no relation to that folder.
You have three options:
Use noreload flag. BUT this will prevent reload for the whole app.
A monkey patch over the autoreload module, obviously not recommended.
Move the external code out of the Django project

How to set multiple settings.py for sites framework django?

Am trying to set up multiple website with same base. While browsing, came to know Django has Sites framework which I could use.
I didnt get how to set multiple settings.py file with site id. Any ideas anyone?
Thanks in advance :)
To serve multiple sites from the same Django instance you do not need multilple settings.py files.
A simple method is to omit the SITE_ID setting from the Sites framework. Then include the Sites framework middleware:
'django.contrib.sites.middleware.CurrentSiteMiddleware'
This automatically passes a request object to Site.objects.get_current() on every request. It also allows your Django application to detect the current site via request.site.
You would need to make sure to setup multilple virtual hosts using your NGINX or apache instance to route traffic from each site to your server.
you can have multiple setting file for example develop.py and production.py
steps:
create a settings folder inside the project
Add all of the settings file to that folder
while running server
./manage.py runserver -- settings=project_name.settings.required_settingfile
for example:
./manage.py runserver --settings=myproject.settings.develop

How do you configure a Django ImageField with upload_to and MEDIA_ROOT on Webfaction?

I have the following model field in a django project:
headshot = models.ImageField(upload_to='/tmp', blank=True, null=True)
settings.py
# format <project>/<app>
MEDIA_ROOT = '/home/username/webapps/django/myproject/books/media/'
I have created a directory: /home/username/webapps/django/myproject/books/media/tmp and gave it chmod 777 permissions.
I get the following error when I try to add a new image:
SuspiciousOperation at /admin/books/author/add/
Attempted access to '/tmp/Comment.png' denied.
Request Method: POST
Request URL: http://username.webfactional.com/app/admin/books/author/add/
Django Version: 1.3.1
Exception Type: SuspiciousOperation
Exception Value:
Attempted access to '/tmp/Comment.png' denied.
Exception Location: /home/username/webapps/django/lib/python2.7/django/core/files/storage.py in path, line 234
Python Executable: /usr/local/bin/python
Python Version: 2.7.1
Does anyone know what I'm doing wrong? Do I need .htaccess or some other settings to be able to write to this directory or is there something wrong with my Django config?
I would still like to know what chmod values to use and how to set MEDIA_URL. I'm thinking I might need to do something in urls.py for MEDIA_URL.
My project is set up on the webhost Webfaction if that makes a difference.
Fixed it. Seems like the answer was to use upload_to='tmp' instead of upload_to='/tmp'.
I see you've marked this as answered, but still have some questions in your answer. Here is how I have this set up, in case you are still working on it.
Set up a new app for media (via the webfaction control panel). I used the "static_only" application because it should prevent users from uploading scripts and running them. You could also use one of the "static/cgi/php". Creating a new app for this (instead of using Django and making a new view) is good practice because it will have a lower resource overheard. Django is overkill for serving static files (images, css files, javascript files, etc.).
Bind your new media (static_only, or whatever you used) app to some URL, again using the webfaction control panel. I bound mine to media..com. MEDIA_URL should be set to the URL you can access your media through, and MEDIA_ROOT should be the root directory for the media app. Thus, in my settings.py file I have:
MEDIA_ROOT = '/home/<username>/webapps/media/'
MEDIA_URL = 'http://media.<mydomain>.com/'
It's best to do the same thing for STATIC_ROOT and STATIC_URL.
As far as permissions go, the defaults should be OK - if you have troubles with that just ask.

gunicorn and django project (no app)

I have a django project, and I want to deploy it with gunicorn/nginx.
But I use settings.py urls.py views.py directly without start a django app, and gunicorn needs application name.
How can I deploy a django project which has no app.
You don't need an application name with gunicorn_django command. just run gunicorn_django command in your projetc folder or tel him the path of settings
http://gunicorn.org/run.html#gunicorn-django