Failed to load resource (plugins, avatars, CSS)

Hello, I’ve deployed seatable developer version on a Synology to evaluate the dbms. I’ve configured the stack using docker-compose and used this guide to manually reconfigure the values in ccnet.conf and dtable_web_settings.py as I’ll be using SSL certs deployed by Synology’s built-in nginx reverse proxy. Using these settings I was successfully able to access seatable instance via https, create and play around bases.

docker-compose.yml
version: '2.0'
services:
  db:
    image: mariadb:latest
    container_name: seatable-mysql
    environment:
      - MYSQL_ROOT_PASSWORD=PASS@123
      - MYSQL_LOG_CONSOLE=true
    volumes:
      - /volume1/docker/seatable/mysql-data:/var/lib/mysql
    networks:
      - seatable-net

  memcached:
    image: memcached:latest
    container_name: seatable-memcached
    entrypoint: memcached -m 256
    networks:
      - seatable-net

  redis:
    image: redis:latest
    container_name: seatable-redis
    networks:
      - seatable-net

  seatable:
    image: seatable/seatable-developer:latest
    container_name: seatable
    ports:
      - "8454:80"
    volumes:
      - /volume1/docker/seatable/seatable-data:/shared
    environment:
      - DB_HOST=db
      - DB_ROOT_PASSWD=PASS@123
      - SEATABLE_SERVER_LETSENCRYPT=False
      - SEATABLE_SERVER_HOSTNAME=db.example.com
      - TIME_ZONE=Australia/Sydney     
    depends_on:
      - db
      - memcached
      - redis
    networks:
      - seatable-net

networks:
  seatable-net:

Issue

Everything works perfectly except the plugins, avatars and some CSS errors. Upon inspecting the console on various pages I could observe the following:

  1. Manual upload or direct market install of plugins fail : POST https://db.example.net/api/v2.1/admin/dtable-system-plugins/ Error 500
    Tried redeploying container but issue persists.

  2. Avatars do not load not even manually uploaded avatars: GET https://db.example.com/media/avatars/default.png 403

  3. Even login background fails to show: GET https://db.example.com/media/custom/login-bg.jpg?t=1645353939519 Error 403

  4. Then there are some CSS related errors:
    https://db.example.com/media/css/seatable-ui.map Error 404
    https://db.example.com/media/css/antd-mobile.min.css.map Error 404

Here are some logs:

dtable_web.log
2022-02-20 10:53:05,446 [ERROR] django.request:230 log_response Internal Server Error: /api/v2.1/admin/dtable-system-plugins/
Traceback (most recent call last):
  File "/opt/seatable/seatable-server-latest/dtable-web/thirdpart/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/opt/seatable/seatable-server-latest/dtable-web/thirdpart/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/seatable/seatable-server-latest/dtable-web/thirdpart/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/opt/seatable/seatable-server-latest/dtable-web/thirdpart/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/opt/seatable/seatable-server-latest/dtable-web/thirdpart/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/opt/seatable/seatable-server-latest/dtable-web/thirdpart/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/opt/seatable/seatable-server-latest/dtable-web/thirdpart/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/opt/seatable/seatable-server-latest/dtable-web/thirdpart/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/opt/seatable/seatable-server-latest/dtable-web/seahub/api2/endpoints/admin/sys_plugins.py", line 186, in post
    plugin_path_id = seafile_api.get_dir_id_by_path(PLUGINS_REPO_ID, plugin_path)
  File "/opt/seatable/seatable-server-latest/seafile/lib/python3/site-packages/seaserv/api.py", line 230, in get_dir_id_by_path
    return seafserv_threaded_rpc.get_dir_id_by_path(repo_id, path)
  File "/opt/seatable/seatable-server-latest/seafile/lib/python3/site-packages/pysearpc/client.py", line 127, in newfunc
    return fret(ret_str)
  File "/opt/seatable/seatable-server-latest/seafile/lib/python3/site-packages/pysearpc/client.py", line 25, in _fret_string
    raise SearpcError(dicts['err_msg'])
pysearpc.common.SearpcError: Invalid repo id
error.log (nginx-log)
2022/02/20 16:05:45 [error] 42#42: *377 open() "/opt/seatable/seatable-server-latest/dtable-web/media/css/seatable-ui.map" failed (2: No such file or directory), client: 192.168.128.1, server: db.example.com, request: "GET /media/css/seatable-ui.map HTTP/1.1", host: "db.example.com"
2022/02/20 16:05:45 [error] 41#41: *378 open() "/opt/seatable/seatable-server-latest/dtable-web/media/css/antd-mobile.min.css.map" failed (2: No such file or directory), client: 192.168.128.1, server: db.example.com, request: "GET /media/css/antd-mobile.min.css.map HTTP/1.1", host: "db.example.com"
2022/02/20 16:05:45 [error] 43#43: *390 open() "/opt/seatable/seatable-server-latest/dtable-web/media/avatars/default.png" failed (13: Permission denied), client: 192.168.128.1, server: db.example.com, request: "GET /media/avatars/default.png HTTP/1.1", host: "db.example.com", referrer: "https://db.example.com/"
2022/02/20 16:09:53 [error] 42#42: *401 open() "/opt/seatable/seatable-server-latest/dtable-web/media/css/seatable-ui.map" failed (2: No such file or directory), client: 192.168.128.1, server: db.example.com, request: "GET /media/css/seatable-ui.map HTTP/1.1", host: "db.example.com"
2022/02/20 16:09:54 [error] 42#42: *402 open() "/opt/seatable/seatable-server-latest/dtable-web/media/avatars/default.png" failed (13: Permission denied), client: 192.168.128.1, server: db.example.com, request: "GET /media/avatars/default.png HTTP/1.1", host: "db.example.com", referrer: "https://db.example.com/sys/info/"
2022/02/20 16:09:55 [error] 42#42: *408 open() "/opt/seatable/seatable-server-latest/dtable-web/media/avatars/default.png" failed (13: Permission denied), client: 192.168.128.1, server: db.example.com, request: "GET /media/avatars/default.png HTTP/1.1", host: "db.example.com", referrer: "https://db.example.com/sys/users/"
2022/02/20 16:09:57 [error] 42#42: *411 open() "/opt/seatable/seatable-server-latest/dtable-web/media/avatars/default.png" failed (13: Permission denied), client: 192.168.128.1, server: db.example.com, request: "GET /media/avatars/default.png HTTP/1.1", host: "db.example.com", referrer: "https://db.example.com/sys/web-settings/"
2022/02/20 16:09:58 [error] 42#42: *415 open() "/opt/seatable/seatable-server-latest/dtable-web/media/custom/login-bg.jpg" failed (13: Permission denied), client: 192.168.128.1, server: db.example.com, request: "GET /media/custom/login-bg.jpg?t=1645353598337 HTTP/1.1", host: "db.example.com", referrer: "https://db.example.com/sys/web-settings/"
2022/02/20 16:14:21 [error] 43#43: *419 open() "/opt/seatable/seatable-server-latest/dtable-web/media/css/antd-mobile.min.css.map" failed (2: No such file or directory), client: 192.168.128.1, server: db.example.com, request: "GET /media/css/antd-mobile.min.css.map HTTP/1.1", host: "db.example.com"
2022/02/20 16:14:21 [error] 42#42: *420 open() "/opt/seatable/seatable-server-latest/dtable-web/media/css/seatable-ui.map" failed (2: No such file or directory), client: 192.168.128.1, server: db.example.com, request: "GET /media/css/seatable-ui.map HTTP/1.1", host: "db.example.com"
2022/02/20 16:14:21 [error] 43#43: *425 open() "/opt/seatable/seatable-server-latest/dtable-web/media/avatars/default.png" failed (13: Permission denied), client: 192.168.128.1, server: db.example.com, request: "GET /media/avatars/default.png HTTP/1.1", host: "db.example.com", referrer: "https://db.example.com/"
2022/02/20 16:15:36 [error] 42#42: *440 open() "/opt/seatable/seatable-server-latest/dtable-web/media/css/seatable-ui.map" failed (2: No such file or directory), client: 192.168.128.1, server: db.example.com, request: "GET /media/css/seatable-ui.map HTTP/1.1", host: "db.example.com"
2022/02/20 16:15:37 [error] 44#44: *448 open() "/opt/seatable/seatable-server-latest/dtable-web/media/avatars/default.png" failed (13: Permission denied), client: 192.168.128.1, server: db.example.com, request: "GET /media/avatars/default.png HTTP/1.1", host: "db.example.com", referrer: "https://db.example.com/sys/info/"
2022/02/20 16:15:38 [error] 42#42: *449 open() "/opt/seatable/seatable-server-latest/dtable-web/media/avatars/default.png" failed (13: Permission denied), client: 192.168.128.1, server: db.example.com, request: "GET /media/avatars/default.png HTTP/1.1", host: "db.example.com", referrer: "https://db.example.com/sys/web-settings/"
2022/02/20 16:15:39 [error] 44#44: *452 open() "/opt/seatable/seatable-server-latest/dtable-web/media/custom/login-bg.jpg" failed (13: Permission denied), client: 192.168.128.1, server: db.example.com, request: "GET /media/custom/login-bg.jpg?t=1645353939519 HTTP/1.1", host: "db.example.com", referrer: "https://db.example.com/sys/web-settings/"
2022/02/20 16:22:58 [error] 42#42: *454 open() "/opt/seatable/seatable-server-latest/dtable-web/media/custom/login-bg.jpg" failed (13: Permission denied), client: 192.168.128.1, server: db.example.com, request: "GET /media/custom/login-bg.jpg?t=1645354378253 HTTP/1.1", host: "db.example.com", referrer: "https://db.example.com/sys/plugins/"
2022/02/20 16:22:58 [error] 42#42: *458 open() "/opt/seatable/seatable-server-latest/dtable-web/media/avatars/default.png" failed (13: Permission denied), client: 192.168.128.1, server: db.example.com, request: "GET /media/avatars/default.png HTTP/1.1", host: "db.example.com", referrer: "https://db.example.com/sys/plugins/"```

image

How should I go about resolving this so I can evaluate seatable properly?

I am the author (of the German original) of the linked article. I successfully tested the tutorial only a few weeks ago - with SeaTable Enterprise Edition, though, but should not make a difference.

I have no experience with Docker on Synology. But I seem to remember that there are restrictions.

The repo id in dtable_web_settings.py is generated on first startup. Because you did not post your config files here, it’s difficult to say what the problem is.

As for nginx’s error.log: No wonder your CSS, avatars, and images are not loaded correctly. If the permission is denied, they cannot be loaded. Unfortunately, I don’t know the cause of the permission problem. I have never seen this issue beforehand. Can you manually change the permission and see if that solves your problem?

Thanks for your reply! Here are some conf files:

dtable_web_settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'db',
        'PORT': '3306',
        'USER': 'root',
        'PASSWORD': 'REDACTED',
        'NAME': 'dtable_db',
        'OPTIONS': {
            'charset': 'utf8mb4',
        },
    }
}

CACHES = {
    'default': {
        'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
        'LOCATION': 'memcached',
    },
    'locmem': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    },
}
COMPRESS_CACHE_BACKEND = 'locmem'

SECRET_KEY = 'REDACTED'

# for dtable-server
DTABLE_PRIVATE_KEY = 'REDATCTED'
DTABLE_SERVER_URL = 'https://db.example.com/dtable-server/'
DTABLE_SOCKET_URL = 'https://db.example.com/'

# for dtable-web
DTABLE_WEB_SERVICE_URL = 'https://db.example.com/'

# for dtable-db
DTABLE_DB_URL = 'http://db.example.com/dtable-db/'

# for seaf-server
FILE_SERVER_ROOT = 'https://db.example.com/seafhttp/'

ENABLE_USER_TO_SET_NUMBER_SEPARATOR = True


PLUGINS_REPO_ID=''

ccnet.conf
[General]
SERVICE_URL = https://db.example.net/

[Database]
ENGINE = mysql
HOST = db
PORT = 3306
USER = root
PASSWD = REDACTED
DB = ccnet_db
CONNECTION_CHARSET = utf8
dtable-db.conf
[general]
host = 127.0.0.1
port = 7777
log_dir = /opt/seatable/logs

[storage]
data_dir = /opt/seatable/db-data

[dtable cache]
private_key = "REDACTED"
dtable_server_url = "http://127.0.0.1:5000"
total_cache_size = 100

[database]
host = "db"
user = root
password = "REDACTED"
db_name = dtable_db

nginx.conf
log_format seatableformat '[$time_iso8601] $http_x_forwarded_for $remote_addr "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_response_time';

upstream dtable_servers {
    server 127.0.0.1:5000;
    keepalive 15;
}

server {
    server_name db.shreejee.net;
    listen 80;



    # for letsencrypt
    location /.well-known/acme-challenge/ {
        alias /var/www/challenges/;
        try_files $uri =404;
    }

    proxy_set_header X-Forwarded-For $remote_addr;

    location / {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
        add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
            add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
            return 204;
        }
        proxy_pass         http://127.0.0.1:8000;
        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;
        proxy_read_timeout  1200s;
        
        # used for view/edit office file via Office Online Server
        client_max_body_size 0;
        
        access_log      /opt/nginx-logs/dtable-web.access.log seatableformat;
        error_log       /opt/nginx-logs/dtable-web.error.log;
    }

    location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
        proxy_pass http://127.0.0.1:8082;

        client_max_body_size 0;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_request_buffering off;
        proxy_connect_timeout  36000s;
        proxy_read_timeout  36000s;
        proxy_send_timeout  36000s;

        send_timeout  36000s;

        access_log      /opt/nginx-logs/seafhttp.access.log seatableformat;
        error_log       /opt/nginx-logs/seafhttp.error.log;

    }

    location /media {
        root /opt/seatable/seatable-server-latest/dtable-web;
    }

    location /socket.io {
        proxy_pass http://dtable_servers;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_redirect off;

        proxy_buffers 8 32k;
        proxy_buffer_size 64k;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
    
        access_log      /opt/nginx-logs/socket-io.access.log seatableformat;
        error_log       /opt/nginx-logs/socket-io.error.log;

    }

    location /dtable-server {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
        add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
            add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
            return 204;
        }
        rewrite ^/dtable-server/(.*)$ /$1 break;
        proxy_pass         http://dtable_servers;
        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;
        proxy_set_header   X-Forwarded-Proto $scheme;

        # used for import excel
        client_max_body_size 100m;

        access_log      /opt/nginx-logs/dtable-server.access.log seatableformat;
        error_log       /opt/nginx-logs/dtable-server.error.log;
    }

    location /dtable-db/ {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
        add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
            add_header Access-Control-Allow-Headers "deviceType,token, authorization, content-type";
            return 204;
        }
        proxy_pass         http://127.0.0.1:7777/;
        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;
        proxy_set_header   X-Forwarded-Proto $scheme;

        access_log      /opt/nginx-logs/dtable-db.access.log seatableformat;
        error_log       /opt/nginx-logs/dtable-db.error.log;
    }

}

seafile.conf
[fileserver]
port=8082

[database]
type = mysql
host = db
port = 3306
user = root
password = REDACTED
db_name = seafile_db
connection_charset = utf8

[history]
keep_days = 60

dtable_server_config.json
{
    "host": "db",
    "user": "root",
    "password": "REDACTED",
    "database": "dtable_db",
    "port": 3306,
    "private_key": "REDACTED",
    "redis_host": "redis",
    "redis_port": 6379,
    "redis_password": ""
}

I would like to draw your attention to some facts below:

  1. Adding an ‘s’ after http for DTABLE_DB_URL in dtable_web_settings.py results in a permission/callback error when creating an admin user. Even though it wasn’t mentioned in the blog post, I tried just in case.
  2. I’m using Cloudflare proxy and Cloudflare Origin SSL to access db outside my main network, But this should not be an issue, as the same problem occurs when accessing certain seatable assets from inside the local network
  3. ‘root’ owns the persistent volumes for the seatable stack and has complete control over all files and folders.

Any pointers are highly appreciated. Thanks!

This is probably the problem.

This post may help you: Error when uploading plugins [self-hosted] - #8 by despens

Well, going out for a water break worked! I can now install plugins.
However, 403s, when accessing avatars and background, remains a mystery.

Your nginx.log reports missing files/directories and permission denied errors. Check if the files are really missing. Check the permissions, set them to 777 to rule out a constraint on that frton.

Did you solve your problem?

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.