Add nginx.exe as Windows system service (like Apache)? - windows

I set up NGINX as a front end server for static content and I use Apache as a back-end server for other thing.
The thing is I can't find a logical answer that allows me to make nginx.exe a Windows system service (like my Apache).
Any come across an answer to this?

How to do it with Windows Service Wrapper
(Note: There are easier alternatives by now - see also solutions described here below using chocolatey package manager by suneg and using NSSM directly from Adamy)
Download the latest version of Windows Service Wrapper via github or nuget.
Current version as of this writing is v2.2.0
Since v2.x executables for .NET2.0 and .NET4.0 are available - others only on demand.
Rename winsw-*.exe to something like nginxservice.exe.
This is the name that will show up for the process that owns your nginx process.
Place an XML file next to the exe with the same base name, e.g. nginxservice.xml. The contents should be like below (verify your nginx location).
<service>
<id>nginx</id>
<name>nginx</name>
<description>nginx</description>
<executable>c:\nginx\nginx.exe</executable>
<logpath>c:\nginx\</logpath>
<logmode>roll</logmode>
<depend></depend>
<startargument>-p</startargument>
<startargument>c:\nginx</startargument>
<stopexecutable>c:\nginx\nginx.exe</stopexecutable>
<stopargument>-p</stopargument>
<stopargument>c:\nginx</stopargument>
<stopargument>-s</stopargument>
<stopargument>stop</stopargument>
</service>
You can find up to date details about the configuration on the config github page, a generic example showing all possible options here and an installation guide.
Run the command nginxservice.exe install as administrator.
You will now have an nginx service in your Services! (It is set to start automatically on boot; if you want to start your server, you must manually start the service (net start nginx).)
Detailed description of correctly setting up nginx as a Windows Service:
http://web.archive.org/web/20150819035021/http://misterdai.yougeezer.co.uk/posts/2009/10/16/nginx-windows-service/
Additional info not contained in above blog post:
You can find the latest version of the Windows Service Wrapper also via this Maven Repository:
http://repo.jenkins-ci.org
Examples for Maven + Gradle:
<dependency>
<groupId>com.sun.winsw</groupId>
<artifactId>winsw</artifactId>
<version>2.2.0</version>
<classifier>bin</classifier>
<packaging>exe</packaging>
</dependency>
<repository>
<id>jenkinsci</id>
<name>jenkinsci-releases</name>
<url>http://repo.jenkins-ci.org/releases</url>
</repository>
compile "com.sun.winsw:winsw:2.2.0"
repositories {
mavenCentral()
maven { url http://repo.jenkins-ci.org/releases }
}

Download NSSM form
http://nssm.cc/download .
"Run %NSSM_HOME%\nssm.exe install “Nginx”"
Select the Nginx executable in the NSSM dialog, then OK.
Go to Services and start the new created service "Nginx", done.

You can using start.bat and stop.bat to realize the same effect.
start.bat
#ECHO OFF
REM Start Nginx
tasklist /FI "IMAGENAME eq nginx.exe" 2>NUL | find /I /N "nginx.exe">NUL
IF NOT "%ERRORLEVEL%"=="0" (
REM Nginx is NOT running, so start it
c:
cd \nginx
start nginx.exe
ECHO Nginx started.
) else (
ECHO Nginx is already running.
)
stop.bat
#ECHO OFF
REM Stop Nginx
tasklist /FI "IMAGENAME eq nginx.exe" 2>NUL | find /I /N "nginx.exe">NUL
IF "%ERRORLEVEL%"=="0" (
REM Nginx is currently running, so quit it
c:
cd \nginx
nginx.exe -s quit
ECHO Nginx quit issued.
) else (
ECHO Nginx is not currently running.
)

SC.EXE will only work for executables that already support the Windows Services API and can respond properly to start and stop requests from the Services Control Manager (SCM). Other regular applications, not specifically written as a service, will simply fail to start (usually with error 1053)...
For those exe's, you need a "service wrapper" -- a small utility that can accept the start/stop commands from the SCM and run/terminate your application accordingly. Microsoft provides Srvany (which is free yet very basic), but there are several other free and commercial alternatives.
BTW, you should check out this guide showing how to run Nginix as a service, especially step 7 which discusses how to stop Nginix properly. Not every wrapper will support that functionality (Srvany doesn't)...

The easiest way I've found, was using the Chocolatey package manager.
Once Chocolatey is installed, you open an administrative prompt and type:
choco install nginx
You now have a Windows service named 'nginx' running.

NSSM is the best tool to run Nginx as a service.
If you do not want to use any external 3rd party software then you can implement any of these two methods.
Windows Task Scheduler
Windows startup shortcut
Windows Task Scheduler
As mentioned in this answer prepare one start.bat file.
Put this file where nginx.exe is present.
Open windows task scheduler and set up the task as described in this answer to run it indefinitely.
Do not forget to run this task as the highest privilege with the system account, more details can be found here.
Make the task to start daily at a certain time, through the bat file it will check whether the service is already running to avoid creating multiple nginx.exe instances.
If due to some reason Nginx shuts down, within 5 minutes it will start.
Windows Startup shortcut
Create one shortcut of nginx.exe and put it in the startup folder of Windows.
Follow this answer to find your startup location.
Nginx will run automatically whenever you log in to the system.
This one is the easiest. However, it is dependent on user profile i.e. if you are running Nginx on a server, it will run only for your user account, when you log off it stops.
This is ideal for dev environment.

Download zip file from here.
Extract nginx-service.exe from winginx\build and run it.

Rather than turning nginx into a service, or using CMD to start a process, which really doesn't seem to work. I found that Powershell makes it easy to startup nginx as a detached process. I've combined starting nginx with PHP. Below is the script, named "start-nginx.ps1"
$fcgiPort = "127.0.0.1:9000"
$PHPini = "c:\php\php.ini"
$ErrorActionPreference = "SilentlyContinue"
function restart {
Push-Location /nginx
Stop-Process -Force -Name nginx
Start-Process ./nginx.exe -WindowStyle Hidden
Stop-Process -Force -Name php-cgi
Start-Process "c:\php\php-cgi.exe" -ArgumentList ("-b" + $fcgiPort + " -c " + $PHPini) -WindowStyle Hidden
Pop-Location
}
restart
This script can be executed from any directory, but needs to be customized for where your nginx installation is located.
This script includes a silent attempt to kill nginx and PHP before launching both.
Windows systems are supposed to recognize ".ps1" files as powershell, even in the CMD prompt.
I created another small script to kill the running processes, which simply removes the "start-process" lines from this file.
To run at startup, I used the win-R command to navigate to the directory shell:startup
Placing a shortcut to the startup script in this directory, nginx starts at boot!
Powershell also includes a much more sophisticated ability to schedule tasks, and it is possible to schedule this script to run at startup. See This Link
From the article:
>powershell
$trigger = New-JobTrigger -AtStartup -RandomDelay 00:00:30
Register-ScheduledJob -Trigger $trigger -FilePath $HOME/start-nginx.ps1 -Name startNginx
Combined, I think this approach gets you everything you'd need from an nginx windows service and doesn't require any third-party applications.

Official nginx wiki referes on winginx for this purpose. It builds exe-installer in linux environment.
Process looks like this:
sudo apt-get install nsis make
wget https://github.com/InvGate/winginx/archive/master.zip
unzip master.zip
cd winginx-master/
make
ls -lh ./build/nginx-service.exe
To get actual versions you should specify them in Makefile.

Related

How to run a bat script on multiple windows servers at once?

I am trying to run a .bat script that uninstall 32/64 bit agents and re-install 64-bit agents on almost 100 window servers.
Can you please guide me how this can be done?
I already tried running for one server to test
psexec \\<windows server> -u <username> -p <password> <command>
But fails with error
COULD NOT START PSEXESVC service on <windows server>
Do we need such service on all machines? Please suggest any other way?
PSEXEC is not a standard windows feature /service.
If you wish to use PS Exec you will need to install it on all of the relevant systems first.
Otherwise, your options are:
CMD:
A) Does the "Agent" Installer you are using allow you to install / uninstall to a given server in it's command line syntax?
If so utilize that.
B) Put the Installer in central location (the Active Directory Netlogon Folder is great for this) along with a CMD script to run the uninstall and install processes.
Then Use SCHTasks to connect to each server and create a Scheduled task that runs using an administrative Username and password for that server, and set it to run with the highest privileges, set the action to be the path to the CMD script in netlogon that you have previously tested and nwo is working, set the task to run 1 minute in the future, or on demand (If on demand you then run schtasks again to execute the task).
Powershell:
Work on getting a working CMD Script to run and use Invoke Command to run that command script on the remote systems. As in Option B from CMD options you can keep the CMD script and Agent installer in the netlogon folder.

Datadog Agent installation on Windows

I am trying to install the Datadog agent on Windows using PowerShell only, not manual however, the APIKEY is not being setup. Is there a way to update/set the APIKEY after installation?
First you may need to download the MSI file:
$image_url = "https://s3.amazonaws.com/ddagent-windows-stable/ddagent-cli-latest.msi"
$destin = "C:\path\to\downloaded\ddagent-cli-latest.msi"
(New-Object System.Net.WebClient).DownloadFile($image_url, $destin)
The actual powershell command for installation (with extra optional arguments included as arguments):
msiexec /i C:\path\to\downloaded\ddagent-cli-latest.msi /l*v C:\path\to\installation_log.txt /quiet APIKEY="$DD_API_KEY" HOSTNAME="$HOSTNAME" TAGS=`"$TAGS,COMMA,DELIMITED`
It's been a while since i've done this (8 months or so?), so it could be outdated, but it used to work :).
Note, if you're running this from a remote provisioning script, you'll probly have to schedule this to be executed not-remotely so that the installation command can be run with heightened permissions, which i believe is required. And you may need to make sure the computer is plugged into the power source (i remember hitting some infuriating issue where that was an arbitrary requirement for Windows scheduled tasks to run, and Windows didn't allow me to configure around that).

Is it possible to force to kill windows service using Octopus?

My octopus installs Windows Service in a machine, but sometimes it can't stop the service so it doesn't deploy.
If I manually go to the machine and try to stop the service, I can't. But if I first go to Task Manager and kill the process of the service, then I can stop the service.
Does Octopus already have a built-in feature to do this for me? Or should I create a .bat to execute it before reinstalling windows service?
Same to Ryan's process, we use the command in this format to kill process that would not gracefully shutdown
taskkill /im Processname /f
Just a note, this takes Process Name not Service Name, and all services share the same process name will be killed.
You could try using a custom powershell pre-deployment script (enable the custom deployment scripts feature for your deployment step) or by placing this in a predeploy.ps1 file in your nuget package.
kill -processname serviceName
If you import the step template Stop Service With Kill you can add this as a deployment step.
The documentation here provides a step by step way to do this

SCCM 2012 Application Deployment scripting issues, any ideas?

I had no problems with SCCM 2007 scripting application deployments, but SCCM 2012 has me pulling my hair out and I have very little left.
We tend to have heavily scripted installs and most of the time the installs fail in SCCM 2012, the latest failure is symantec enterprise vault, I wrote a script that would check the main DLL plugin version and use the correct uninstall string to remove the previous version, before installing the latest version.
my script is very simple and works fine outside of SCCM, but inside SCCM it fails.
If I recreate the application as a MSI deployment and use the MSI file then it installs fine, so SCCM is working correctly to the client. The uninstall that SCCM puts in from the MSI failed, but that is covered below in the example. I have checked all the client side log files and can not find any issue.
I even return the successfull install return code 1707 and 0 at the end of the script to try and get SCCM to make it a success.
I have written the script first in VB.net as a console service app and then rewrote it in vb script. both scripts fail. I used to use AutoIT to write scripts in the past, but that too was failing, so I thought I would switch to something more microsoft.
For detection I use the windows installer selection and point to the msi file where it picks up the product code.
deployment type is script.
The only thing I can think of is SCCM 2012 does not like the sleeps that are in the scripts.
or it just does not like scripts. :-(
The MSI uninstall failed, because it needed to run as administrator, as you can see from the script below, I run as administrator and this works outside SCCM, but not in SCCM. the install uses pretty much the same code but more logic and many more uninstall strings.
even the uninstall fails and here is how simple the uninstall script is;
Set WshShell = WScript.CreateObject("WScript.Shell")
If WScript.Arguments.length = 0 Then
Set ObjShell = CreateObject("Shell.Application")
ObjShell.ShellExecute "wscript.exe", """" &
WScript.ScriptFullName & """" & "RunAsAdministrator", , "runas", 1
Else
end if
Set objShell = CreateObject("WScript.Shell")
Set objExec = objShell.Exec("MsiExec.exe /x{ADEBB592-4986-4FD1-868C-D59DB32F0BC2} /q")
WScript.Sleep 8000
returnValue = 1707
WScript.Quit(returnValue)
Just because it works outside of SCCM, does not mean a lot if you have to make it work with SCCM! people make that comparison all the time a work and it means nothing, what you need to do, is enable verbose logging on the MSI, the command line it's something like this msiexec /x {xyz-code} /l*v c:\somelogpath.log, try it you may find something equally bizarre like a 1303 error inside the log files
Use PSEXEC and execute the command under system account.
I found some setups/installers do not like to be executed without GUI or other non-user account.
Another thing, in SCCM 2012 you have packages that just simple execute the program, with only exit code check.
And there are Applications that can have detection rules, which can be used to really verify if the program installed/executed correctly.
Also always check ITninja for tips.
Something like this you may need to make sure that outlook.exe is closed you may want to add a taskkill to your script and then try it:
taskkill /IM outlook.exe /T
msiexec /a "path to file" /qn
might work as a simple .cmd file
This is an old thread, but maybe this is helpful for people searching the web:
SCCM Applications usually run as SYSTEM, no need to "run as administrator" (you could configure that within the Deployment Type).
You cannot "break" out of SYSTEM context and do a "run as"
runas and system account.
Tried that once and finally did an ugly workaround by creating a scheduled task that runs under a specific user, then ran that task from my script, which is running as SYSTEM.
As already mentioned, test your scripts interactively using SYSTEM account:
psexec.exe \\localhost -s cmd
Check with whoami that you're running the cmd with SYSTEM.
Make sure you add the COMPUTER account of your test client to the share/folder ACL of your networked scripts folder, otherwise the system account does NOT have access rights.
If running the script as SYSTEM works but SCCM still reports an error, chances are high that the Detection Method failed, NOT the actual install!
Check the following logs here: C:\Windows\CCM\Logs
(See 4. below how to use the index service to speed up troubleshooting logs.)
AppDiscovery.log
AppEnforce.log
AppIntentEval.log
Open up the Windows Indexing Service Options. Configure *.log to index file contents as well. Then add the path C:\Windows\CCM\Logs to the index. Howto.
This way you could easily search for the application name and you will find all log files which deal with that application. You will also find the matching AppDT ID, so you could search for that ID and will find even more info about your package/application.
On your admin machine create a new log collection folder, add this folder to the index. This allows you to copy the whole log folder of a client to your admin folder. A few minutes later it's indexed and fully searchable on your local machine!
There's a tool available from Microsoft which could gather a full log package on a client: ConfigMgr Support Center
Do you have SCCM setup to run it as administrator in the program that you defined?

Run batch file as a Windows service

In order to run one application, a batch file has to be kicked off (which does things like start Jetty, display live logs, etc). The application will work only if this batch file is running. I am hence forced to have this batch file running and not logout from the Windows server.
Can this batch file be run as a service? I am experimenting with one of the suggestions from a similar question.
NSSM is totally free and hyper-easy, running command prompt / terminal as administrator:
nssm install "YourCoolServiceNameLabel"
then a dialog will appear so you can choose where is the file you want to run.
to uninstall
nssm remove "YourCoolServiceNameLabel"
There's a built in windows cmd to do this: sc create. Not as fancy as nssm, but you don't have to download an additional piece of software.
sc create "ServiceName" start= demand displayname= "DisplayName" binpath= [path to .bat file]
Note
start=demand means you must start the service yourself. Options include: boot, system, auto, demand, disabled, delayed-auto
whitespace is required after =
I did encounter an error on service start that the service did not respond in a timely manner, but it was clear the service had run the .bat successfully. Haven't dug into this yet but this thread experienced the same thing and solved it using nssm to install the service.
No need for extra software. Use the task scheduler -> create task -> hidden. The checkbox for hidden is in the bottom left corner. Set the task to trigger on login (or whatever condition you like) and choose the task in the actions tab. Running it hidden ensures that the task runs silently in the background like a service.
Note that you must also set the program to run "whether the user is logged in or not" or the program will still run in the foreground.
On Windows 2019 Server, you can run a Minecraft java server with these commands:
sc create minecraft-server DisplayName= "minecraft-server" binpath= "cmd.exe /C C:\Users\Administrator\Desktop\rungui1151.lnk" type= own start= auto
The .lnk file is a standard windows shortcut to a batch file.
--- .bat file begins ---
java -Xmx40960M -Xms40960M -d64 -jar minecraft_server.1.15.1.jar
--- .bat file ends ---
All this because:
service does not know how to start in a folder,
cmd.exe does not know how to start in a folder
Starting the service will produce "timely manner" error, but the log file reveals the server is running.
If you need to shut down the server, just go into task manager and find the server java in background processes and end it, or terminate the server from in the game using the /stop command, or for other programs/servers, use the methods relevant to the server.
As Doug Currie says use RunAsService.
From my past experience you must remember that the Service you generate will
have a completely different set of environment variables
have to be carefully inspected for rights/permissions issues
might cause havoc if it opens dialogs asking for any kind of input
not sure if the last one still applies ... it was one big night mare in a project I worked on some time ago.
While it is not free (but $39), FireDaemon has worked so well for me I have to recommend it. It will run your batch file but has loads of additional and very useful functionality such as scheduling, service up monitoring, GUI or XML based install of services, dependencies, environmental variables and log management.
I started out using FireDaemon to launch JBoss application servers (run.bat) but shortly after realized that the richness of the FireDaemon configuration abilities allowed me to ditch the batch file and recreate the intent of its commands in the FireDaemon service definition.
There's also a SUPER FireDaemon called Trinity which you might want to look at if you have a large number of Windows servers on which to manage this service (or technically, any service).
Since NSSM is no longer maintained, you can consider using WinSW. It has binaries that would work with or without .Net.
Basically you create an XML file and then install it. Here is a sample of a minimal XML:
<service>
<!-- ID of the service. It should be unique across the Windows system-->
<id>myapp</id>
<!-- Path to the executable, which should be started -->
<!-- CAUTION: Don't put arguments here. Use <arguments> instead. -->
<executable>%BASE%\myExecutable.exe</executable>
</service>
And then you can install and start it:
winsw install myapp.xml
winsw start myapp.xml
Install NSSM and run the .bat file as a windows service.
Works as expected
My easest way is using opensource svcbatch (https://github.com/mturk/svcbatch/) as wrapper of CMD(BAT) in sc :
sc create myservice binPath= ""%cd%\svcbatch.exe" myservice.bat"

Resources