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

events {
  worker_connections  1024;
}

http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;
  proxy_set_header Host $host;

  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" '
                    'response_time=$upstream_response_time proxy_host=$proxy_host upstream_addr=$upstream_addr';

  access_log /var/log/nginx/access.log main;
  
  map $http_upgrade $connection_upgrade {
    default     "upgrade";
  }

  upstream app-service {
    server ${PROXY_ADDRESS}:4001;
    keepalive 32;
  }

  upstream worker-service {
    server ${PROXY_ADDRESS}:4002;
    keepalive 32;
  }

  upstream builder {
    server ${PROXY_ADDRESS}:3000;
    keepalive 32;
  }

  server { 
    listen       10000 default_server;
    server_name  _;
    client_max_body_size 50000m;
    ignore_invalid_headers off;
    proxy_buffering off;

    error_page 502 503 504 /error.html;
    location = /error.html {
      root /usr/share/nginx/html; 
      internal;
    }

    location /db/ {
      proxy_pass      http://couchdb-service:5984;
      rewrite ^/db/(.*)$ /$1 break;
    }

    location ~ ^/api/(system|admin|global)/ {
      proxy_read_timeout 120s;
      proxy_connect_timeout 120s;
      proxy_send_timeout 120s;
      proxy_http_version 1.1;

      proxy_set_header Host $host;
      proxy_set_header Connection "";

      proxy_pass      http://worker-service;
    }

    location /api/backups/ {
      proxy_read_timeout 1800s;
      proxy_connect_timeout 1800s;
      proxy_send_timeout 1800s;
      proxy_pass      http://app-service;
      proxy_http_version 1.1;
      proxy_set_header Connection "";
    }

    location /api/ {
      proxy_read_timeout 120s;
      proxy_connect_timeout 120s;
      proxy_send_timeout 120s;
      proxy_http_version 1.1;

      proxy_set_header Host $host;
      proxy_set_header Connection "";

      proxy_pass      http://app-service;
    }

    location = / {
      proxy_read_timeout 120s;
      proxy_connect_timeout 120s;
      proxy_send_timeout 120s;
      proxy_http_version 1.1;

      proxy_set_header Host $host;
      proxy_set_header Connection "";

      proxy_pass      http://app-service;
    }

    location /app_ {
      proxy_read_timeout 120s;
      proxy_connect_timeout 120s;
      proxy_send_timeout 120s;
      proxy_http_version 1.1;

      proxy_set_header Host $host;
      proxy_set_header Connection "";

      proxy_pass      http://app-service;
    }

    location /app {
      proxy_read_timeout 120s;
      proxy_connect_timeout 120s;
      proxy_send_timeout 120s;
      proxy_http_version 1.1;

      proxy_set_header Host $host;
      proxy_set_header Connection "";

      proxy_pass      http://app-service;
    }

    location /embed {
      rewrite /embed/(.*) /app/$1  break;
      proxy_pass         http://app-service;
      proxy_redirect     off;
      proxy_set_header   Host $host;
      proxy_set_header   x-budibase-embed "true";
      add_header x-budibase-embed "true";
      add_header Content-Security-Policy "frame-ancestors *";
    }

    location /builder {
      proxy_read_timeout 120s;
      proxy_connect_timeout 120s;
      proxy_send_timeout 120s;
      proxy_http_version 1.1;

      proxy_set_header Host $host;
      proxy_set_header Connection "";

      proxy_pass      http://builder;
      rewrite ^/builder(.*)$ /builder/$1 break;
    }

    location /builder/ {
      proxy_http_version  1.1;

      proxy_set_header    Host                $host;
      proxy_set_header    Connection          $connection_upgrade;
      proxy_set_header    Upgrade             $http_upgrade;
      proxy_set_header    X-Real-IP           $remote_addr;
      proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;

      proxy_read_timeout 120s;
      proxy_connect_timeout 120s;
      proxy_send_timeout 120s;

      proxy_pass      http://builder;
    }

    location /vite/ {
      proxy_pass  http://builder;
      proxy_read_timeout 120s;
      proxy_connect_timeout 120s;
      proxy_send_timeout 120s;
      rewrite     ^/vite(.*)$ /$1 break;
    }

    location /socket/ {
      proxy_http_version  1.1;
      proxy_set_header    Upgrade     $http_upgrade;
      proxy_set_header    Connection  'upgrade';
      proxy_set_header    Host        $host;
      proxy_cache_bypass  $http_upgrade;
      proxy_pass          http://app-service;
    }

    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $http_host;

      proxy_connect_timeout 300;
      proxy_http_version 1.1;
      proxy_set_header Connection "";
      chunked_transfer_encoding off;

      proxy_pass      http://minio-service:9000;
    }

    location /files/signed/ {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      # IMPORTANT: Signed urls will inspect the host header of the request.
      # Normally a signed url will need to be generated with a specified client host in mind.
      # To support dynamic hosts, e.g. some unknown self-hosted installation url,
      # use a predefined host header. The host 'minio-service' is also used at the time of url signing.
      proxy_set_header Host minio-service;

      proxy_connect_timeout 300;
      proxy_http_version 1.1;
      proxy_set_header Connection "";
      chunked_transfer_encoding off;

      proxy_pass      http://minio-service:9000;
      rewrite ^/files/signed/(.*)$ /$1 break;
    }

    client_header_timeout 60;
    client_body_timeout   60;
    keepalive_timeout     60;
    gzip                  off;
    gzip_comp_level       4;
  }
}