66 "github.com/caddyserver/caddy/v2"
77 caddycmd "github.com/caddyserver/caddy/v2/cmd"
88 _ "github.com/caddyserver/caddy/v2/modules/standard"
9+ "github.com/evilmartians/caddy_rails/internal/logger"
10+ "github.com/evilmartians/caddy_rails/internal/process"
911 "github.com/evilmartians/caddy_rails/internal/utils"
1012 "github.com/spf13/cobra"
1113 "go.uber.org/zap"
@@ -14,48 +16,39 @@ import (
1416 "time"
1517)
1618
17- const (
18- errStopUpstream = "failed to stop upstream process: %v"
19- errPhasedRestart = "failed to phased restart upstream process: %v"
20- errRunUpstreamProcess = "failed to run upstream process: %v"
21- errLoadCaddyConfig = "Caddyfile loading error"
22- errAccessCaddyFile = "Error accessing Caddyfile"
23- infoCaddyFileAbsent = "Caddyfile does not exist. The server is running direct way"
24- infoCaddyFileLoaded = "Caddyfile is correct and loaded. The server is running via Caddyfile"
25- )
26-
27- var logger = utils .NewCaddyRailsLogger ()
19+ var caddyLogger = logger .NewCaddyRailsLogger ()
2820
2921func init () {
3022 caddycmd .RegisterCommand (caddycmd.Command {
3123 Name : "serve" ,
3224 Short : "Runs an external server and sets up a reverse proxy to it" ,
33- Long : `
34- The serve command runs an external server specified as its argument and
35- sets up a reverse proxy to forward requests to it.` ,
3625 CobraFunc : func (cmd * cobra.Command ) {
37- cmd .Flags ().String ("pid-file" , "" , "Path to the PID file to control an existing process" )
38- cmd .Flags ().Bool ("stop" , false , "Stop the running process" )
39- cmd .Flags ().Bool ("phased-restart" , false , "Perform a phased restart of the server" )
40- cmd .Flags ().Bool ("anycable-enabled" , false , "Activate AnyCable" )
41- cmd .Flags ().String ("server-type" , "puma" , "The type of server (puma or unicorn) to control" )
42- cmd .Flags ().Int ("target-port" , 3000 , "The port that your server should run on. caddy-rails will set this values to the PORT env variable when starting your server." )
43- cmd .Flags ().Int ("http-port" , 80 , "The port to listen on for HTTP traffic." )
44- cmd .Flags ().Int ("https-port" , 443 , "The port to listen on for HTTPS traffic." )
45- cmd .Flags ().StringP ("listen" , "l" , "localhost" , "The address to which to bind the listener" )
46- cmd .Flags ().String ("ssl-domain" , "" , "The domain name to use for SSL provisioning. If not set, SSL will be disabled." )
47- cmd .Flags ().StringP ("files-path" , "f" , "" , "The domain name to use for SSL provisioning. If not set, SSL will be disabled." )
48- cmd .Flags ().BoolP ("debug" , "v" , false , "Enable verbose debug logs" )
49- cmd .Flags ().Bool ("access-log" , true , "Enable the access log" )
50- cmd .Flags ().Bool ("no-compress" , false , "Disable Zstandard and Gzip compression" )
51- cmd .Flags ().Duration ("http-idle-timeout" , 60 * time .Second , "The maximum time in seconds that a client can be idle before the connection is closed." )
52- cmd .Flags ().Duration ("http-read-timeout" , 30 * time .Second , "The maximum time in seconds that a client can take to send the request headers." )
53- cmd .Flags ().Duration ("http-write-timeout" , 30 * time .Second , "The maximum time in seconds during which the client must read the response." )
26+ addServeFlags (cmd )
5427 cmd .RunE = caddycmd .WrapCommandFuncForCobra (cmdServeRails )
5528 },
5629 })
5730}
5831
32+ func addServeFlags (cmd * cobra.Command ) {
33+ cmd .Flags ().String ("pid-file" , "" , "Path to the PID file to control an existing process" )
34+ cmd .Flags ().Bool ("stop" , false , "Stop the running process" )
35+ cmd .Flags ().Bool ("phased-restart" , false , "Perform a phased restart of the server" )
36+ cmd .Flags ().String ("server-type" , "puma" , "The type of server (puma or unicorn) to control" )
37+ cmd .Flags ().Int ("target-port" , 3000 , "The port that your server should run on" )
38+ cmd .Flags ().Int ("http-port" , 80 , "The port to listen on for HTTP traffic." )
39+ cmd .Flags ().Int ("https-port" , 443 , "The port to listen on for HTTPS traffic." )
40+ cmd .Flags ().StringP ("listen" , "l" , "localhost" , "The address to which to bind the listener" )
41+ cmd .Flags ().String ("ssl-domain" , "" , "The domain name to use for SSL provisioning. If not set, SSL will be disabled." )
42+ cmd .Flags ().StringP ("files-path" , "f" , "" , "The path to the files to serve" )
43+ cmd .Flags ().BoolP ("debug" , "v" , false , "Enable verbose debug logs" )
44+ cmd .Flags ().Bool ("access-log" , true , "Enable the access log" )
45+ cmd .Flags ().Bool ("no-compress" , false , "Disable Zstandard and Gzip compression" )
46+ cmd .Flags ().Bool ("anycable-enabled" , false , "Activate AnyCable" )
47+ cmd .Flags ().Duration ("http-idle-timeout" , 60 * time .Second , "The maximum idle time for HTTP connections." )
48+ cmd .Flags ().Duration ("http-read-timeout" , 30 * time .Second , "The maximum read timeout for HTTP connections." )
49+ cmd .Flags ().Duration ("http-write-timeout" , 30 * time .Second , "The maximum write timeout for HTTP connections." )
50+ }
51+
5952func cmdServeRails (fs caddycmd.Flags ) (int , error ) {
6053 caddy .TrapSignals ()
6154
@@ -65,86 +58,75 @@ func cmdServeRails(fs caddycmd.Flags) (int, error) {
6558 serverType := fs .String ("server-type" )
6659
6760 if stop || phasedRestart {
68- upstream , err := utils .NewUpstreamProcess ("" , nil , false , pidFile )
69- if err != nil {
70- return 1 , err
71- }
72-
73- if stop {
74- if err := upstream .Stop (); err != nil {
75- return 1 , fmt .Errorf (errStopUpstream , err )
76- }
77- return 0 , nil
78- }
79-
80- if phasedRestart {
81- if err := upstream .PhasedRestart (serverType ); err != nil {
82- return 1 , fmt .Errorf (errPhasedRestart , err )
83- }
84- return 0 , nil
85- }
61+ return handleProcessControl (pidFile , stop , phasedRestart , serverType )
8662 }
8763
88- if loadConfigIfNeeded () {
64+ loaded , err := loadConfigIfNeeded ()
65+ if err != nil {
66+ return 1 , err
67+ }
68+ if loaded {
8969 select {}
9070 }
9171
72+ if fs .Int ("target-port" ) != 0 {
73+ os .Setenv ("PORT" , fmt .Sprintf ("%d" , fs .Int ("target-port" )))
74+ }
75+
9276 if err := utils .StartCaddyReverseProxy (fs ); err != nil {
9377 return 1 , err
9478 }
9579
96- return runUpstreamProcess ( fs , pidFile )
80+ select {}
9781}
9882
99- func loadConfigIfNeeded () bool {
100- curdir , _ := os .Getwd ()
101- configFile := filepath .Join (curdir , "Caddyfile" )
102-
103- if _ , err := os .Stat (configFile ); err != nil {
104- if errors .Is (err , os .ErrNotExist ) {
105- logger .Info (infoCaddyFileAbsent )
106- } else {
107- logger .Error (errAccessCaddyFile , zap .Error (err ))
108- }
109- return false
110- }
111-
112- config , _ , err := caddycmd .LoadConfig (configFile , "" )
83+ func handleProcessControl (pidFile string , stop , phasedRestart bool , serverType string ) (int , error ) {
84+ upstream , err := process .NewUpstreamProcess ("" , nil , false , pidFile )
11385 if err != nil {
114- logger .Error (errLoadCaddyConfig , zap .Error (err ))
115-
116- return false
86+ return 1 , err
11787 }
11888
119- err = caddy . Load ( config , true )
120- if err != nil {
121- logger . Error ( errLoadCaddyConfig , zap . Error ( err ) )
122-
123- return false
89+ if stop {
90+ if err := upstream . Stop (); err != nil {
91+ return 1 , fmt . Errorf ( "failed to stop upstream process: %v" , err )
92+ }
93+ return 0 , nil
12494 }
12595
126- logger .Info (infoCaddyFileLoaded )
96+ if phasedRestart {
97+ if err := upstream .PhasedRestart (serverType ); err != nil {
98+ return 1 , fmt .Errorf ("failed to phased restart upstream process: %v" , err )
99+ }
100+ return 0 , nil
101+ }
127102
128- return true
103+ return 1 , errors . New ( "invalid process control command" )
129104}
130105
131- func runUpstreamProcess ( fs caddycmd. Flags , pidFile string ) (int , error ) {
132- // Set PORT to be inherited by the upstream process.
133- os . Setenv ( "PORT" , fmt . Sprintf ( "%d" , fs . Int ( "target-port" )) )
106+ func loadConfigIfNeeded ( ) (bool , error ) {
107+ curdir , _ := os . Getwd ()
108+ configFile := filepath . Join ( curdir , "Caddyfile" )
134109
135- var args []string
136- if len (fs .Args ()) > 0 {
137- args = fs .Args ()[1 :]
110+ if _ , err := os .Stat (configFile ); err != nil {
111+ if errors .Is (err , os .ErrNotExist ) {
112+ caddyLogger .Info ("Caddyfile does not exist. Running directly" )
113+ } else {
114+ caddyLogger .Error ("Error accessing Caddyfile" , zap .Error (err ))
115+ }
116+ return false , nil
138117 }
139118
140- upstream , err := utils . NewUpstreamProcess ( fs . Arg ( 0 ), args , true , pidFile )
119+ config , _ , err := caddycmd . LoadConfig ( configFile , "" )
141120 if err != nil {
142- return 1 , err
121+ caddyLogger .Error ("Caddyfile loading error" , zap .Error (err ))
122+ return false , err
143123 }
144124
145- exitCode , err := upstream . Run ()
146- if err != nil {
147- return 1 , fmt . Errorf ( errRunUpstreamProcess , err )
125+ if err := caddy . Load ( config , true ); err != nil {
126+ caddyLogger . Error ( "Caddyfile loading error" , zap . Error ( err ))
127+ return false , err
148128 }
149- return exitCode , nil
129+
130+ caddyLogger .Info ("Caddyfile loaded successfully" )
131+ return true , nil
150132}
0 commit comments