Running Go executables (Consul, Telegraf, ...) as windows services

Running Go executables (Consul, Telegraf, ...) as windows services

There are many companies building applications using C# which still predominantly run on Windows servers.

Windows 2012 Server was definitely a step forward and I can´t wait to see the first headless Windows Nano servers, which is happening in Windows 2016 Server. However, the Windows ecosystem is sometimes a bit of a step behind the Linux world or has taken a completely different approach (Powershell I am looking at you).

And because of this completely different world, creating a Windows service to run a binary exe file with some arguments, which happens to be a trivial thing in the Linux world, becomes a real pain in Windows.

One of the biggest Go features is that it can generate executables for a number of architectures including ARM or Windows.

There are a lot of great DevOps tools these days written in Go, like the Hashicorp stack (Packer, Terraform, Consul…) or the InfluxData time-series platform based on the TICK stack (Telegraf, InfluxDB, Chronograf, Kapacitor). And because they are written in Go, they happen to run on Windows and you can get exe files for most of them.

You probably won´t run InfluxDB or the Consul Agent in Server mode in a Windows server but many chances are that you will want to install the Consul Agent in Client Mode or the Telegraf Agents in your Windows nodes running either your C# application or other Windows-only pieces of your stack like your SQL Server nodes or your Active Directory servers.

You may be tempted to download for instance Consul in a directory called “consul.io” and try to create a Windows Service with something like this (yeah the spaces after the = are not typos, this is actually how it works, thanks Windows…)

1sc create "Consul" binPath= "c:\consul.io\consul.exe agent -config-dir c:\consul.io\consul.d\someconfig --ui-dir c:\consul.io\ui" type= share start= auto

Or if you try to do the same for the Telegraf agents, you will download them to a “telegraf” directory, and try this command

1sc create "Telegraf" binPath= "c:\telegraf\telegraf.exe -config c:\telegraf\telegraf.config" type= share start= auto

The services will be registered but then when you try to start them you will see that they end up erroring after trying for a while.

So, how can we fix that? NSSM to the rescue! And we can install it from chocolatey! Opening our powershell session:

1# This will install Chocolatey
2iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
3
4# This will download the latest NSSM
5choco install -y nssm

And now we can register our services with:

1nssm install Consul c:\consul.io\consul.exe agent -config-dir c:\consul.io\consul.d\someconfig --ui-dir c:\consul.io\ui

and

1nssm install Telegraf c:\telegraf\telegraf.exe -config c:\telegraf\telegraf.config

And finally, our services will start and stop gracefully in a Windows environment!