Self-hosted SeekTable + NGINX how to configure a reverse proxy

Docker images of self-hosted SeekTable are configured for standalone usage of web app (by HTTP), and this is ok when your SeekTable is accessed only from your company's local or private network (VPN).

If you want to make your SeekTable installation accessible from internet and/or use HTTPS it is recommended to use web server as reverse proxy for SeekTable application (NGINX, IIS or Apache).

This documentation page explains how to use NGINX for this purpose.

  1. Install NGINX on your host where SeekTable containers are running; for Debian/Ubuntu run sudo apt-get install nginx
  2. Change port mapping for seektable/seektable container by editing docker-compose.yml:
    replace 80:5000 with 5080:5000.
  3. Edit NGINX config /etc/nginx/sites-available/default and in the server section replace:
    location / {
      # nginx defaults
    }
    with
    client_max_body_size 50M;  # max file size to upload
    
    location ^~ /pivotdataservice {
    	rewrite /pivotdataservice/(.*) /$1 break;
    	proxy_pass http://127.0.0.1:5200/;
    	proxy_http_version 1.1;
    	proxy_set_header Upgrade $http_upgrade;
    	proxy_set_header Connection keep-alive;
    	proxy_set_header Host $host;
    	proxy_set_header DNT "";
    	proxy_cache_bypass $http_upgrade;
    	proxy_buffering off;
    	proxy_send_timeout 120s;
    	proxy_read_timeout 5m;
    	send_timeout 120s;		
    }
    	
    location / {
    	proxy_pass http://127.0.0.1:5080;
    	proxy_http_version 1.1;
    	proxy_set_header Upgrade $http_upgrade;
    	proxy_set_header Connection keep-alive;
    	proxy_set_header Host $host;
    	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    	proxy_cache_bypass $http_upgrade;
    	proxy_buffering off;
    	proxy_send_timeout 120s;
    	proxy_read_timeout 5m;
    }
    
  4. Add the following line to docker-compose.seektable.env:
    SeekTable_ST__PivotDataService__ExternalBaseUrl=/pivotdataservice/
    Important: to apply changes in the .env file seektable/seektable container should be re-created. This is performed automatically if you use docker compose up to start the containers.
  5. Restart nginx; for Ubuntu run sudo systemctl restart nginx
  6. Then try open http://your_host/.

How to configure HTTPS

You can easily can enable HTTPS for your SeekTable installation with a free Let's Encrypt certificate.

  1. For automatic challenge add to /etc/nginx/sites-available/default (before SeekTable reverse proxy config):
    location ~ /.well-known {
      root /var/www/html;
      allow all;
    }
  2. Install certbot (follow the instructions).
  3. Ensure that SSL works correctly by accessing some static content.

How to enable NGINX cache for public reports

If you have many users that may access the same public report at the same time, you may configure NGINX cache to avoid overloading your SeekTable installation and the database server. This makes sense only if you expect dozens of requests per second.

  1. Add to /etc/nginx/sites-available/default
    proxy_cache_path /tmp/nginx levels=1:2 keys_zone=st_public_report:10m max_size=100m inactive=60m use_temp_path=off;
    (change the the values if needed)
  2. Add to server section:
    location /public/report/ {
    	proxy_pass http://127.0.0.1:5080;
    	proxy_buffering on;
    	proxy_http_version 1.1;
    	proxy_set_header Upgrade $http_upgrade;
    	proxy_set_header Connection keep-alive;
    	proxy_set_header Host $host;
    	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    	proxy_cache_bypass $http_upgrade $cookie_STAuth;
    	proxy_send_timeout 120m;
    	proxy_read_timeout 5m;
    	proxy_cache st_public_report;
    	proxy_cache_valid any 1m;
    	proxy_cache_min_uses 1; 
    	proxy_cache_use_stale updating;
    	proxy_cache_background_update on; # comment if your nginx version doesn't support background updates
    	proxy_cache_lock on;
    	add_header X-Frame-Options "";
    }
    

Note that NGINX cache works only with proxy_buffering on and this means that when a published report needs to be loaded (= is not taken from the cache) the loading spinner will not work.