Expanding on @JimB's answer:
Use a process supervisor to run your application as a specific user (and handle restarts/crashes, log re-direction, etc). setuid
and setgid
are universally bad ideas for multi-threaded applications.
Either use your OS' process manager (Upstart, systemd, sysvinit) or a standalone process manager (Supervisor, runit, monit, etc).
Here's an example for Supervisor:
[program:yourapp]
command=/home/yourappuser/bin/yourapp # the location of your app
autostart=true
autorestart=true
startretries=10
user=yourappuser # the user your app should run as (i.e. *not* root!)
directory=/srv/www/yourapp.com/ # where your application runs from
environment=APP_SETTINGS="/srv/www/yourapp.com/prod.toml" # environmental variables
redirect_stderr=true
stdout_logfile=/var/log/supervisor/yourapp.log # the name of the log file.
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=10
Further: if you're not reverse proxying and your Go application needs to bind to a port < 1024 (e.g. port 80 or 443) then use setcap - for example: setcap cap_net_bind_service=+ep /home/yourappuser/bin/yourapp
PS: I wrote a little article on how to run Go applications with Supervisor (starting from "I don't have Supervisor installed").