I’ve been hosting my Gitlab instance for some time now. Gives me the freedom of experimenting with various features and also forces me to learn a thing or two about it.

Install I currently have has been done via installation from source. Reason for that was that Omnibus package has certain things in which would break other components on that system.

So long story short, the main issue I had with it was upgrading it to latest patch release. This issue got even amplified by the fact Gitlab releases new versions quite often, so I simply had to automate it.

You can take many different approaches, but I decided to do it in bash. Full script for upgrading instance is as follows:

#!/usr/bin/env bash

# Define variables
GITLAB_PATCH_VERSION="$1"
GITLAB_INSTALL_DIR="/home/git/gitlab"
GITLAB_SHELL_INSTALL_DIR="/home/git/gitlab-shell"
GITLAB_CURRENT_VERSION=$(cat /home/git/gitlab/VERSION 2> /dev/null)

# Define functions
gitlab_backup() {
        cd "$GITLAB_INSTALL_DIR" || exit 1
        bundle exec rake gitlab:backup:create RAILS_ENV=production
}

gitlab_stop() {
        sudo systemctl stop gitlab
}

gitlab_start() {
        sudo systemctl start gitlab
}

gitlab_update() {
        cd "$GITLAB_INSTALL_DIR" || exit 1
        git fetch --all
        git checkout -- Gemfile.lock db/schema.rb locale
        git checkout "v$GITLAB_PATCH_VERSION" -b "v$GITLAB_PATCH_VERSION"

        echo -e "---\nBUNDLE INSTALL\n---"
        bundle install --without development test mysql --deployment
        echo -e "---\nBUNDLE CLEAN\n---"
        bundle clean
        echo -e "---\nYARN INSTALL\n---"
        yarn
        echo -e "---\nDB MIGRATIONS\n---"
        bundle exec rake db:migrate RAILS_ENV=production
        echo -e "---\nGETTEXT PACK\n---"
        bundle exec rake gettext:pack RAILS_ENV=production
        echo -e "---\nGETTEXT PO TO JSON\n---"
        bundle exec rake gettext:po_to_json RAILS_ENV=production
        echo -e "---\nASSETS\n---"
        bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile cache:clear RAILS_ENV=production NODE_ENV=production

        # Upgrade Gitlab Workhorse
        echo -e "---\nGITLAB WORKHORSE\n---"
        bundle exec rake "gitlab:workhorse:install[/home/git/gitlab-workhorse]" RAILS_ENV=production

        # Upgrade Gitaly
        echo -e "---\nGITALY\n---"
        bundle exec rake "gitlab:gitaly:install[/home/git/gitaly,/home/git/repositories]" RAILS_ENV=production

        # Upgrade Gitlab Shell
        cd "$GITLAB_SHELL_INSTALL_DIR" || exit 1
        git fetch --all --tags
        git checkout "v$(</home/git/gitlab/GITLAB_SHELL_VERSION)" -b "v$(</home/git/gitlab/GITLAB_SHELL_VERSION)"
        sh -c 'if [ -x bin/compile ]; then bin/compile; fi'
}

gitlab_status() {
        cd "$GITLAB_INSTALL_DIR" || exit 1
        bundle exec rake gitlab:env:info RAILS_ENV=production
        bundle exec rake gitlab:check RAILS_ENV=production
}

# Perform variable checks and start upgrade
if [ -z "$GITLAB_PATCH_VERSION" ] ; then
        echo -e "[ERROR] Undefined desired version"
        echo -e "Usage:\n$0 GITLAB_PATCH_VERSION"
        exit
elif [ -z "$GITLAB_CURRENT_VERSION" ] ; then
        echo -e "[ERROR] Couldn't determine current Gitlab version. Exiting..."
        exit
elif [ "$GITLAB_CURRENT_VERSION" == "$GITLAB_PATCH_VERSION" ] ; then                                                                                                                                                                                                            
        echo -e "[ERROR] Gitlab is already updated to the specified patch version. Nothing to do here, exiting..."                                                                                                                                                              
        exit                                                                                                                                                                                                                                                                    
else                                                                                                                                                                                                                                                                            
        echo -e "[NOTICE] Starting upgrade process..."                                                                                                                                                                                                                          
        echo -e "\t- Current version: $GITLAB_CURRENT_VERSION"                                                                                                                                                                                                                  
        echo -e "\t- New version: $GITLAB_PATCH_VERSION"                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                
        # Run all of the steps                                                                                                                                                                                                                                                  
        gitlab_backup                                                                                                                                                                                                                                                           
        gitlab_stop                                                                                                                                                                                                                                                             
        gitlab_update                                                                                                                                                                                                                                                           
        gitlab_start                                                                                                                                                                                                                                                            
        gitlab_status                                                                                                                                                                                                                                                           
fi                                     

Few requirements and assumptions:

  • Gitlab is installed under git user on the machine
  • git user has access to start|stop|status|restart the gitlab service
  • git user has access to update/install ruby gems (I use rbenv)

For permission to start|stop|status|restart the gitlab service I have following in /etc/sudoers.d/git

git ALL=NOPASSWD:/bin/systemctl restart gitlab*                                                                                                                                                                                                                                 
git ALL=NOPASSWD:/bin/systemctl start gitlab*
git ALL=NOPASSWD:/bin/systemctl status gitlab*
git ALL=NOPASSWD:/bin/systemctl stop gitlab*