-
Notifications
You must be signed in to change notification settings - Fork 4
/
DEPLOYING
184 lines (130 loc) · 5.86 KB
/
DEPLOYING
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
Deploying application daemons with niet
=======================================
If you deploy using the user you want to run the app daemon is, you can just run niet directly to
start up your daemon. To restart your daemon after a new release, just sent niet a TERM signal.
Most sites host only one app per VM or run each app on the VM under individual user accounts. If
you do this, then you can simply use killall to send signals to the niet instance(s) running under
the user account you're deploying with.
namespace :some_daemon do
task :start do
run "niet #{current_path}/lib/some_daemon.rb"
end
task :restart do
run "killall niet"
end
task :stop do
run "killall -QUIT niet"
end
end
If you have niet processes from other users on the same box, you should use -u to target only yours:
task :restart do
run "killall -u some_user niet"
end
task :stop do
run "killall -u some_user -QUIT niet"
end
Depending on your deployment configuration, you may need to use "sudo" instead of "run".
To hook these tasks into a deploy you can use:
after "deploy:start", "some_daemon:start"
after "deploy:restart", "some_daemon:restart"
However you shouldn't use killall on Solaris, because their killall really does kill all. Instead
you can use the pkill utility, which works more consistently across different types of unixy OSs.
In Solaris it is installed by default, and in Linux it's usually in the 'psmisc' package.
task :restart do
run "pkill niet"
end
task :stop do
run "pkill -QUIT niet"
end
Or if there are other niet users:
task :restart do
run "pkill -u some_user niet"
end
task :stop do
run "pkill -QUIT -u some_user niet"
end
If you absolutely need to run different apps under the same user and don't want to restart the
daemons from all the apps as a group, then filtering by user isn't enough. You can either use
pkill's ability to filter on the command, or use the PID file option (-p). For example:
task :start do
run "niet -p #{shared_path}/some_daemon.pid #{current_path}/lib/some_daemon.rb"
end
task :restart do
run "kill `cat #{shared_path}/some_daemon.pid`"
end
task :stop do
run "kill -QUIT `cat #{shared_path}/some_daemon.pid`"
end
(The author thinks you shouldn't need to set your system up this way. Separate apps should
generally run under separate users if they have to share a VM.)
Note that the above stop scripts initiate a stop of the daemon, but don't wait for it to complete.
If you want to wait until the daemon terminates, you can use pgrep (or pkill -0) to see if the
processes are running, but the easiest thing to do is to just repeat the action until there's no
processes left:
run "while killall -u some_user -QUIT -q niet; do sleep 1; done"
Or:
run "while pkill -QUIT -u some_user niet; do sleep 1; done"
Again, depending on your deployment configuration, you may need to use "sudo" instead of "run".
These 'while' lines are small shell loops, so if you are running them manually at the command line
under sudo, you'll need to use a sh command line, for example:
sudo sh -c 'while pkill -QUIT -u some_user niet; do sleep 1; done'
You should make sure that your daemons will be started if/when the VM reboots. For example, you
could put this in the crontab for some_user:
@reboot niet /apps/some_app/current/lib/some_daemon.rb
This has the advantage that you can install this startup job without needing root access, by
running crontab -e as the user (assuming cron is installed on the system).
Or if you have root access to the server/VM, you could add something like this in /etc/init.d:
#!/bin/sh
case "$1" in
start)
su some_user -c "niet /apps/some_app/current/lib/some_daemon.rb"
;;
stop)
while pkill -QUIT -u some_user niet; do sleep 1; done
;;
restart)
pkill -u some_user niet
;;
*)
echo "Usage: $0 {start|stop|restart}" >&2
exit 1
;;
esac
exit 0
On Linux, you can then use "update-rc.d your_init_file_name defaults" to set this up for system
startup & shutdown.
You can start a number of daemons separately and still ask them to shut down (or ask them to restart
their apps) with a single command:
#!/bin/sh
case "$1" in
start)
su some_user -c "niet /apps/some_app/current/lib/some_daemon.rb"
su some_user -c "niet /apps/some_app/current/lib/another_daemon.rb"
su different_user -c "niet /apps/different_app/current/lib/different_daemon.rb"
;;
stop)
while pkill -QUIT niet; do sleep 1; done
;;
restart)
pkill niet
;;
*)
echo "Usage: $0 {start|stop|restart}" >&2
exit 1
;;
esac
exit 0
Again, if you run a number of daemons and want to control them using individual init.d scripts,
you can make the script more or less selective using the -u user filtering and/or pkill's process
filtering and/or PID files.
It shouldn't be necessary to find the PID of your app itself; note that if your app responds to the
USR1, USR2, or HUP signals, you can send the signal to niet and it will pass it on to the process.
If you have trouble getting your app to start up the same way it does when you run it from the
command line, your app probably has an implicit dependency on one or both of:
- The $PATH that you have in your interactive shell. In particular cron normally has a very tightly
restricted PATH that doesn't include directories like /usr/local. Scripts will usually need to
give the full path to any subcommands that they run, or add to $PATH.
- The current directory you are normally in when you run it. It's more convenient to use programs
which will work even when not run in their 'home' directory, but you can use niet's -c option to
set the current directory if the app requires it. (By default niet will always chdir to / so that
it won't hold open any directory handles you might want to remove or umount.)