Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for context path #313

Merged
merged 2 commits into from
Aug 7, 2022
Merged

Conversation

s2marine
Copy link
Contributor

@s2marine s2marine commented Aug 6, 2022

add an optional environment variable: LD_CONTEXT_PATH.

I'm not very familiar with django, but I tried my best to do it.
Please let me know if there is any code to improve.
Thank you.

Closes: #127

add an optional environment variable: LD_CONTEXT_PATH
Copy link
Owner

@sissbruecker sissbruecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this looks very promising. I did give this a shot at some point, and could not come up with a good solution, but the path nesting you are using here makes this pretty easy.

I did an initial review and some manual testing, I still need to test running the production app from a Docker container.

Did you already test that this works with a reverse proxy such as nginx? Would you have a configuration that I could reproduce the tests with?

.env.sample Outdated Show resolved Hide resolved
bookmarks/tests/test_context_path.py Outdated Show resolved Hide resolved
siteroot/urls.py Outdated Show resolved Hide resolved
siteroot/urls.py Outdated Show resolved Hide resolved
bookmarks/tests/test_context_path.py Outdated Show resolved Hide resolved
@s2marine
Copy link
Contributor Author

s2marine commented Aug 7, 2022

I am using docker and Nginx on my NAS for linking.
I did some clicks and it seems to work fine.
Here is a short version of my Nginx configuration.

server {
    listen 80;
    server_name _;

    location /linkding/ {
        proxy_pass http://linkding:9090;
    }
}

Copy link
Owner

@sissbruecker sissbruecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good, also could not find any issues with testing the Docker image 👌

@sissbruecker sissbruecker merged commit 8053468 into sissbruecker:master Aug 7, 2022
@xuhcc
Copy link
Contributor

xuhcc commented Aug 14, 2022

Why it is called "context path"?
I couldn't figure out what it means until I looked at the code

@0x9394
Copy link

0x9394 commented Sep 6, 2022

Changes look good, also could not find any issues with testing the Docker image ok_hand

hello, using test image from dockerhub did not work with subpath.

access to https://my.fake.tld:2443/linkding in chrome, will be redirect to https://my.fake.tld:2443/bookmarks with 404 error

nginx block conf

	location /linkding/ {
		proxy_pass	http://10.0.1.19:9090/;
	}

image version
sissbruecker/linkding:test 2df59eef10d7

nginx logs:

3.3.3.3 - - [06/Sep/2022:02:51:21 +0000] "GET /linkding HTTP/2.0" 301 162 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.112 Safari/537.36" "-"
3.3.3.3 - - [06/Sep/2022:02:51:21 +0000] "GET /linkding/ HTTP/2.0" 302 0 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.112 Safari/537.36" "-"
2022/09/06 02:51:21 [error] 110#110: *416 open() "/etc/nginx/html/bookmarks" failed (2: No such file or directory), client: 3.3.3.3, server: my.fake.tld, request: "GET /bookmarks HTTP/2.0", host: "my.fake.tld:2443"
3.3.3.3 - - [06/Sep/2022:02:51:21 +0000] "GET /bookmarks HTTP/2.0" 404 167 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.112 Safari/537.36" "-"
2022/09/06 02:51:21 [error] 110#110: *416 open() "/etc/nginx/html/favicon.ico" failed (2: No such file or directory), client: 3.3.3.3, server: my.fake.tld, request: "GET /favicon.ico HTTP/2.0", host: "my.fake.tld:2443", referrer: "https://my.fake.tld:2443/bookmarks"
3.3.3.3 - - [06/Sep/2022:02:51:21 +0000] "GET /favicon.ico HTTP/2.0" 404 167 "https://my.fake.tld:2443/bookmarks" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.112 Safari/537.36" "-"

linkding logs:

[pid: 16|app: 0|req: 137/221] 10.0.1.100 () {54 vars in 2176 bytes} [Tue Sep  6 02:51:21 2022] GET / => generated 0 bytes in 1 msecs (HTTP/1.0 302) 9 headers in 275 bytes (1 switches on core 0)

@0x9394
Copy link

0x9394 commented Sep 8, 2022

add -e "LD_CONTEXT_PATH=linkding/" to docker run parameters did not make it work. and local access url change from http://ip:9090/ to http://ip:9090/linkding/

@s2marine
Copy link
Contributor Author

s2marine commented Sep 8, 2022

location /linkding/ {
proxy_pass http://10.0.1.19:9090/;
}

Try removing the slash which end of proxy_pass. @kt1024

location /linkding/ {
    proxy_pass	http://10.0.1.19:9090;
}

@0x9394
Copy link

0x9394 commented Sep 8, 2022

@s2marine just tried remove / from proxy conf, and run docker with -e "LD_CONTEXT_PATH=linkding/"
add -e DEBUG=True did not show more details.
image

image
and docker logs with

[pid: 15|app: 0|req: 12/22] 10.0.1.100 () {58 vars in 1145 bytes} [Thu Sep  8 05:11:30 2022] GET /linkding/bookmarks => generated 0 bytes in 1 msecs (HTTP/1.0 302) 9 headers in 313 bytes (1 switches on core 0)
[pid: 14|app: 0|req: 4/23] 10.0.1.100 () {58 vars in 1186 bytes} [Thu Sep  8 05:11:30 2022] GET /linkding/login?next=/linkding/bookmarks => generated 0 bytes in 2 msecs (HTTP/1.0 301) 6 headers in 250 bytes (1 switches on core 0)
[pid: 15|app: 0|req: 13/24] 10.0.1.100 () {58 vars in 1188 bytes} [Thu Sep  8 05:11:30 2022] GET /linkding/login/?next=/linkding/bookmarks => generated 2874 bytes in 4 msecs (HTTP/1.0 200) 11 headers in 509 bytes (1 switches on core 1)
[pid: 15|app: -1|req: -1/25] 10.0.1.100 () {56 vars in 1080 bytes} [Thu Sep  8 05:11:30 2022] GET /linkding/static/theme-light.css => generated 51128 bytes in 0 msecs via sendfile() (HTTP/1.0 200) 3 headers in 112 bytes (0 switches on core 0)
[pid: 15|app: -1|req: -1/26] 10.0.1.100 () {56 vars in 1112 bytes} [Thu Sep  8 05:11:30 2022] GET /linkding/static/logo.png => generated 2937 bytes in 0 msecs via sendfile() (HTTP/1.0 200) 3 headers in 112 bytes (0 switches on core 1)
[pid: 15|app: -1|req: -1/27] 10.0.1.100 () {56 vars in 1078 bytes} [Thu Sep  8 05:11:30 2022] GET /linkding/static/theme-dark.css => generated 51868 bytes in 0 msecs via sendfile() (HTTP/1.0 200) 3 headers in 112 bytes (0 switches on core 0)
[pid: 14|app: 0|req: 5/28] 10.0.1.100 () {66 vars in 1341 bytes} [Thu Sep  8 05:11:34 2022] POST /linkding/login/ => generated 1019 bytes in 2 msecs (HTTP/1.0 403) 8 headers in 260 bytes (1 switches on core 1)

just found similar issue #39 .

@s2marine
Copy link
Contributor Author

s2marine commented Sep 9, 2022

@0x9394
I created a minimal docker-compose.yaml on gist and reproduced your problem.

After removing the LD_CONTEXT_PATH configuration, I still get CSRF errors.
Direct access to port 9090 of linkding works fine.
Using the latest image, it works fine with or without LD_CONTEXT_PATH.
So I think maybe someone broke the functionality that linkding can run behind Nginx.

You should create a new issue for that.

nginx with LD_CONTEXT_PATH nginx only direct
linkding:test error error ok
linkding:latest ok ok ok

@0x9394
Copy link

0x9394 commented Sep 9, 2022

following these 2 links
https://stackoverflow.com/questions/70501974/django-returning-csrf-verification-failed-request-aborted-behind-nginx-prox
https://www.reddit.com/r/django/comments/s6daj0/csrf_verification_failed_django_nginx_docker/

in running container I found in opt/venv/lib/python3.10/site-packages/django/conf/global_settings.py

SECURE_CROSS_ORIGIN_OPENER_POLICY = "same-origin"

now I get reverse proxy with subpath working, just in a ugly way:

  1. copy the global_settings.py to host
  2. add CSRF_TRUSTED_ORIGINS = ["https://my.fake.tld:2443"] to above py file
  3. map host py file into docker with above file path

@einmueller
Copy link

Same problem here with apache proxy to https://my.domain/ with no subdir.

The ugly solutions works great. Would be great to have an option to set the real hostname on proxy side.

@sissbruecker
Copy link
Owner

So it seems this is not a context path problem, but related to changes to CSRF handling in Django 4.0, which is used since the latest linkding release.

I need to dig a bit deeper into the docs to see if this can be configured in a reasonable way out of the box. Currently it looks like if you are running a proxy you might need to configure the specific domain to get the application running, which is not a great experience. It doesn't seem to be a general problem, as I don't have this issue with my personal installation (using Caddy), or with the demo instance running on fly.io.

For now I created an issue for this: #340

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for custom base URL to play nice with reverse proxy
5 participants