0
Fork 0
mirror of https://github.com/caddyserver/caddy.git synced 2025-04-01 02:42:35 -05:00

caddy: support running as a service on windows and easy control

Allows running caddy without a terminal open or user logged in.
Use example "caddy -service install && caddy -service start".

Fixes #293
This commit is contained in:
Daniel Theophanes 2016-02-04 22:15:58 -08:00
parent 5b7e0361dd
commit 1de6f3b4b9

71
main.go
View file

@ -7,11 +7,13 @@ import (
"io/ioutil"
"log"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
"time"
"github.com/kardianos/service"
"github.com/mholt/caddy/caddy"
"github.com/mholt/caddy/caddy/letsencrypt"
"github.com/xenolf/lego/acme"
@ -23,6 +25,7 @@ var (
logfile string
revoke string
version bool
srvctl string
)
const (
@ -47,6 +50,7 @@ func init() {
flag.StringVar(&revoke, "revoke", "", "Hostname for which to revoke the certificate")
flag.StringVar(&caddy.Root, "root", caddy.DefaultRoot, "Root path to default site")
flag.BoolVar(&version, "version", false, "Show version")
flag.StringVar(&srvctl, "service", "", "Control a system service of Caddy")
}
func main() {
@ -85,20 +89,39 @@ func main() {
os.Exit(0)
}
// Set CPU cap
err := setCPU(cpu)
// Create an absolute path to the caddy file for use
// in a service.
serviceCaddyPath := caddy.DefaultConfigFile
if len(conf) != 0 {
serviceCaddyPath = conf
}
if !filepath.IsAbs(serviceCaddyPath) {
wd, err := os.Getwd()
if err != nil {
mustLogFatal(err)
}
serviceCaddyPath = filepath.Join(wd, serviceCaddyPath)
}
sys, err := service.New(app{}, &service.Config{
Name: caddy.AppName,
DisplayName: caddy.AppName,
Arguments: []string{"-conf", serviceCaddyPath},
})
if err != nil {
mustLogFatal(err)
}
// Get Caddyfile input
caddyfile, err := caddy.LoadCaddyfile(loadCaddyfile)
if err != nil {
mustLogFatal(err)
// Handle any service control commands.
if len(srvctl) != 0 {
err = service.Control(sys, srvctl)
if err != nil {
mustLogFatal(err, service.ControlAction)
}
return
}
// Start your engines
err = caddy.Start(caddyfile)
err = sys.Run()
if err != nil {
mustLogFatal(err)
}
@ -107,6 +130,38 @@ func main() {
caddy.Wait()
}
type app struct{}
func (app) Start(s service.Service) error {
if !service.Interactive() && len(conf) != 0 {
// Set the WD here if running under a service.
// This is required as on windows there is no way to set the current working
// directory as a service.
dir, _ := filepath.Split(conf)
err := os.Chdir(dir)
if err != nil {
return err
}
}
// Set CPU cap
err := setCPU(cpu)
if err != nil {
return err
}
// Get Caddyfile input
caddyfile, err := caddy.LoadCaddyfile(loadCaddyfile)
if err != nil {
return err
}
// Start your engines
return caddy.Start(caddyfile)
}
func (app) Stop(s service.Service) error {
return caddy.Stop()
}
// mustLogFatal just wraps log.Fatal() in a way that ensures the
// output is always printed to stderr so the user can see it
// if the user is still there, even if the process log was not