nginx powershell
From time to time there is a need to create some small service which is not required to be super fast or fancy
In my case it will be a webhook for external system that will be called few times per day
I wish not to have some buildable language, docker images, etc
What if all this will be configured ad-hoc?
Here is how we can have such service powered by powershell
We are going to use nginx:alpine docker image, install powershell and fastcgi inside and serve our endpoints with powershell scripts
Here are starting point examples (make sure to make all scripts executable by running chmod +x script.file
)
entrypoint.sh
#!/bin/sh
apk add -q fcgiwrap spawn-fcgi powershell
/usr/bin/spawn-fcgi -s /var/run/fcgiwrap.socket -M 766 /usr/bin/fcgiwrap
Nothing fancy here, just installing required software and instantiating fastcgi
default.conf
server {
listen 80;
root /usr/share/nginx/html;
location /post {
fastcgi_pass unix:/var/run/fcgiwrap.socket;
fastcgi_param REQUEST_BODY $request_body;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/post.ps1;
}
location /query {
fastcgi_pass unix:/var/run/fcgiwrap.socket;
fastcgi_param NAME $arg_name;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/query.ps1;
}
}
Here you can see how we are mapping certain urls to our scripts, as well as how to pass request body and query string parameters
And here are our oversimplified scripts
post.ps1
#!/usr/bin/pwsh
Write-Host 'content-type: application/json'
Write-Host 'cache-control: no-store'
Write-Host ''
$body = $env:REQUEST_BODY | ConvertFrom-Json
$body | ConvertTo-Json | Out-Host
query.ps1
#!/usr/bin/pwsh
Write-Host 'content-type: text/html'
Write-Host 'cache-control: no-store'
Write-Host ''
if ($env:NAME) {
Write-Host "<h1>Hell $($env:NAME)</h1>"
} else {
Write-Host "<h1>Hell World</h1>"
}
Now we can run container like this:
docker run -it --rm -p 8080:80 -v $PWD/entrypoint.sh:/docker-entrypoint.d/00-init.sh -v $PWD/default.conf:/etc/nginx/conf.d/default.conf -v $PWD/post.ps1:/usr/share/nginx/html/post.ps1 -v $PWD/query.ps1:/usr/share/nginx/html/query.ps1 nginx:alpine
Usage examples
curl localhost:8080
# will respond with default nginx page
curl localhost:8080/query
# <h1>Hello World</h1>
curl localhost:8080/query?name=Alex
# <h1>Hello Alex</h1>
curl localhost:8080/post -d '{"foo":"bar"}'
# {
# "foo": "bar"
# }
Notes:
- because of how locations work, even if you will call
/query.ps1
results will be the same - make sure to not mess with headers and content
- more complex bash example can be found here