Anybody used nginx for Windows? lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- egsuh · 2021-10-03 09:52 Has anybody used nginx on Windows together with fpweb applications? What are characteristics and benefits of nginx over IIS? I have written on TWebModule.kind --- wkPooled and wkOneShot previously.  wkPooled mode causes errors when run in FCGI or HTTPServer applications.  So I separated TDataModule which contains database and queries. In FastCGI or HTTPServer, webmodule is created at every request, but datamodule which contains database is created only once. Even with this, FastCGI causes server errors.  I could remove occurrences of errors by setting FastCGI's max request number per instance to 20 ~ 25 (I wrote about this in previous threads).  There have been no problem with HTTPserver yet --- I could access several hundreds of times without restarting HTTPServer application without any error.  I'm running HTTPServer application as Windows service, and this solves the most serious problem (reconnecting the database every request). But this is little bit limited, as it cannot process other requests like requesting simple HTML file (Yes, I could write the program and specify paths, but it's too complicated).  I read about nginx today (because Lazarus FCGI application template explains to define port for e.g. nginx, etc.). Is nginx flexible as IIS? Does it support fastCGI mode? I'll google for the data, but hope quick replies from those who have used nginx with fpweb. ---------------------------------------------------------------------- Thaddy · 2021-10-03 10:10 One advantage over IIS is that nginx is cross platform. ---------------------------------------------------------------------- egsuh · 2021-10-03 12:37 I read some materials on the nginx and installed it on my PC. I could see the basic "localhost" page. Running FastCGI app independently is rather interesting --- hoping that it has the same effect as HTTPServer. But the configuration is too complex for me (not familiar with Linux) now. ---------------------------------------------------------------------- Leledumbo · 2021-10-03 14:32 Quote from: egsuh on October 03, 2021, 11:52:26 amWhat are characteristics and benefits of nginx over IIS? Basically you're not tied to one specific OS so you can develop and deploy on different OSes, just in case you want to deploy on Linux but feeling more comfortable developing on Windows. The configuration can be shared largely, differing only in file paths. Quote from: egsuh on October 03, 2021, 11:52:26 amThere have been no problem with HTTPserver yet --- I could access several hundreds of times without restarting HTTPServer application without any error.  Despite was designed mainly for testing during development, I do find the same experience: it's the most stable interface out of all 4. Quote from: egsuh on October 03, 2021, 11:52:26 amBut this is little bit limited, as it cannot process other requests like requesting simple HTML file (Yes, I could write the program and specify paths, but it's too complicated). This can be delegated to nginx, let your HTTP application serves data only, not static files. Real world deployment will consider CDN instead, so you have even less traffic burden. Quote from: egsuh on October 03, 2021, 11:52:26 amIs nginx flexible as IIS? No, it's A HELL LOT MORE flexible Quote from: egsuh on October 03, 2021, 11:52:26 amDoes it support fastCGI mode? Both FastCGI and reverse proxy are supported built-in, CGI (and obviously Apache module) do(es)n't. I use reverse proxy, though, not FastCGI due to stability reason above, but your mileage may vary. ---------------------------------------------------------------------- egsuh · 2021-10-03 16:31 @ Leledummbo, Thank you for your kind replies. I tried some, and now I can run FCGI through nginx. First, I run my fcgi program as stand-alone (I didn't know this works. What's difference from HTTPserver?) Following is the whole codes I wrote.  The default ACTION is Hello, which says something like 'Hello,World'. I added another action "Morning", which says "Good Morning". Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program fcgi_1; {$mode objfpc}{$H+} uses  fpFCGI, uwm1; begin  Application.Title:='fcgiproject1';  { Uncomment the port setting here if you want to run the     FastCGI application stand-alone (e.g. for NGINX) }  Application.Port:=2015; // For example  Application.LegacyRouting := true;  Application.Initialize;  Application.Run;end.  unit uwm1; {$mode objfpc}{$H+} interface uses  SysUtils, Classes, httpdefs, fpHTTP, fpWeb; type   { Twm1 }   Twm1 = class(TFPWebModule)     procedure MorningRequest(Sender: TObject; ARequest: TRequest;        AResponse: TResponse; var Handled: Boolean);  private   public   end; var  wm1: Twm1; implementation {$R *.lfm} { Twm1 } procedure Twm1.MorningRequest(Sender: TObject; ARequest: TRequest;   AResponse: TResponse; var Handled: Boolean);begin   AResponse.Content:= 'Good Morning';   Handled:= true;end; initialization    RegisterHTTPModule('wm', Twm1);end.  By pressing F9, this is running listening to port 2015. So, I defined in the nginx.conf file as follows. Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i         location /aqrun/  {            fastcgi_pass   127.0.0.1:2015;        #    fastcgi_index  index.php;        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;            include      fastcgi_params;        } And... http://localhost/aqrun  displays "Hello World", but I cannot run localhost/aqrun/morning.  This displays "Hello, World" as well. How can I define nginx to process pathinfo? ---------------------------------------------------------------------- PascalDragon · 2021-10-04 07:12 Quote from: egsuh on October 03, 2021, 11:52:26 amI'm running HTTPServer application as Windows service, and this solves the most serious problem (reconnecting the database every request). But this is little bit limited, as it cannot process other requests like requesting simple HTML file (Yes, I could write the program and specify paths, but it's too complicated). So RegisterFileLocation from fpWebFile isn't enough for you? ---------------------------------------------------------------------- egsuh · 2021-10-04 08:04 QuoteSo RegisterFileLocation from fpWebFile isn't enough for you? I think this did not work correctly on Windows. Does it? ---------------------------------------------------------------------- Jurassic Pork · 2021-10-04 08:54 hello, BrookFreePascal (in OPM) works on windows with nginx  using fastcgi. here is  how to route with brook  : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses  BrookAction; type   { TDoDefault }   TDoDefault = class(TBrookAction)  public    procedure Get; override;  end;   { TDoHello }   TDoHello = class(TBrookAction)  public    procedure Get; override;  end;  { TDoMorning }   TDoMorning = class(TBrookAction)  public    procedure Get; override;  end; implementation{ TDoDefault } procedure TDoDefault.Get;begin  Write('

FastCGI!

');end; { TDoHello } procedure TDoHello.Get;begin  Write('

Hello World!

');end;{ TDoMorning } procedure TDoMorning.Get;begin  Write('

Good Morning!

');end; initialization  TDoDefault.Register('/');  TDoHello.Register('/dohello');  TDoMorning.Register('/domorning'); end. fascgi config of my nginx server : Quotelocation /aqrun/ {         #     root           html;              fastcgi_pass   127.0.0.1:9000;         fastcgi_split_path_info ^(/aqrun/)(.*)$;         fastcgi_param  PATH_INFO          $fastcgi_path_info;         #    fastcgi_index  index.php;         #     fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;              include        fastcgi_params;         }i use the port 9000 because port 2015 is already used in my system. Project in attachment. Friendly, J.P ---------------------------------------------------------------------- egsuh · 2021-10-04 10:08 Hello Jurassic Pork, Really really thank you very much.  I tested your configuration only with one change which is following line, and it works very well with my previous fpweb application.        include      fastcgi.conf;  # fastcgi_params; I had difficulty with handling   fastcgi_split_path_info ^(/aqrun/)(.*)$;  ,  on which you gave a great solution.  Many thanks again. Just one thing to note :  I can pass query fields, like     localhost/aqrun/morning?good=evening , but passing action as query parameter does not work. i.e,      localhost/aqrun?action=morning  does not work. ---------------------------------------------------------------------- egsuh · 2021-10-04 11:27 I successfully finished quick testing of NGINX with FastCGI --- there were no errors which occurred with IIS.  (Haven't tried wkPooled mode. I don't think this will work as wkPooled mode had problems even in HTTPServer).   I don't know whether Apache server has the same problem as IIS. I suspect NGINX's asynchronous event‑driven approach might be related with this issue. Hope that anybody who has deep knowledge can explain. And I appreciate advices from Leledumbo, Jurassic Pork, and PascalDragon. ---------------------------------------------------------------------- PascalDragon · 2021-10-04 11:36 Quote from: egsuh on October 04, 2021, 10:04:36 amQuoteSo RegisterFileLocation from fpWebFile isn't enough for you? I think this did not work correctly on Windows. Does it? With FPC 3.2.2 it should work correctly as long as you either use a relative (.\whatever) or an absolute (D:\whatever) path. What won't work are drive relative (D:whatever) or drive absolute (\whatever) paths. ---------------------------------------------------------------------- Thaddy · 2021-10-04 15:24 Sarah, in that case canonical paths *should* work. I will write a little test. ---------------------------------------------------------------------- Leledumbo · 2021-10-04 17:53 Quote from: egsuh on October 03, 2021, 06:31:54 pmFirst, I run my fcgi program as stand-alone (I didn't know this works. What's difference from HTTPserver?) The underlying protocol differs. HTTPServer really does what it says: it hosts a HTTP server. You can directly query through curl or any other HTTP clients. FastCGI cannot, you will need a webserver capable of communicating with a FastCGI app as the middle layer, you will still send your HTTP request to the webserver, not the FastCGI app. ---------------------------------------------------------------------- nicanor · 2021-10-04 20:11 I'm stuck ... I tried the @egsuh example here in my computer whit ubuntu... I just added Code: [Select]        location /test/ {                 # include fastcgi.conf;                 include fastcgi_params;                 fastcgi_pass 127.0.0.1:9100;                 # fastcgi_split_path_info ^(/teste/)(.*)$;                 # gzip off;         } in /ect/nginx/sites-available/default and restarted nginx... before restart I sudo nginx -t  and returned everting is ok  . When I built my test app with (commented Application.port): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program test; {$mode objfpc}{$H+} uses  fpFCGI, unit_principal; begin  Application.Title:='fcgiproject1';  { Uncomment the port setting here if you want to run the     FastCGI application stand-alone (e.g. for NGINX) }  //Application.Port := 9100; // For example  Application.Initialize;  Application.Run;end. and try to access http://localhost/test/test, I got a "502 Bad Gateway" in the browser with a    2021/10/04 16:37:47 [error] 1168#1168: *21 connect() failed (111: Unknown error) while connecting to upstream, client: 127.0.0.1, server: _, request: "GET /test/test HTTP/1.1", upstream: "fastcgi://127.0.0.1:9100", host: "localhost"    in the   tail -f /var/log/nginx/error.log if I give a sudo spawn-fcgi -a127.0.0.1 -p9100 /var/www/http/test/test, works ok, create a process, but http://localhost/test/test returns: fcgiproject1: ERROR The application encountered the following error:     Error: Not found     Stack trace:     $00000000004B216F     $00000000004B17D2 If I uncomment Application.Port := 9100 and rebuild ... sudo spawn-fcgi -a127.0.0.1 -p9100 /var/www/http/test/test, it doesn't work and http://localhost/test/test always returns: "502 Bad Gateway" doesn't matter combination of comments/uncomments in Code: [Select]location /test/ {                 # include fastcgi.conf;                 include fastcgi_params;                 fastcgi_pass 127.0.0.1:9100;                 # fastcgi_split_path_info ^(/teste/)(.*)$;                 # gzip off;         } [Edited to add code tags - please read How to use the Forum.] ---------------------------------------------------------------------- egsuh · 2021-10-04 23:33 First try to change as follows in nginx.conf file (not sure whether this has effect or not).  But the first one did not work in my case.    include fastcgi_params;   -->  include      fastcgi.conf; If you can see nginx's welcome screen on browser at "localhost", then with program test,   //Application.Port := 9100;   //    ->  UNCOMMENT this line, And you'd better to add Application.Legacyrouting := true; in the program file. I assume that unit_principal is TFPWebModule.  Please check whether it has default action, and its DefActionWhenUnknown property is set to true.  Press F9.  In Windows, there appear a command window. If it does not display a small command window, press Shift-Ctrl-F9. The test application must be running. Then    http://localhost/test     must work.  This should display the default action. In order to make http://localhost/test/test , you need following definitions in nginx.conf.         fastcgi_split_path_info ^(/aqrun/)(.*)$;        fastcgi_param  PATH_INFO          $fastcgi_path_info; Without these lines, the second test is not processed. It will always do default action. Program name "test" has nothing to do with "test" in the URL. You must have an Action named test defined in the web module. ---------------------------------------------------------------------- PierceNg · 2021-10-05 00:51 Quote from: nicanor on October 04, 2021, 10:11:46 pmI'm stuck ... I tried the @egsuh example here in my computer whit ubuntu... Why not just use the fpweb's HTTP server to do development and testing? You could even deploy the pure Pascal solution into production if your threat model is ok with that. Otherwise, HTTP reverse proxying thru Nginx and Apache is easy to configure. ---------------------------------------------------------------------- egsuh · 2021-10-05 03:59 Quote sudo spawn-fcgi -a127.0.0.1 -p9100 /var/www/http/test/test I think you should not do this, because FPC FastCGI programs will auto-spawn.  In the following page, https://www.nginx.com/resources/wiki/start/topics/examples/fastcgiexam ple/ there are explanation : QuoteUnlike Apache or Lighttpd, NGINX does not automatically spawn FCGI processes. You must start them separately. In fact, FCGI is a lot like proxying. There’s a few ways to start FCGI programs, but luckily PHP5 will auto-spawn as many as you set in the PHP_FCGI_CHILDREN environment variable. So we simply run php -b 127.0.0.1:9000 manually, or create an init script like so: And your test.exe would be the same as PHP5.  So you may run it manually.  I configured both nginx and my fcgi app to automatically start as Windows service, and have no problem in using the webserver. Well, problem is nginx does not support CGI directly. They say they are providing FCGI Wrapper for Ubuntu and Debian (not Windows) --- which I think runs CGI program as if FastCGI. ---------------------------------------------------------------------- PascalDragon · 2021-10-05 06:58 Quote from: Thaddy on October 04, 2021, 05:24:53 pmSarah, in that case canonical paths *should* work. I will write a little test. I looked at the code and I know that drive absolute and relative paths don't work, because I had already complained about that to MvC when he fixed it from previously only working with relative paths (where drive absolute paths did work however as I used them as a workaround). ---------------------------------------------------------------------- nicanor · 2021-10-05 23:49 Hey @egsuh... It works!!!! Thank you very much! Is a great sensation to live the mark zero! I was not understanding the dynamics involved in "running the application".... Well, nothing like turn few nights studying, researching... googling... I ended up learning and understanding some things these days... So I went back to this topic and read again all the messages, this time paying more attention, so I connected the dots, (I was even a little embarrassed by the content of my previous post, i was even very raw! ... finally i think i understood what means "stand alone" execution... and went opening my eyes. I also found this tool called "supervisor" that can be used in linux to load the FCGI application into a process and manage it... ("supervisor" can auto- spawn FCGI application when nginx receives the request...) ... But with your answers i was able to solve final details and put this test application to works! Thanks to @PierceNg too ... Thank you all ---------------------------------------------------------------------- matthius · 2023-09-15 07:22 I am trying to run fastcgi on nginx. I used the config shown here. It cannot connect to anything. Server writes connection refused. I use GNU Linux Mint 21.