If you don't have multiple cores and/or you have a small VPN, you may end up with a huge slow down of your web app, when rake tasks are executed. This can be a big issue especially when you use something like whenever to perform periodic tasks. Luckily there's a nice program:
nice is a program found on Unix and Unix-like operating systems such as Linux. It directly maps to a kernel call of the same name. nice is used to invoke a utility or shell script with a particular priority, thus giving the process more or less CPU time than other processes. A niceness of −20 is the highest priority and 19 or 20 is the lowest priority. The default niceness for processes is inherited from its parent process and is usually 0.
With nice you can tell your Linux kernel to give your rake tasks the lowest priority possible. Thanks to that, you can make sure, that any task with higher priority (like web UI server) won't get stuck because of the background rake task.
If you use a gem like whenever, you can easily integrate nice with it:
job_type :runner, "cd :path && nice -n 19 script/rails runner -e :environment ':task' :output"
every 30.minutes do
runner 'Worker.new.perform'
end
or for a rake task with whenever, you can use this:
job_type :runner, "cd :path && :environment_variable=:environment nice -19 bundle exec rake :task --silent :output"
every 15.minutes do
runner 'your_task'
end
Note: Of course this will help, when CPU is your bottleneck. Keep in mind that you're rake task might slow down your website because of many more reasons (IO, DB, etc).
At this point, you should be able to execute puma worker:
# You should execute this from a git user
cd /home/git/gitlab && exec bundle exec puma -C /home/git/gitlab/config/puma.rb
[4419] Puma starting in cluster mode...
[4419] * Version 2.9.0 (ruby 2.1.2-p95), codename: Team High Five
[4419] * Min threads: 4, max threads: 32
[4419] * Environment: production
[4419] * Process workers: 2
[4419] * Preloading application
[4419] * Listening on unix:///home/git/gitlab/tmp/puma/sock
Init Script
To manage my Pumas I use Jungle. You can read more about it here. From this point, I assume that you have figured out a way to autostart GitLab Puma process (if not, you'll have to start it each time manually - good luck!).
Unfortunately it is not all. Default GitLab init script (provided with GitLab sources) will try to run Unicorn, so we need to silent it (but we need to keep the Sidekiq part).
To do so, we have to change the /etc/init.d/gitlab script.
start_gitlab() method (line 165) - we have to comment the else case:
# Then check if the service is running. If it is: don't start again.
if [ "$web_status" = "0" ]; then
echo "The Unicorn web server already running with pid $wpid, not restarting."
# else
# Remove old socket if it exists
# rm -f "$socket_path"/gitlab.socket 2>/dev/null
# Start the web server
# RAILS_ENV=$RAILS_ENV bin/web start
fi
wait_for_pids() method (line 78) - we have to remote the first condition from while loop. We no longer check for web_server_pid_path:
wait_for_pids(){
# We are sleeping a bit here mostly because sidekiq is slow at writing it's pid
i=0;
while [ ! -f $sidekiq_pid_path ]; do
sleep 0.1;
i=$((i+1))
if [ $((i%10)) = 0 ]; then
echo -n "."
elif [ $((i)) = 301 ]; then
echo "Waited 30s for the processes to write their pids, something probably went wrong."
exit 1;
fi
done
echo
}
There are some other places that you could modify - so you would not get any warnings, but hey! Those are just warnings. What I did above is an absolute minimum for starting/stopping Sidekiq without any Unicorn errors.
Nginx server block
And an example Nginx server block (virtual host) config: