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.