Upstart: Run service as unprivileged user and pre-start script as root
I have following upstart job:
description "posty api"
start on mysql
stop on shutdown
env RACK_ENV=production
setuid vmail
setgid vmail
chdir /opt/posty_api
pre-start script
mkdir -p /var/run/posty
chown -R vmail:root /var/run/posty
end script
exec /usr/local/bin/unicorn -D -c /opt/posty_api/unicorn.rb --env production >> /var/log/posty/upstart.log 2>&1
post-stop exec kill `cat /var/run/posty/unicorn.pid`
respawn
respawn limit 1 10
To create the folder in /var/run
I need root privileges. How can I run some parts of the upstart job as root, and the service itself as unprivileged user?
Solution 1:
upstart
has no facility equivalent to systemd
's PermissionsStartOnly
setting. All processes in the job run as the user set via the setuid
stanza, as the Cookbook says.
So do things the daemontools way.
Use setuidgid
, setuidgid
, s6-setuidgid
, chpst
, runuid
, or setuidgid
in the exec
stanza:
exec \ setuidgid somebody \ unicorn -D -c /opt/posty_api/unicorn.rb --env production >> /var/log/posty/upstart.log 2>&1
That's a terrible logging mechanism, by the way. The daemontools way would have a proper, automatically cycled, rotateable-on-demand, size-capped, log using multilog
, multilog
, s6-log
, svlogd
, tinylog
, or cyclog
. upstart
is tricky to integrate with those, however, given its expect
mechanism.
expect fork exec \ setuidgid somebody \ unicorn -D -c /opt/posty_api/unicorn.rb --env production 2>&1 | \ /usr/local/bin/chdir /var/log/ \ setuidgid log \ cyclog posty/unicorn/
(The chdir
here is the chain-loading one from the nosh
package, and isn't strictly necessary. But it makes things somewhat tidier.)