Skip to content

Setup with nginx reverse proxy #4647

@delucarnaud

Description

@delucarnaud

Issue

Hi guys, first of all, thanks for the awesome application, if I get it working, I'm completely using it with my girlfriend to have our meal schedule and grocery list !
My only problem right now is that I can't get it to work outside my local network.
I use the docker install on my Synology NAS, and I have an Nginx reverse proxy on a Raspberry Pi 4 (I once had every application I use at home non dockerized on the Pi, and I used a reverse proxy to access it outside my local network).
I chose to access tandoor outside my LAN via the URL https://myurl.ddns.net/tandoor, because that's how I use all my other apps (media server stuff such as emby for example), and it woulod be too much of a hassle to change every config I have right now to use subdomains, given the time and energy I have these days.

Accessing it via the local IP (192.168.0.149:8082) works fine :

Image

Accessing it via https://myurl.ddns.net/tandoor apparently it has trouble locating the static resources, even though they are (I believe) correctly mapped in my compose.yml file.

Image

I read in the docs that I might have to change the nginx configuration inside the tandoor container, but I might have not understood correctly.
I must be doing something wrong, obviously, and I read the docs, found some people with similar problems, but I still can't quite figure it out on my own.

Can anyone help me with this ?

Tandoor Version

2.6.9

OS Version

Synology DSM 7

Setup

Docker / Docker-Compose

Reverse Proxy

Others (please state below)

Other

nginx

Environment file

# ---------------------------------------------------------------------------
# This template contains only required options.
# Visit the docs to find more https://docs.tandoor.dev/system/configuration/
# ---------------------------------------------------------------------------

# random secret key, use for example `base64 /dev/urandom | head -c50` to generate one
SECRET_KEY=REDACTED

# your default timezone See https://timezonedb.com/time-zones for a list of timezones
TZ=Europe/Paris

# allowed hosts (see documentation), must be set to your hostname(s)
ALLOWED_HOSTS=*

# add only a database password if you want to run with the default postgres, otherwise change settings accordingly
DB_ENGINE=django.db.backends.postgresql
POSTGRES_HOST=db_recipes
POSTGRES_DB=djangodb
POSTGRES_PORT=5432
POSTGRES_USER=djangouser
POSTGRES_PASSWORD=REDACTED

# Allow in-browser requests from other domains to this instance (CORS stuff)
CORS_ALLOW_ALL_ORIGINS=1
CORS_ALLOWED_ORIGINS=['*']

DEBUG=1
SCRIPT_NAME=/tandoor
ALLAUTH_TRUSTED_PROXY_COUNT=2

CSRF_TRUSTED_ORIGINS="https://myurl.ddns.net"

Docker-Compose file

services:
  db_recipes:
    restart: always
    image: postgres:16-alpine
    volumes:
      - /volume1/Configs/tandoor-recipes/postgresql:/var/lib/postgresql/data
    env_file:
      - ./.env

  web_recipes:
    restart: always
    image: vabene1111/recipes
    env_file:
      - /volume1/Configs/tandoor-recipes/.env
    ports:
      - 8082:80
    volumes:
      - /volume1/Configs/tandoor-recipes/staticfiles:/opt/recipes/staticfiles
      - /volume1/Configs/tandoor-recipes/mediafiles:/opt/recipes/mediafiles
    depends_on:
      - db_recipes

volumes:
  staticfiles:

Relevant logs

Nginx Reverse Proxy : 

server {
    server_name myurl.ddns.net;

    return 301 https://$server_name$request_uri;

    listen 80;

    # Increase http2 max sizes
    large_client_header_buffers 4 16k;
}

server {
    # SSL Configuration
    listen 443 ssl http2 default_server;
    listen [::]:443 http2 default_server;

    include /etc/nginx/snippets/strong-ssl.conf;

    ssl_certificate /etc/letsencrypt/live/myurl.ddns.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myurl.ddns.net/privkey.pem;
    ssl_session_cache shared:SSL:10m;

    # Add headers to serve security related headers
    # Before enabling Strict-Transport-Security headers please read into this
    # topic first.
    #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Robots-Tag none;
    add_header X-Download-Options noopen;
    add_header X-Permitted-Cross-Domain-Policies none;
    add_header Referrer-Policy no-referrer;

    # Remove X-Powered-By, which is an information leak
    fastcgi_hide_header X-Powered-By;

...

    location /tandoor {
        proxy_set_header Host $http_host;
#        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Proto https;
        proxy_pass http://192.168.0.149:8082;
        proxy_redirect http://192.168.0.149:8082 https://myurl.ddns.net;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Frame-Options SAMEORIGIN;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header HTTP_HOST myurl.ddns.net;
        proxy_set_header HTTP_X_FORWARDED_HOST myurl.ddns.net;
        proxy_cookie_path / /tandoor;
        proxy_set_header HTTP_X_SCRIPT_NAME /tandoor;
        proxy_set_header X-Script-Name /tandoor;
    }
}


# Debug from /system/ page using the LAN IP address : 
Gunicorn Media: False
Sqlite:  Faux 
        PostgreSQL: 16 
        Debug: False

SERVER_PROTOCOL:HTTP/1.0
REMOTE_ADDR:
SERVER_PORT:8082

HTTP_HOST:192.168.0.149:8082
HTTP_X_FORWARDED_FOR:172.19.0.1
HTTP_CONNECTION:close
HTTP_UPGRADE_INSECURE_REQUESTS:1
HTTP_USER_AGENT:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36
HTTP_ACCEPT:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8
HTTP_SEC_GPC:1
HTTP_ACCEPT_ENCODING:gzip, deflate
HTTP_ACCEPT_LANGUAGE:fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
HTTP_COOKIE:_SSID=rDzuZiWrHYjhUFjewKdD11xU3qLJDiP-qc1j8qvm02w; stay_login=0; did=XZ3ZSho9ie3BXa3uHv_LTaE2r5XHaUREkGrfu56Zp8cTwCzXvPKf8psexN_DJ6xtjiszh363BRXsoG6KBBQS9Q; _CrPoSt=cHJvdG9jb2w9aHR0cDo7IHBvcnQ9NTAwMDsgcGF0aG5hbWU9Lzs%3D; ViewLibrary=shared_space; ViewType=timeline; id=F0IFu4PE8XtLN-xFyLjJnwXNE0z4MR_J1ASve0PHhxISprsNxNdylog2SmRfFlGhl796wIgbNG5VcVV9Xq7zSo; io=6NtgyElgW1Yin1aRAAAj; messages=W1siX19qc29uX21lc3NhZ2UiLDAsMjUsIkNvbm5leGlvbiBhdmVjIG5hbm91IHJcdTAwZTl1c3NpZS4iLCIiXV0:1wGjIl:vPOD17z39J3LPeA9Ifsf6Rd6hcBfRwIKXEE5EDPFTtc; csrftoken=bZtSnz58SkQ42TX6GWzBKakT2RVUORhP; sessionid=udx3yjqxeouv01iqvhg5lhhwymsa6iwd

wsgi.errors:<gunicorn.http.wsgi.WSGIErrorsWrapper object at 0x7fcf14a6a500>
wsgi.version:(1, 0)
wsgi.multithread:True
wsgi.multiprocess:True
wsgi.run_once:False
wsgi.file_wrapper:
wsgi.input_terminated:True
wsgi.input:<gunicorn.http.body.Body object at 0x7fcf146c8350>
wsgi.url_scheme:http

Metadata

Metadata

Assignees

No one assigned

    Labels

    setup issuepossibly or definitely an issue with the user setup

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions