Saturday, November 30, 2013

GitBlit at Nginx Issue on Pushing

I recently bumped into a problem with Gitblit which is deployed on a Jetty instance at my public virtual machine. I got some errors when pushing a change to my repository. It says "File too large to upload". This is error 413 and I first suspected Jetty but I have found out that the issue in on Nginx. It's not actually an issue but I just need to do some tweaking with my Nginx installation so I won't get the error anymore.


Client Max Body Size (client_max_body_size)

I don't know the exact default value of client_max_body_size but this parameter when set to a very high value will allow an upload not more that to that set value.

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        gzip_disable "msie6";

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/x-      
        # javascript text/xml ap$

        ##
        # nginx-naxsi config
        ##
        # Uncomment it if you installed nginx-naxsi
        ##

        #include /etc/nginx/naxsi_core.rules;

        ##
        # nginx-passenger config
        ##
        # Uncomment it if you installed nginx-passenger
        ##

        #passenger_root /usr;
        #passenger_ruby /usr/bin/ruby;

        client_max_body_size 300M;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

When I set about 300M to my Nginx's client_max_body_size, I don't get the error 413 anymore. 

That's all! 

Proxy Pass Gitblit and Nexus in Nginx

I have done this set-up several weeks ago. I just want to share this to anyone who's looking for some steps to set-up the same pool of technologies in his machine.

I have been using Apache 2 as my web server for more than a year now, but I still don't understand how to set it up. I'm not sure if I'm just too slow for Apache 2 or its documentation just lack the details. When I started using Nginx, I thought I never come back to Apache 2 anymore. And, it's really true. Nginx is a lot better to understand and it just took me some time to set-up and configure my server again.

What I will show is how I pass proxy my Gitblit and Nexus applications.

Ngix Location Patterns

Before I show you how I pass proxy my applications, please read the following excerpts from Nginx documentation site.

location  = / {
  # matches the query / only.
  [ configuration A ] 
}
location  / {
  # matches any query, since all queries begin with /, but regular
  # expressions and any longer conventional blocks will be
  # matched first.
  [ configuration B ] 
}
location /documents/ {
  # matches any query beginning with /documents/ and continues searching,
  # so regular expressions will be checked. This will be matched only if
  # regular expressions don't find a match.
  [ configuration C ] 
}
location ^~ /images/ {
  # matches any query beginning with /images/ and halts searching,
  # so regular expressions will not be checked.
  [ configuration D ] 
}
location ~* \.(gif|jpg|jpeg)$ {
  # matches any request ending in gif, jpg, or jpeg. However, all
  # requests to the /images/ directory will be handled by
  # Configuration D.   
  [ configuration E ] 
}

You may read this part at http://wiki.nginx.org/HttpCoreModule.

Nginx Configuration Folders

I'm using Linux so my installation of Nginx might be a little different with that of Windows. But anyways, the way to configure Nginx must still be the same. The following is the content of the Nginx configuration folder (/etc/nginx).

total 80
drwxr-xr-x   5 root root  4096 Nov 12 06:24 ./
drwxr-xr-x 131 root root 12288 Nov 24 00:15 ../
drwxr-xr-x   2 root root  4096 May 10  2013 conf.d/
-rw-r--r--   1 root root   898 Apr 29  2013 fastcgi_params
-rw-r--r--   1 root root  2258 Apr 29  2013 koi-utf
-rw-r--r--   1 root root  1805 Apr 29  2013 koi-win
-rw-r--r--   1 root root  2085 Apr 29  2013 mime.types
-rw-r--r--   1 root root  5287 Apr 29  2013 naxsi_core.rules
-rw-r--r--   1 root root   287 Apr 29  2013 naxsi.rules
-rw-r--r--   1 root root   222 Apr 29  2013 naxsi-ui.conf
-rw-r--r--   1 root root  1644 Nov 27 08:03 nginx.conf
-rw-r--r--   1 root root   131 Apr 29  2013 proxy_params
-rw-r--r--   1 root root   465 Apr 29  2013 scgi_params
drwxr-xr-x   2 root root  4096 Nov 26 23:48 sites-available/
drwxr-xr-x   2 root root  4096 Nov 24 00:27 sites-enabled/
-rw-r--r--   1 root root   532 Apr 29  2013 uwsgi_params
-rw-r--r--   1 root root  3071 Apr 29  2013 win-utf

The main configuration file here is nginx.conf. If you open this file, you will find a few configuration blocks, but will focus on the HTTP configuration since we are talking about web application here. Note that Nginx can also pass proxy other stuff like SMTP.

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        gzip_disable "msie6";

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/x-      
        # javascript text/xml ap$

        ##
        # nginx-naxsi config
        ##
        # Uncomment it if you installed nginx-naxsi
        ##

        #include /etc/nginx/naxsi_core.rules;

        ##
        # nginx-passenger config
        ##
        # Uncomment it if you installed nginx-passenger
        ##

        #passenger_root /usr;
        #passenger_ruby /usr/bin/ruby;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

Notice the last line with the keyword include. This statement says that it will include some configuration from configuration files under the folder /etc/nginx/sites-enabled.

Initially after installing Nginx, you will find a file named default under /etc/nginx/sites-enabled. This file contains server block configuration like the following:

server {
     listen 80;
     server_name my.server.com
     
     location / {
               root 8/usr/share/nginx/html;
        index index.html index.htm;          
     }
}

By calling include in nginx.conf, the effective configuration will be something like the following:

http {
     ...
     ...
     server {
          listen 80;
          server_name my.server.com
     
          location / {
                         root 8/usr/share/nginx/html;
            index index.html index.htm;          
          }
     }
}

For my purpose, I have removed the default file and created my own configuration file. I created myserver configuration file at /etc/nginx/sites-enabled and here are the contents:

server {
        listen          80;
        server_name     my.server.com;

        location / {
                proxy_pass           http://myserver.azurewebsites.net;
        }

        location ^~ /gitblit/ {
                proxy_pass           http://localhost:18080;
                proxy_set_header     X-Real-IP $remote_addr;
                proxy_set_header     X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header     Host $http_host;
        }

        location ^~ /nexus/ {
                proxy_pass           http://localhost:18090;
                proxy_set_header     X-Real-IP $remote_addr;
                proxy_set_header     X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header     Host $http_host;
        }

        location ^~ /application3/ {
                proxy_pass           http://localhost:18600;
                proxy_set_header     X-Real-IP $remote_addr;
                proxy_set_header     X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header     Host $http_host;
        }

        location ^~ /application4/ {
                proxy_pass           http://localhost:18700;
                proxy_set_header     X-Real-IP $remote_addr;
                proxy_set_header     X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header     Host $http_host;
        }
}

I have about six location blocks. All of these points to the respective Jetty server instances that I have created some weeks ago, except for one. The root / points to the Windows Azure website that I have recently created. I separate this application for some purpose that I will not mention here. All will be accessed via Nginx or via port 80.

That's all. I hope you get something from here.
Thanks for reading.

Monday, November 18, 2013

Convert Maven Project to Gradle in an instant

At first, I was very hesitant to convert all my Maven projects to Gradle because of the set-up and configurations I have to do. Though Gradle is Groovy-based, there is still much I need to know before I can accept it as I am accepting Maven now as my build automation tool. But things may change from now on. I discovered something good while playing around.

The Transition

I was about to create a Wicket project in Maven. As most Maven users know, we can "quickstart" a project using Maven Archetypes. And, Wicket happens to be a very fan of Maven ever since. Of course, they are both created by Apache.

Now, to start.

mvn archetype:generate -Dfilter=wicket

There will be displayed a lot of Maven Archetypes using Wicket as the Java Web Framework. I just chose the wicket-quickstart-archetype.

Then, I input groupId, artifactId, version, as usual.

When done, I change-directory'ed to the project's folder. I don't know the exact meaning of the Gradle task. But, I typed and entered

gradle setupBuild

Poop! It became Koko Gradle! Yeah, corny it may sound. But yes, I confirmed when I looked onto the build.gradle file.

apply plugin: 'java'
apply plugin: 'maven'

group = 'com.sudocode.checkman'
version = '0.0.01'

description = """quickstart"""

sourceCompatibility = 1.6
targetCompatibility = 1.6



repositories {
     maven { url "http://www.sudocodesystems.com/nexus/content/groups/public" }        
     maven { url "https://repository.apache.org/content/repositories/snapshots/" }
     maven { url "http://repo.maven.apache.org/maven2" }
}
dependencies {
    compile group: 'org.apache.wicket', name: 'wicket-core', version:'6.12.0'
    compile group: 'org.slf4j', name: 'slf4j-log4j12', version:'1.6.4'
    compile group: 'log4j', name: 'log4j', version:'1.2.16'
    testCompile group: 'junit', name: 'junit', version:'4.11'
    providedCompile group: 'org.eclipse.jetty.aggregate', name: 'jetty-all-server', version:'7.6.13.v20130916'
}


I imported the project in IntelliJ IDEA to confirm. I just bumped into a problem on the highlighted text above. You have to change it to testCompile in able for Gradle to include the Jetty libraries.

Now, I am confident to migrate everything to Gradle. I never thought the command gradle setupBuild was that powerful.

Tuesday, November 12, 2013

Deploying Java Web Applications in Separate Jetty Instances

I recently have a requirement to deploy GitBlit and Nexus in separate Jetty Application Server instances. It sounds easy right? I could place a package of Jetty on our Linux box and just duplicate so I could have two Jetty instances. But, it was not so straight forward. There were a lot of stuff need to customize, like separate PID of each instance, separate web application directories, etc. I had to read the shell script to start Jetty and find out how to arrive at the set-up required for me to do.

Here's to save you time to research and do experimentation. I documented what to do and how to do things in deploying two web applications (or more than) in separate Jetty instances.

Requirements

Download Jetty package at http://download.eclipse.org/jetty/. Try to download the latest stable version. It's currently 9.0.6 when I wrote this post.

Prepare your Web Archive (WAR) files. For this post, I deploy GitBlit and Nexus WAR files.

Note: I deployed these WARs at a Linux box so if you are using other OS like Windows, you might need to do some stuff differently.

Procedure

Extract Jetty Package

In this procedure, you don't need to duplicate the Jetty package. You just need one package and I recommend the following directory structure for Linux systems.

drwxr-xr-x  3 root     root     4096 Nov 11 23:46 ./
drwxr-xr-x  3 root     root     4096 Nov 12 06:56 ../
lrwxrwxrwx  1 root     root        6 Nov 11 23:46 default -> latest/
drwxrwxr-x 14 rmaranan rmaranan 4096 Nov 13 07:32 jetty-distribution-9.0.6.v20130930/
lrwxrwxrwx  1 root     root       34 Nov 11 23:45 latest -> jetty-distribution-9.0.6.v20130930/

I based this install folder structure from the Java installation in Fedora. Basically in my work, I created two soft links latest and default. The latest links to the latest Jetty package and the default links to the latest soft link. With this set-up, I could easily switch between different Jetty packages in the future.

For those who are not familiar yet, here's how I extracted my Jetty package. Assuming you have root access to your Linux box.

cp jetty-distribution-9.0.7.v20130930.tar.gz /opt

cd /opt

tar xvf jetty-distribution-9.0.7.v20130930.tar.gz

ln -s jetty-distribution-9.0.7.v20130930 latest

ln -s latest default

Set-up Web Application Directories

I know advance Jetty users and Java programmers have already figured this out. The secret for having one package for two Jetty instances is having two separate web application directories. So here, we create directories gitblit-apps and nexus-apps for Gitblit and Nexus applications respectively.

cd /opt/jetty/default
mkdir gitblit-apps
mkdir nexus-apps

Then, we copy the WAR files for each respective directories.

cp ~/war-files/gitblit.war gitblit-apps
cp ~/war-files/nexus.war nexus-apps

Finally, we open to modify the Jetty deployment configuration. This is to make the web application directory configurable.

nano etc/jetty-deploy.xml

Inside jetty-deploy.xml, look for the webappprovider Jetty call. And, add the highlighted text below.

<Call id="webappprovider" name="addAppProvider">
    <Arg>
        <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
            <Set name="monitoredDirName">
                <Property name="jetty.home" default="." />
                <Property name="jetty.sudocode.webapps" default="/webapps" />
            </Set>
            <Set name="defaultsDescriptor">
                <Property name="jetty.home" default="."/>/etc/webdefault.xml
            </Set>
            <Set name="scanInterval">1</Set>
            <Set name="extractWars">true</Set>
            <Set name="configurationManager">
                <New class="org.eclipse.jetty.deploy.PropertiesConfigurationManager">
                <!-- file of context configuration properties
                    <Set name="file"><SystemProperty name="jetty.home"/>/etc/some.properties</Set>
                  -->
                  <!-- set a context configuration property
                  <Call name="put"><Arg>name</Arg><Arg>value</Arg></Call>
                  -->
                </New>
            </Set>
        </New>
    </Arg>
</Call>

The property jetty.sudocode.webapps will hold the web application directory path when we run each instances of Jetty for Gitblit and Nexus.

Create Customized Start-up Script

To make it more organized, We put the start-up scripts at the /etc/jetty/default/bin. And, we create sub-directories for Gitblit and Nexus start-up scripts.

mkdir bin/gitblit
mkdir bin/nexus

Then on each sub-directory we create separate start-up scripts but these scripts should contain same code except for the values of the parameters (which holds our Jetty run-time properties).

nano bin/gitblit/gitblit-starter

Notice that I have been using nano. If you are not so familiar with Linux, you could actually use any text editor which you are comfortable.

Inside the gitblit-starter script file, we write the following. Notice all the configurable parameters are at the top of the script.

#!/bin/sh

JETTY_BASE_DIR=/opt/jetty/default                                               # Jetty Installation folder
JAVA_EXEC=java                                                                  # java executable
JETTY_PORT=18080                                                                # HTTP Port
JETTY_HTTPS_PORT=18081                                                          # HTTPS Port
JETTY_STOP_PORT=18082                                                           # STOP Port
JETTY_STOP_KEY=ilovejetty                                                       # STOP Key
JETTY_SUDOCODE_WEBAPPS=/gitblit-apps                                            # Location of WAR under ${jetty.home}
JETTY_START_JAR=start.jar                                                       # Location of start.jar
JETTY_HOST=localhost                                                            # Jetty Host
JETTY_JVM_OPTS="-Xms192m -Xmx256m -XX:MaxPermSize=64m"                          # JVM Options

####################################################################################################################
# Don't touch the rest as much as possible
# This file must reside at ${jetty.home}
# Romeo H. Maranan Jr.
# Sudocode Systems Solutions, Inc.
JAVA_EXEC_PARAMS=""
JETTY_COMMAND=$1
JETTY_STOP=""
EXECUTOR_PWD=$(pwd)

changeDirToJettyHome() {
        cd $JETTY_BASE_DIR
}

changeDirBack() {
        cd $EXECUTOR_PWD
}
executeJetty() {
        JAVA_EXEC_PARAMS=" $JETTY_JVM_OPTS"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -DSTOP.PORT=$JETTY_STOP_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -DSTOP.KEY=$JETTY_STOP_KEY"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -jar $JETTY_START_JAR"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS --module=http"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.port=$JETTY_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.https.port=$JETTY_HTTPS_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.sudocode.webapps=$JETTY_SUDOCODE_WEBAPPS"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.host=$JETTY_HOST"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS $JETTY_STOP"
        COMMAND="$JAVA_EXEC $JAVA_EXEC_PARAMS "
        $COMMAND &
}


case $JETTY_COMMAND in
        start)
                changeDirToJettyHome
                executeJetty
                changeDirBack
                ;;
        stop)
                changeDirToJettyHome
                JETTY_STOP="--stop"
                executeJetty
                changeDirBack
                ;;
        restart)
                changeDirToJettyHome
                executeJetty
                JETTY_STOP="--stop"
                executeJetty
                changeDirBack
                ;;
        *)
                echo "Usage: $(basename $0) (start | stop | restart)"
                ;;
esac

I'm not a "pro" in scripting so forgive me if you notice something awkward in my script. Here's the other one for the nexus-starter.

#!/bin/sh

JETTY_BASE_DIR=/opt/jetty/default                                               # Jetty Installation folder
JAVA_EXEC=java                                                                  # java executable
JETTY_PORT=18090                                                                # HTTP Port
JETTY_HTTPS_PORT=18091                                                          # HTTPS Port
JETTY_STOP_PORT=18092                                                           # STOP Port
JETTY_STOP_KEY=ilovejetty                                                       # STOP Key
JETTY_SUDOCODE_WEBAPPS=/nexus-apps                                              # Location of WAR under ${jetty.home}
JETTY_START_JAR=start.jar                                                       # Location of start.jar
JETTY_HOST=localhost                                                            # Jetty Host
JETTY_JVM_OPTS="-Xms256m -Xmx384m -XX:MaxPermSize=128m"                         # JVM Options

####################################################################################################################
# Don't touch the rest as much as possible
# This file must reside at ${jetty.home}
# Romeo H. Maranan Jr.
# Sudocode Systems Solutions, Inc.
JAVA_EXEC_PARAMS=""
JETTY_COMMAND=$1
JETTY_STOP=""
EXECUTOR_PWD=$(pwd)

changeDirToJettyHome() {
        cd $JETTY_BASE_DIR
}

changeDirBack() {
        cd $EXECUTOR_PWD
}

executeJetty() {
        JAVA_EXEC_PARAMS=" $JETTY_JVM_OPTS"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -DSTOP.PORT=$JETTY_STOP_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -DSTOP.KEY=$JETTY_STOP_KEY"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS -jar $JETTY_START_JAR"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS --module=http"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.port=$JETTY_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.https.port=$JETTY_HTTPS_PORT"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.sudocode.webapps=$JETTY_SUDOCODE_WEBAPPS"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS jetty.host=$JETTY_HOST"
        JAVA_EXEC_PARAMS="$JAVA_EXEC_PARAMS $JETTY_STOP"
        COMMAND="$JAVA_EXEC $JAVA_EXEC_PARAMS "
        $COMMAND &
}


case $JETTY_COMMAND in
        start)
                changeDirToJettyHome
                executeJetty
                changeDirBack
                ;;
        stop)
                changeDirToJettyHome
                JETTY_STOP="--stop"
                executeJetty
                changeDirBack
                ;;
        restart)
                changeDirToJettyHome
                executeJetty
                JETTY_STOP="--stop"
                executeJetty
                changeDirBack
                ;;
        *)
                echo "Usage: $(basename $0) (start | stop | restart)"
                ;;
esac

You will notice that we set different ports for properties JETTY_PORT, JETTY_HTTPS_PORT, JETTY_STOP_PORT and JETTY_SUDOCODE_WEBAPPS for each start-up script.

The JETTY_PORT will be set to jetty.port or the HTTP Port to be assigned to the Jetty instance. The JETTY_HTTPS_PORT will be set to the property jetty.https.port. The JETTY_STOP_PORT is for the STOP.PORT property which holds the value for the stop port - the port that will listen for stop commands. JETTY_SUDOCODE_WEBAPPS, finally, is for the property jetty.sudocode.webapps. This is a customized property that we set-up for our web directories.

Feel free to read the scripts so you may understand how things worked here. Also feel free to criticize. I'm very open to them since I'm not really a "pro" Linux user. That will be okay.

Now in able for these scripts to be executable, execute the chmod commands.

chmod +x bin/giblit/gitblit-starter
chmod +x bin/nexus/nexus-starter

Create Daemon Services

You could actually run the Jetty instances if you have finished the previous step.

bin/gitblit/gitblit-starter
bin/nexus/nexus-starter

But, if you are installing in an actual Linux server. You might need to create daemon services that will start-up your Jetty instances when the machine is booting up and will stop them when the machine is shutting down.

For this purpose, I created two more scripts. Using nano again:

nano bin/gitblit/gitblit-daemon

The script contains the following:

#!/bin/sh

JETTY_STARTER=/opt/jetty/default/bin/gitblit/gitblit-starter
JETTY_USER=rmaranan
JETTY_STARTER_COMMAND=

executeCommand() {
        start-stop-daemon -S -u $JETTY_USER -c $JETTY_USER -o -x $JETTY_STARTER $JETTY_STARTER_COMMAND
}

startCommand() {
        JETTY_STARTER_COMMAND=start
        executeCommand
}

stopCommand() {
        JETTY_STARTER_COMMAND=stop
        executeCommand
}

case $1 in
        start)
                startCommand
                ;;
        stop)
                stopCommand
                ;;
        restart)
                stopCommand
                startCommand
                ;;
        *)
                echo "Usage: $(basename $0) (start | stop | restart)"
                ;;
esac

Again, forgive my scripting. I hope you can see it here very straight forward.

The JETTY_STARTER parameter should be set to the respective start-up script. For gitblit-daemon, it should be /opt/jetty/default/gitblit/gitblit-starter.

For the nexus-daemon, it should look like the following:

#!/bin/sh

JETTY_STARTER=/opt/jetty/default/bin/nexus/nexus-starter
JETTY_USER=rmaranan
JETTY_STARTER_COMMAND=

executeCommand() {
        start-stop-daemon -S -u $JETTY_USER -c $JETTY_USER -o -x $JETTY_STARTER $JETTY_STARTER_COMMAND
}

startCommand() {
        JETTY_STARTER_COMMAND=start
        executeCommand
}

stopCommand() {
        JETTY_STARTER_COMMAND=stop
        executeCommand
}

case $1 in
        start)
                startCommand
                ;;
        stop)
                stopCommand
                ;;
        restart)
                stopCommand
                startCommand
                ;;
        *)
                echo "Usage: $(basename $0) (start | stop | restart)"
                ;;
esac

This time, the JETTY_STARTER points to /opt/jetty/default/nexus/nexus-starter.

Next step is to copy both daemon files at /etc/init.d.

Note that I'm using Ubuntu when I created the scripts. So start-stop-daemon command should have a counterpart at other Linux Distros. 

Anyway, let's move on. I leave the minor things to your research and development prowess.

We copy the daemon scripts to /etc/init.d

cp bin/gitblit/gitblit-daemon /etc/init.d
cp bin/nexus/nexus-daemon /etc/init.d

Then we execute the following commands:

update-rc.d gitblit-daemon defaults
update-rc.d nexus-daemon defaults

These commands will make our daemon scripts automatically started and stopped on boot-up and shutdown respectively.

Also, you could execute commands like start, stop and restart the following ways:

/etc/init.d/gitblit-daemon start

/etc/init.d/nexus-daemon start

/etc/init.d/gitblit-daemon stop

/etc/init.d/nexus-daemon stop

/etc/init.d/gitblit-daemon restart

/etc/init.d/nexus-daemon restart

That's all, blog readers!

Thank you for spending some time to read this blog. I hope you learned something. Also if you have comments or inquiries, I'll try my best as possible to answer them. I hope I could learn from you too.