datatools-ui icon indicating copy to clipboard operation
datatools-ui copied to clipboard

Which file/location to point to in nginx config?

Open wkulesza opened this issue 1 year ago • 22 comments

When running the Datatools UI and server, front-end is served by nginx, but it's unclear on which file of UI controls the dynamic urls and thus, how to setup nginx to point to index.html? Without this, when trying to refresh any url, I'm getting "403 The requested path could not be found" message. The URL adds "/login/", or "/home/4a80f2a2-d3a3-4cd9-af66-99d716d0ad44" or other similar suffixes. I'm currently on: UI Version: 1391fb Server version: 2a725e

wkulesza avatar May 22 '23 07:05 wkulesza

How are you running the UI? depending on the command you use the answer for this changes

miles-grant-ibigroup avatar May 22 '23 14:05 miles-grant-ibigroup

Im using (sometimes replacing production with test):

mastarm build --env production && serve -p 9966

wkulesza avatar May 22 '23 17:05 wkulesza

If that helps @miles-grant-ibigroup this is the ui that is then served by nginx and it's config is:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;


    upstream front {
      server datatools-ui:9966;
    }

    upstream back {
      server datatools-server:4000;
    }

    server {
      listen 8081;

      location /api {
        #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;

        proxy_pass http://back/api;
        #proxy_redirect off;
      }

      location / {
        proxy_pass http://front/;

      }
    }
}

wkulesza avatar May 23 '23 17:05 wkulesza

@miles-grant-ibigroup would you have any hints ?

wkulesza avatar May 30 '23 09:05 wkulesza

I don't think you need to manually set your /api route. Try hosting your datatools server on a separate host.

Merging the 2 together on one endpoint is something I've been struggling with for a while too...

miles-grant-ibigroup avatar May 30 '23 11:05 miles-grant-ibigroup

@miles-grant-ibigroup when react app is served by Apache it's enough to set the vhost to point all requests to index.html of react app that does the rest of rourting.

'''

<VirtualHost *:8080> ServerName example.com DocumentRoot /var/www/httpd/example.com

<Directory "/var/www/httpd/example.com"> ...

RewriteEngine On
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
'''

I tried doing similar with nginx conf file but with no success;

'''

Any route containing a file extension (e.g. /devicesfile.js)

location ~ ^.+..+$ { try_files $uri =404; }

Any route that doesn't have a file extension (e.g. /devices)

location / { try_files $uri $uri/ /index.html; }

'''

wkulesza avatar Jun 01 '23 16:06 wkulesza

Try first just routing to the datatools server. the server includes an old version of the UI. once you have this routing in place and working, try swapping out just the non-api routes. in our experience we've actually found most helpful to host the datatools server on one server and host the UI separately!

miles-grant-ibigroup avatar Jun 01 '23 17:06 miles-grant-ibigroup

Can you elaborate? What is the point of having ui and server on different servers?

wkulesza avatar Jun 03 '23 19:06 wkulesza

I have here: https://github.com/ColombiaTransit/datatools-ui a config for docker with lighthttpd as the server serving the ui. Traefik routes in my situation the /api requests to the datatools server. I'm hosting the datatools-server in a separate container.

mvanlaar avatar Jun 06 '23 08:06 mvanlaar

@mvanlaar Hi - thanks for this. We're using a docker-compose project that builds datatools-server, datatools-ui, postgis and mongodb and serves all through nginx. So i reckon here, we would need to replace nginx with lighthttpd. How to mix this with Traefik? Do you have any template to use ?

wkulesza avatar Jun 06 '23 09:06 wkulesza

My redacted traefik file:

http:

  ## EXTERNAL ROUTING EXAMPLE - Only use if you want to proxy something manually ##
  routers:
    datatools-ui:
      entryPoints:
        - web        
      rule: "Host(`datatools.example.org`)"      
      service: datatools-ui@docker
      middlewares:
        - datatools-ui@file
    datatools-api:
      entryPoints:
        - web        
      rule: "Host(`datatools.example.org`) && PathPrefix(`/api`)"      
      service: datatools-server@docker
      middlewares:
        - datatools-api@file    
    datatools-graphhopper-api:
      entryPoints:
        - web        
      rule: "Host(`datatools.example.org`) && PathPrefix(`/graphhopper`)"      
      service: graphhopper-api@docker
      middlewares:
        - datatools-graphhopper-api@file    
  # allow self-signed certificates for proxied web services
  serversTransports:
    insecureTransport:
      insecureSkipVerify: true

  ## MIDDLEWARES ##
  middlewares:
    # Only Allow Local networks
    datatools-api:
      chain:
        middlewares:    
          - default-headers
          - real-ip
          - datatools-cors-headers
    datatools-graphhopper-api:
      chain:
        middlewares:    
          - default-headers
          - real-ip
          - datatools-cors-headers
          - cleanup-datatools-request
    datatools-ui:
      chain:
        middlewares:    
          - default-headers
          - real-ip
          - datatools-cors-headers
    datatools-cors-headers:
      headers:
        accessControlAllowMethods:
          - GET
          - OPTIONS
          - POST
          - PUT
        accessControlAllowOriginList:
          - https://datatools.example.org          
        accessControlMaxAge: 100
        addVaryHeader: true
        accessControlAllowHeaders: "*"          
        customRequestHeaders:
          X-Forwarded-Proto: https
    cleanup-datatools-request:
      stripPrefix:
        prefixes:
          - "/graphhopper"    ```

mvanlaar avatar Jun 06 '23 09:06 mvanlaar

Thanks @mvanlaar will give Traefik a try. And you don't have mongodb and postgis in the docker-compose? Our docker-compose (for all Datatools project) is: https://github.com/goeuropa/gtfs_editor_ibi_datatools_docker/blob/master/docker-compose.yml

wkulesza avatar Jun 06 '23 09:06 wkulesza

Thanks @mvanlaar will give Traefik a try. And you don't have mongodb and postgis in the docker-compose? Our docker-compose (for all Datatools project) is: https://github.com/goeuropa/gtfs_editor_ibi_datatools_docker/blob/master/docker-compose.yml

Yes i have a docker compose with those services also.

mvanlaar avatar Jun 06 '23 09:06 mvanlaar

@mvanlaar Hi - thanks for this. We're using a docker-compose project that builds datatools-server, datatools-ui, postgis and mongodb and serves all through nginx. So i reckon here, we would need to replace nginx with lighthttpd. How to mix this with Traefik? Do you have any template to use ?

I use lighthttpd only because i don't need the full webserver of nignx, it serves only static files (ui). So for me the lighthttpd is sufficicient

mvanlaar avatar Jun 06 '23 09:06 mvanlaar

Cool. With my current setup, i'm struggling with 404 The requested path could not be found for all urls that are generated. Would Traefik solve this? So I can use the current docker-compose but replace the nginx part with traefik docker-compose and then open up the traefik port rather than nginx port in browser? Maybe we could discuss this off issues, not to clutter this ?

wkulesza avatar Jun 06 '23 10:06 wkulesza

My docker UI includes the webserver (lighthttpd) part. Look in the dockerfile and actions of the above repo link to see how this is build. I've got 2 main docker containers (server - with separate docker for postegres and mongo) and the ui docker. traefik controlls the access to the ui and rewirtes only the /api part. You can include this also in the lighthttpd part i think.

mvanlaar avatar Jun 06 '23 10:06 mvanlaar

Can you elaborate? What is the point of having ui and server on different servers?

I didn't make this decision, but I believe it was done so that the ui and server could be deployed separately

miles-grant-ibigroup avatar Jun 06 '23 16:06 miles-grant-ibigroup

It's about using the cloud at its best. Ui only needs cheap storage like s3, github pages etc. to host the website part. The processing parts are done at the server.

mvanlaar avatar Jun 06 '23 16:06 mvanlaar

In this config file: image i would like to clone git repository with datatools-ui code. However i don't understand exactly where source of datatools-ui is located. I need this since i need to run working version of datatools-ui with access to datatools-server. Or where do i set datatools-server host ?

changtung avatar Jun 07 '23 12:06 changtung

The github action on my repo creates the config file witch is included in the build of the application. The .js and .css files are generated in the dist folder after the build. These are copied with the index.html

It's a 2 stage build to only include only what's needed and keep the container small. The /static/ folder i use for including the logo etc.

mvanlaar avatar Jun 07 '23 12:06 mvanlaar

@mvanlaar does your setup allow to refresh any URL that is created (/i.e. /home /login or /admin?) and able to open l/admin/users?). We're struggling with being able to open any link other than the main page.

wkulesza avatar Jun 10 '23 10:06 wkulesza

Following this issue. I used the GoEuropa docker setup which works pretty much flawlessly in terms of actually getting stuff set up (thanks @wkulesza for getting that set up) but I'm struggling with 404s being returned for any calls to the API, unfortunately rendering the whole thing useless. @mvanlaar if you could write detailed instructions on how to get your setup going with Traefik and stuff (i.e. instructions for starting from scratch and how to set up the Traefik config) that'd be greatly appreciated. If anyone has had any luck with the GoEuropa setup so that the API doesn't return 404s please share how you did it!

brodyFlannigan avatar Jun 10 '23 16:06 brodyFlannigan