GitBucket as a service on Debian

If you want to host your own Git Server you have multiple possibilities. Here I want to describe how to run GitBucket, an Open Source GitHub like platform.

The focus of this article is to show you how to setup GitBucket as a service (incl. autostart) on a Debian OS.

Installation in short

Java 8

GitBucket required Java8 to run. So first we install Java8 on the machine if not already done.

echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list
echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886
apt-get update
apt-get install oracle-java8-installer

This will add additional repositories to your system that contains the Java8 installer (not the Java8 binaries). This installer will download Java8 binaries for you and install them correctly. While installing you have to accept the license and after that you can check the java version with the following command:

java --version

For more detailed description see HOW TO INSTALL ORACLE JAVA 8 IN DEBIAN VIA REPOSITORY [JDK8].

User and GitBucket

 

First of all  we should avoid to run services using root user because of security reasons. So we will create a new user, switch to that user and go to the home directory:

adduser gitbucket
su gitbucket
cd

After that we download the latest version of GitBucket from GitHub Releases:

wget https://github.com/gitbucket/gitbucket/releases/download/4.9/gitbucket.war

Now you can first run GitBucket using the following command:

java -jar gitbucket.war

See GitBucket readme for detailed information.

Run as a service with autostart on boot

Now we want to setup GitBucket as a service with autostart on OS boot.

For that we create two files with the following contents:

File: gitbucket_startscript.sh :

#!/bin/sh

COMMANDLINE_PARAMETERS="${2}" #add any command line parameters you want to pass here
D1=$(readlink -f "$0")
BINARYPATH="$(dirname "${D1}")"
cd "${BINARYPATH}"
LIBRARYPATH="$(pwd)"
BINARYNAME="gitbucket"

case "$1" in
	start)
		if [ -e gitbucket.pid ]; then
			if ( kill -0 $(cat gitbucket.pid) 2> /dev/null ); then
				echo "The server is already running, try restart or stop"
				exit 1
			else
				echo "gitbucket.pid found, but no server running. Possibly your previously started server crashed"
				echo "Please view the logfile for details."
				rm gitbucket.pid
			fi
		fi
		if [ "${UID}" = "0" ]; then
			echo WARNING ! For security reasons we advise: DO NOT RUN THE SERVER AS ROOT
			c=1
			while [ "$c" -le 10 ]; do
				echo -n "!"
				sleep 1
				c=$(($c+1))
			done
			echo "!"
		fi
		echo "Starting the GitBucket server"
		if [ -e "$BINARYNAME" ]; then
			if [ ! -x "$BINARYNAME" ]; then
				echo "${BINARYNAME} is not executable, trying to set it"
				chmod u+x "${BINARYNAME}"
			fi
			if [ -x "$BINARYNAME" ]; then
				export LD_LIBRARY_PATH="${LIBRARYPATH}:${LD_LIBRARY_PATH}"		
				nohup java -jar $BINARYNAME $COMMANDLINE_PARAMETERS > /dev/null &
				PID=$!
				ps -p ${PID} > /dev/null 2>&1
				if [ "$?" -ne "0" ]; then
					echo "GitBucket server could not start"
				else
					echo $PID > gitbucket.pid
					echo "GitBucket server started, for details please view the log file"
				fi
			else
				echo "${BINARNAME} is not exectuable, cannot start GitBucket server"
			fi
		else
			echo "Could not find binary, aborting"
			exit 5
		fi
	;;
	stop)
		if [ -e gitbucket.pid ]; then
			echo -n "Stopping the GitBucket server"
			if ( kill -TERM $(cat gitbucket.pid) 2> /dev/null ); then
				c=1
				while [ "$c" -le 300 ]; do
					if ( kill -0 $(cat gitbucket.pid) 2> /dev/null ); then
						echo -n "."
						sleep 1
					else
						break
					fi
					c=$(($c+1)) 
				done
			fi
			if ( kill -0 $(cat gitbucket.pid) 2> /dev/null ); then
				echo "Server is not shutting down cleanly - killing"
				kill -KILL $(cat gitbucket.pid)
			else
				echo "done"
			fi
			rm gitbucket.pid
		else
			echo "No server running (gitbucket.pid is missing)"
			exit 7
		fi
	;;
	restart)
		$0 stop && $0 start ${COMMANDLINE_PARAMETERS} || exit 1
	;;
	status)
		if [ -e gitbucket.pid ]; then
			if ( kill -0 $(cat gitbucket.pid) 2> /dev/null ); then
				echo "Server is running"
			else
				echo "Server seems to have died"
			fi
		else
			echo "No server running (gitbucket.pid is missing)"
		fi
	;;
	*)
		echo "Usage: ${0} {start|stop|restart|status}"
		exit 2
esac
exit 0

Copy that file to the home directory of the user “gitbucket” /home/gitbucket and execute the following commands:

chown gitbucket:gitbucket /home/gitbucket/gitbucket_startscript.sh
chmod u+x /home/gitbucket/gitbucket_startscript.sh

This file contains the logic to start/stop/restart/status commands for GitBucket service.

 

File: gitbucket :

#! /bin/sh
### BEGIN INIT INFO
# Provides:		 gitbucket
# Required-Start:	 $remote_fs $syslog
# Required-Stop:	 $remote_fs $syslog
# Default-Start:	 2 3 4 5
# Default-Stop:		 0 1 6
# Short-Description: GitBucket Server
# Description:		 Startup Init-Script for GitBucket Server
### END INIT INFO

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="GitBucket Server"
NAME=gitbucket
USER=gitbucket
BINARY=gitbucket
BINARY_BIN=/home/gitbucket
DAEMON=gitbucket_startscript.sh
DAEMON_ARGS=
PIDFILE=$BINARY_BIN/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

#
# Function that starts the daemon/service
#
do_start()
{
  su $USER -s /bin/sh -c "$BINARY_BIN/$DAEMON start $DAEMON_ARGS"
}

#
# Function that stops the daemon/service
#
do_stop()
{
  su $USER -s /bin/sh -c "$BINARY_BIN/$DAEMON stop $DAEMON_ARGS"
}

#
# Function that shows the status of to the daemon/service
#
do_status()
{
  su $USER -s /bin/sh -c "$BINARY_BIN/$DAEMON status $DAEMON_ARGS"
}

case "$1" in
  start)
	log_daemon_msg "Starting $DESC" ""
	do_start
	case "$?" in
	  0|1) log_end_msg 0 ;;
	  2) log_end_msg 1 ;;
	esac
	;;
  stop)
	log_daemon_msg "Stopping $DESC" ""
	do_stop
	case "$?" in
	  0|1) log_end_msg 0 ;;
	  2) log_end_msg 1 ;;
	esac
	;;
  status)
	do_status
	status_of_proc "$BINARY" "$DESC" && exit 0 || exit $?
	;;
  restart)
	log_daemon_msg "Restarting $DESC" ""
	do_stop
	case "$?" in
	  0|1)
		do_start
		case "$?" in
		  0) log_end_msg 0 ;;
		  1) log_end_msg 1 ;; # Old process is still running
		  *) log_end_msg 1 ;; # Failed to start
		esac
		;;
	  *)
		# Failed to stop
		log_end_msg 1
		;;
	esac
	;;
  *)
	echo "Usage: $SCRIPTNAME {start|stop|status|restart}"
	exit 3
	;;
esac

:

Copy this file to /etc/init.d  and execute the following commands:

# set permissions
chmod 755 /etc/init.d/gitbucket

# register for autostart
update-rc.d gitbucket default

This file defines the gitbucket service that can be automatically started.

Now you have to start the service by your own (if you don’t want to restart the complete server):

/etc/init.d/gitbucket start

 

Gitbucket access on port 80

Here we want to use Gitbucket on port 80 parallel to Apache Webserver using mod_proxy .

Install and enable mod_proxy  and mod_proxy_http :

sudo apt-get install libapache2-mod-proxy-html
a2enmod proxy proxy_http

Add new VirtualHost configuration (ignore .well-known  requests for Let’s Encrypt):

<VirtualHost <HOST_IP>:80>
  ServerName <DOMAIN>
  ProxyPreserveHost On
  ProxyRequests off
  ProxyPass /.well-known !
  ProxyPass / http://localhost:8080/
  ProxyPassReverse / http://localhost:8080/
</VirtualHost>

Restart Apache

service apache2 restart

Disable direct access for GitBucket, it should be only accessable over the Proxy. Edit the gitbucket_startscript.sh and change the commandline parameters:

COMMANDLINE_PARAMETERS="--host=localhost""${2}"