Making the leap from SVN to Git

In SVN, many repositories are setup like this:

- trunk  : The place where all of the main development occurs
- tag    : Storing versions of major releases or important milestones
- branch : Where smaller "branch" development occurs as to not conflict with the main development occurring in the trunk, then is later merged into the trunk

Git does not force you to use a specific structure for your project. All information which is important for git itself will be stored in the hidden .git directory

    SVN trunk --- Git master (refs/heads/master)
    SVN branches/* --- Git branches (refs/heads/*)
    SVN tags/* --- Git tags (refs/tags/*)

The “master” branch in Git is not a special branch. It is exactly like any other branch. The only reason nearly every repository has one is that the git init command creates it by default and most people don’t bother to change it.

Free git book: http://git-scm.com/book/en/v2

Edit 2015-12-10, Some good readings about git:

http://blog.anvard.org/conversational-git/

http://lucamezzalira.com/2014/03/10/git-flow-vs-github-flow/

https://coding.abel.nu/2015/10/become-a-git-wizard-with-7-simple-tricks/

http://danielkummer.github.io/git-flow-cheatsheet/

 

And the best graphical git-client in my opinion is SmartGit:

http://www.syntevo.com/smartgit/

Howto set up Git over Https with Apache on Ubuntu Server 14.04

Welcome,

In this post we will look at setting up Git over https (git-http-backend) with Apache on a Ubuntu Server 14.04 LTS. We will require users to be authenticated with basic auth before accessing the central git-repositories, both when reading from and writing to any repository.

Let’s start by installing git on our Ubuntu system:

root@ubuntu01:~# apt-get upgrade
root@ubuntu01:~# apt-get install git
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  git-man liberror-perl
Suggested packages:
  git-daemon-run git-daemon-sysvinit git-doc git-el git-email git-gui gitk
  gitweb git-arch git-bzr git-cvs git-mediawiki git-svn
The following NEW packages will be installed:
  git git-man liberror-perl
0 upgraded, 3 newly installed, 0 to remove and 3 not upgraded.
Need to get 3,346 kB of archives.
After this operation, 21.6 MB of additional disk space will be used.

Setting up Git over Https with Apache is basically just enabling a CGI-script that is provided with Git called git-http-backend on the server.

We can find out the location of git-http-backend on our system by searching for it:

root@ubuntu01:/etc/apache2/mods-enabled# find / -name git-http-backend
/usr/lib/git-core/git-http-backend

Now, in order for the git-http-backend to work properly with Apache we need to enable these modules: mod_cgi, mod_alias, and mod_env. On my system I already have mod_alias and mod_env up and running so I only need to enable mod_cgi:

root@ubuntu01:/etc/apache2# a2enmod cgi
Enabling module cgi.

For security purposes, it is generally a good practice to execute CGI-scripts as a different user than the web server user, hence we create the unprivileged user and group called git, we will also install and make use of the apache2 suexec packages:

First, you create a git group:

root@ubuntu01:/opt# groupadd git

You can easily restrict the git user to only doing Git activities with a limited shell tool called git-shell that comes with Git. If you set this as your git user’s login shell, then the git user can’t have normal shell access to your server. To use this, specify git-shell instead of bash or csh for your user’s login shell. To do so, you must first add git-shell to /etc/shells if it’s not already there:

root@ubuntu01:/opt# more /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/usr/bin/tmux
/usr/bin/screen

So git-shell is not enabled, let’s enable it, first we need to find out the path:

root@ubuntu01:/opt# find / -name git-shell
/usr/bin/git-shell
/usr/lib/git-core/git-shell

Okay, so let’s add the /usr/bin/git-shell to /etc/shells

root@ubuntu01:/opt# vi /etc/shells

root@ubuntu01:/opt# more /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/usr/bin/tmux
/usr/bin/screen
/usr/bin/git-shell

Now create a home directory for the git user at /opt/git

root@ubuntu01:/opt# mkdir git

Now create a git user. We’ll make this user a member of the git group, with a home directory of /opt/git, and with a shell of /usr/bin/git-shell

root@ubuntu01:/opt# useradd -s /usr/bin/git-shell -g git -d /opt/git git

Make the git user and group the owner of the /opt/git folder:

root@ubuntu01:/opt# chown git:git git/

Now, I’ve decided to use a subdomain called git with my domain so that the url will look similar to this: https://git.example.com  For this to work I need to add a subdomain record to my DNS-configuration. I will use a CNAME-record for this.

add_subdomain_git

With the host-command I can now verify that the new record does resolve in dns:

root@ubuntu01:/opt/git# host -t CNAME git.creang.com
git.creang.com is an alias for creang.com.

Now, let’s set up a VirtualHost in Apache for this subdomain:

root@ubuntu01:/opt/git# vi /etc/apache2/sites-enabled/vhosts-default.conf
        <VirtualHost *:443>
                ServerName git.creang.com
                DocumentRoot /opt/git
                ErrorLog ${APACHE_LOG_DIR}/error.log
                CustomLog ${APACHE_LOG_DIR}/access.log combined
                <Directory /opt/git>
                        Options ExecCGI Indexes FollowSymLinks
                        AllowOverride All
                        Require all granted
                </Directory>
                SSLEngine on
                SSLCertificateFile /etc/apache2/ssl-stuff/myCert.crt
                SSLCertificateKeyFile /etc/apache2/ssl-stuff/myKey.key
                SSLCertificateChainFile /etc/apache2/ssl-stuff/myCA.crt
                <Location />
                        AuthType Basic
                        AuthName "Private Git Access"
                        AuthUserFile /opt/git/.htpasswd
                        Require valid-user
                </Location>
                SuexecUserGroup git git
                ScriptAlias /git /var/www/sbin/git-http-backend-wrapper
        </VirtualHost>

Now install apache2-suexec:

root@ubuntu01:/etc/apache2# apt-get install apache2-suexec
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  apache2-suexec-pristine
The following NEW packages will be installed:
  apache2-suexec apache2-suexec-pristine

Enable suEXEC Support so that the git user and group can be used when running the CGI-Script:

root@ubuntu01:/etc/apache2# a2enmod suexec
Enabling module suexec.

To work with the SuExec security model a wrapper script needs to be create that configures the environment when SuExec executes the script. The script simply sets the correct environment variable and calls git-http-backend.

root@ubuntu01:/var/www# mkdir sbin
root@ubuntu01:/var/www# vi ./sbin/git-http-backend-wrapper

#!/bin/bash
PATH_INFO=$SCRIPT_URL
GIT_PROJECT_ROOT=/opt/git
REMOTE_USER=$REDIRECT_REMOTE_USER
export GIT_HTTP_EXPORT_ALL=true
/usr/lib/git-core/git-http-backend

Change owner to git user and group on this folder and script and make it executable:

root@ubuntu01:/var/www# chown -R git:git sbin/

root@ubuntu01:/var/www# chmod 755 ./sbin/git-http-backend-wrapper

Now create the htpasswd-file. This will require the apache-utils package, install if not installed already:

root@ubuntu01:/etc/apache2# apt-get install apache2-utils

Create the file, replace with your user:

root@ubuntu01:/etc/apache2# htpasswd -c /opt/git/.htpasswd jbilander
New password:
Re-type new password:
Adding password for user jbilander

Make the git user and group owner of this file:

root@ubuntu01:/etc/apache2# chown git:git /opt/git/.htpasswd

Restart Apache:

root@ubuntu01:/etc/apache2# service apache2 restart

Now create a repository in /opt/git

root@ubuntu01:/opt/git# git init --bare --shared=group projectA.git
Initialized empty shared Git repository in /opt/git/projectA.git/

Set the git user and group as the owner, recursively, of this repo:

root@ubuntu01:/opt/git# chown -R git.git projectA.git/

Set the repo to http.receivepack true:

root@ubuntu01:/opt/git# cd projectA.git/

root@ubuntu01:/opt/git/projectA.git# git config --file config http.receivepack true

The config file will now look like this:

root@ubuntu01:/opt/git/projectA.git# more config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = true
        sharedrepository = 1
[receive]
        denyNonFastforwards = true
[http]
        receivepack = true

Now lets access and clone this repo from a client over https. I will do this from the command line just to show how, you may prefer to use a gui client here like SmartGit:

C:\Projects>git.exe clone https://git.creang.com/git/projectA.git myProjectA.git
Cloning into 'myProjectA.git'...
Username for 'https://git.creang.com': jbilander
Password for 'https://jbilander@git.creang.com':
warning: You appear to have cloned an empty repository.
Checking connectivity... done.

I used another name here for the repository folder just for instructional purposes. You can leave that out if you want the same name on the client side as on the server side. Please note, if you are using a self-signed-certificate you can ignore any warning with this configuration on the client side:

git config --global http.sslVerify false

Maybe even better you can add your certificate to your trust store. I will not  show how to do that here though.

Let’s try to add a new file and commit and push to the server repo:

Create a new file:

C:\Projects\myProjectA.git>notepad test.txt
C:\Projects\myProjectA.git>git.exe add test.txt
C:\Projects\myProjectA.git>git.exe commit -m "a first commit"

[master (root-commit) da37104] a first commit
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt

Push to the remote repository on the server:

C:\Projects\myProjectA.git>git.exe push origin master

Username for 'https://git.creang.com': jbilander
Password for 'https://jbilander@git.creang.com':
Counting objects: 3, done.
Writing objects: 100% (3/3), 217 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://git.creang.com/git/projectA.git
 * [new branch]      master -> master

All done! and it works :) Now time to grab some coffee…

Howto protect your wordpress blog from comment and trackback spam with Akismet

Welcome,

We will here learn to activate and protect our wordpress blog from comment and trackback spam. We will use the popular Akismet plugin.

akismet

After installing wordpress you automatically get a notice about the available Akismet-plugin under the Plugins-menu and the possibility to upgrade to the latest version of Akismet. Let’s do that.

You can update Akismet-plugin either by clicking the “update now” or do it manually, we will do the latter.

akismet_update_info

“Update now” will open this dialog:

update_now_dialog

However, I will not do the update this way but rather prefer to do it manually…

Manually updating the akismet-plugin:

root@ubuntu01:/usr/src/download# wget https://downloads.wordpress.org/plugin/akismet.3.1.2.zip

install unzip if you don’t have it installed already.

root@ubuntu01:/usr/src/download# apt-get install unzip

Unpack

root@ubuntu01:/usr/src/download# unzip akismet.3.1.2.zip

Set the same owner and group that you have for the wordpress folder.

root@ubuntu01:/usr/src/download# chown -R nobody:www-data ./akismet

move the old akismet plugin away or delete it. I’m moving it to the download folder here and call it akismet_old

root@ubuntu01:/usr/src/download# mv /var/www/creang/wp-content/plugins/akismet/ ./akismet_old

Move the new updated folder in place

root@ubuntu01:/usr/src/download# mv akismet /var/www/creang/wp-content/plugins/

Now when the plugin is in place, Activate the plugin by clicking “Activate”

akismet_activate1

Follow the instructions:

akismet_activate2

Get your API key…

akismet_activate3

Signing up for Akismet with wordpress.com…

akismet_activate4

akismet_activate5

Choose your plan, I chose the basic plan here…

akismet_activate6

Choose wether you want to donate an annual amount or not…

akismet_activate7

Pulling the slider to $0 makes the payment info disappear…

akismet_activate8

After clicking the continue button…

akismet_activate10

click to automatically save your api key…

akismet_activate11

akismet_activate12

All done!

Now, let’s see what happens when a comment is made:

akismet_update5

“Your comment is awaiting moderation”

This comment can be taken care of by the admin/moderator under the comments section…

akismet_update6

Setting up SNI with Apache 2.4

Welcome,

In this tutorial we will look at setting up SNI with Apache 2.4. With SNI you can use multiple SSL certificates in Apache with one IP-address.

Since Apache v2.2.12 and OpenSSL v0.9.8j and later you can use a transport layer security (TLS) called SNI. SNI can secure multiple Apache sites using a single SSL Certificate and use multiple SSL Certificates to secure various websites on a single domain (e.g. www.yourdomain.com, site2.yourdomain.com) or across multiple domains (www.domain1.com, www.domain2.com)—all from a single IP address. The benefits of using SNI are obvious: you can secure more websites without purchasing more IP addresses or additional hardware.

SNI is supported by many common browsers:

Desktop Browsers
Internet Explorer 7 and later
Firefox 2 and later
Opera 8 with TLS 1.1 enabled
Google Chrome:
Supported on Windows XP on Chrome 6 and later
Supported on Vista and later by default
OS X 10.5.7 in Chrome Version 5.0.342.0 and later
Safari 2.1 and later (requires OS X 10.5.6 and later or Windows Vista and later).

Note: No versions of Internet Explorer on Windows XP support SNI

Mobile Browsers
Mobile Safari for iOS 4.0 and later
Android 3.0 (Honeycomb) and later
Windows Phone 7 and later

Now, looking at our Apache installation at location /etc/apache2/mods-available we can see that the ssl-module is in there ready to be enabled:

root@ubuntu01:/etc/apache2/mods-available# ls -al
...
-rw-r--r-- 1 root root  3404 Jan  7  2014 ssl.conf
-rw-r--r-- 1 root root    97 Jan  3  2014 ssl.load

Determining if the ssl-module is already enabled can be done with the following command…

root@ubuntu01:/etc/apache2/mods-available# apachectl -M

…or by listing the /etc/apache2/mods-enabled folder

root@ubuntu01:/etc/apache2/mods-enabled# ls -al

We can see that it’s not enabled already so let’s enable it:

root@ubuntu01:/etc/apache2/mods-enabled# a2enmod ssl

Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
  service apache2 restart

To verify that the symlinks now have been created we can list the content of mods-enabled folder:

root@ubuntu01:/etc/apache2/mods-enabled# ls -al
...
lrwxrwxrwx 1 root root   26 Jul  6 11:53 ssl.conf -> ../mods-available/ssl.conf
lrwxrwxrwx 1 root root   26 Jul  6 11:53 ssl.load -> ../mods-available/ssl.load

Now create a folder where we will put the certificates and keys. I chose to call it ssl-stuff:

root@ubuntu01:/etc/apache2# mkdir ssl-stuff

Copy your certificate www_example_com.crt, your unencrypted key www_example_com.key and your Authority’s certificate file ca.crt

Please note:

  • If the contained private key is encrypted, the pass phrase dialog is forced at startup time.
  • SSLCertificateChainFile became obsolete with Apache version 2.4.8, when SSLCertificateFile was extended to also load intermediate CA certificates from the server certificate file.

Since we are using Apache 2.4.7 the obsolete SSLCertificateChainFile  directive is not concerning us.

Set the permissions so that only the owner can read/write the decrypted key in ssl-stuff

root@ubuntu01:/etc/apache2/ssl-stuff# chmod 600 www_example_com.key

Now edit your vhosts file:

<IfModule mod_ssl.c>
  <VirtualHost *:443>
    ServerName www.example.com
    DocumentRoot /var/www/example
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    <Directory /var/www/example>
      Options Indexes FollowSymLinks
      AllowOverride None
      Require all granted
    </Directory>
    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl-stuff/www_example_com.crt
    SSLCertificateKeyFile /etc/apache2/ssl-stuff/www_example_com.key
    SSLCertificateChainFile /etc/apache2/ssl-stuff/ca.crt
    JkMount /manager/* ajp13_worker
    JkMount /manager ajp13_worker
    JkMount /examples/* ajp13_worker
    JkMount /examples ajp13_worker
 </VirtualHost>
</IfModule>

Now restart Apache and access the https site from a browser that supports SNI. If you set it up correctly, you will access the site without any warnings or problems. You can add as many websites or SSL Certificates as you need adding more VirtualHost-configurations similar to above.

root@ubuntu01:/etc/apache2/sites-available# service apache2 restart

Howto set up Tomcat 8 with Apache 2.4 and mod_jk on Ubuntu

Welcome,

In this walkthrough we will look at installing the binary distribution of Tomcat 8 on Ubuntu Server 14.04 LTS. Please note that we will not use Tomcat-native package here. Apache 2.4 will be used as a front optionally handling static content and ssl-termination while dynamic content will be served by the Tomcat-server through the Apache JServ Protocol (AJP 1.3) with apache module mod_jk.

apache_tomcat_setup

First we need to install a Java Runtime that the Tomcat-server will run in. I chose the server-jre8-version for obvious reason. The Server JRE is a runtime environment specifically targeted for deploying Java in server environments and it is available for 64-bit Linux, Solaris and Windows platforms. The Server JRE includes tools for JVM monitoring and tools commonly required for server applications, but does not include browser integration (the Java plug-in).

The Server JRE can be downloaded from this location: http://www.oracle.com/technetwork/java/javase/downloads/server-jre8-downloads-2133154.html

At the time of my download, this was the latest version available:

 server-jre-8u45-linux-x64.tar.gz

Download it to /usr/src/download or any other location you prefer and unpack.

root@ubuntu01:/usr/src/download# tar xvzf server-jre-8u45-linux-x64.tar.gz

That will create the folder /usr/src/download/jdk1.8.0_45

Change the owner recursively on that folder, I’m using root as user and group here.

root@ubuntu01:/usr/src/download# chown -R root:root jdk1.8.0_45/

Move the folder to your desired location, I chose /opt here since that folder is typically for third-party add-on software.

root@ubuntu01:/usr/src/download# mv jdk1.8.0_45/ /opt

To make it obvious that this is the Server JRE I created a symlink pointing to that folder.

root@ubuntu01:/opt# ln -s jdk1.8.0_45/ server_jre

root@ubuntu01:/opt# ls -al
drwxr-xr-x  8 root   root     4096 Apr 10 19:22 jdk1.8.0_45
lrwxrwxrwx  1 root   root       12 Jul  1 11:18 server_jre -> jdk1.8.0_45/

Just to verify this is the correct java version

root@ubuntu01:/opt/server_jre/bin# ./java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

That’s all for the Java installation, now let’s download and install Tomcat.

Tomcat installation:

Download Tomcat binary distribution:

root@ubuntu01:/usr/src/download# wget http://apache.mirrors.spacedump.net/tomcat/tomcat-8/v8.0.23/bin/apache-tomcat-8.0.23.tar.gz

Unpack

root@ubuntu01:/usr/src/download# tar xvzf apache-tomcat-8.0.23.tar.gz

Move to /opt

root@ubuntu01:/usr/src/download# mv apache-tomcat-8.0.23 /opt/

create symlink in /opt folder

root@ubuntu01:/usr/src/download# cd /opt/
root@ubuntu01:/opt# ln -s apache-tomcat-8.0.23/ tomcat

For security purposes, Tomcat should be run as an unprivileged user. We will create a new user (tomcat) and group (tomcat) that will run the Tomcat-service.

root@ubuntu01:/opt# groupadd tomcat

Then create a new tomcat user. We’ll make this user a member of the tomcat group, with a home directory of /opt/tomcat, and with a shell of /bin/false

root@ubuntu01:/opt# useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat

Change to the new user and group recursively on the tomcat folder structure

root@ubuntu01:/opt# chown -R tomcat:tomcat apache-tomcat-8.0.23

Now it should look like this when listing the /opt folder:

root@ubuntu01:/opt# ls -al
drwxr-xr-x  9 tomcat tomcat  apache-tomcat-8.0.23
drwxr-xr-x  8 root   root    jdk1.8.0_45
lrwxrwxrwx  1 root   root    server_jre -> jdk1.8.0_45/
lrwxrwxrwx  1 root   root    tomcat -> apache-tomcat-8.0.23/

Now, comment out the port 8080 connector in server.xml…(we will only enable AJP on port 8009)

root@ubuntu01:/opt# cd tomcat/conf/
root@ubuntu01:/opt/tomcat/conf# vi server.xml
<!-- <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> -->

Make sure the ajp-connector is not disabled…

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

Configure Tomcat Web Management Interface. Put this in your tomcat-users.xml in between the <tomcat-users> tags, choose your username and password.

root@ubuntu01:/opt/tomcat/conf# vi tomcat-users.xml
  <role rolename="manager-gui"/>
  <user username="admin" password="password" roles="manager-gui"/>

Because we want to be able to run Tomcat as a service, we will set up an Upstart script. Create and install a Tomcat Upstart script:

root@ubuntu01:/opt/tomcat/conf# vi /etc/init/tomcat.conf

Put this content in the new file:

description "Tomcat Server"

start on runlevel [2345]
stop on runlevel [!2345]
respawn
respawn limit 10 5

setuid tomcat
setgid tomcat

env JAVA_HOME=/opt/server_jre
env CATALINA_HOME=/opt/tomcat

# Modify these options as needed
env JAVA_OPTS="-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom"
env CATALINA_OPTS="-Xms512M -Xmx1024M -server -XX:+UseParallelGC"

exec $CATALINA_HOME/bin/catalina.sh run

# cleanup temp directory after stop
post-stop script
  rm -rf $CATALINA_HOME/temp/*
end script

Tomcat can now be started/stopped by the service command. It will also startup automatically on boot.

root@ubuntu01:/opt/tomcat/conf# service tomcat start
tomcat start/running, process 5666

The log file is located at /var/log/upstart/tomcat.log

root@ubuntu01:/var/log/upstart# tail tomcat.log

Looking at the log file after startup…

tomcat_upstart_log

…we can see the following message in the log output:

org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib

Ignore this message. The library referred to is bundled into an OS specific libtcnative.so (or dll for windows) loaded via JNI. It allows Tomcat to use OS functionalities not provided in the Java Runtime (such as sendfile, epoll, OpenSSL, OS level functionality (random number generation, system status, etc), and native process handling (shared memory, NT pipes and Unix sockets). Tomcat will run just fine without it, these features allows making Tomcat a general purpose webserver. We will however only use Tomcat as a backend-server working together with the Apache-webserver, hence we ignore this message.

Installing and configuring mod_jk

root@ubuntu01:/var/log/upstart# apt-get install libapache2-mod-jk

Preparing to unpack .../libapache2-mod-jk_1%3a1.2.37-3_amd64.deb ...
Unpacking libapache2-mod-jk (1:1.2.37-3) ...
Setting up libapache2-mod-jk (1:1.2.37-3) ...
apache2_invoke: Enable module jk
 * Restarting web server apache2

Now with the following command we can see that the module jk_module has indeed been loaded.

root@ubuntu01:/var/log/upstart# apache2ctl -M

Loaded Modules:
 core_module (static)
 so_module (static)
 watchdog_module (static)
 http_module (static)
 log_config_module (static)
 logio_module (static)
 version_module (static)
 unixd_module (static)
 access_compat_module (shared)
 alias_module (shared)
 auth_basic_module (shared)
 authn_core_module (shared)
 authn_file_module (shared)
 authz_core_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 deflate_module (shared)
 dir_module (shared)
 env_module (shared)
 filter_module (shared)
 jk_module (shared)
 mime_module (shared)
 mpm_prefork_module (shared)
 negotiation_module (shared)
 php5_module (shared)
 rewrite_module (shared)
 setenvif_module (shared)
 status_module (shared)

In the jk.conf file we can see where the workers.properties file is located:

root@ubuntu01:/var/log/upstart# cd /etc/apache2/mods-available/
root@ubuntu01:/etc/apache2/mods-available# more jk.conf

# Configuration Example for mod_jk
# used in combination with Apache 2.2.x

<IfModule jk_module>

    # We need a workers file exactly once
    # and in the global server
    JkWorkersFile /etc/libapache2-mod-jk/workers.properties

    # Our JK error log
    # You can (and should) use rotatelogs here
    JkLogFile /var/log/apache2/mod_jk.log

    # Our JK log level (trace,debug,info,warn,error)
    JkLogLevel info

    # Our JK shared memory file
    JkShmFile /var/log/apache2/jk-runtime-status

…we can see that the workers.properties is located under /etc/libapache2-mod-jk

Edit the workers.properties file, put in your path to your tomcat_home and java_home:

#
# workers.tomcat_home should point to the location where you
# installed tomcat. This is where you have your conf, webapps and lib
# directories.
#
workers.tomcat_home=/opt/tomcat

#
# workers.java_home should point to your Java installation. Normally
# you should have a bin and lib directories beneath it.
#
workers.java_home=/opt/server_jre

Make sure the other settings are correctly put in here, should look similar to this:

worker.list=ajp13_worker
worker.ajp13_worker.port=8009
worker.ajp13_worker.host=localhost
worker.ajp13_worker.type=ajp13
worker.ajp13_worker.lbfactor=1
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=ajp13_worker

Finally to configure the URLs that Apache should pass through the Tomcat, edit your VirtualHost directive:

root@ubuntu01:/etc/libapache2-mod-jk# cd /etc/apache2/sites-available/
root@ubuntu01:/etc/apache2/sites-available# vi vhosts-default.conf
<VirtualHost *:80>
        ServerName www.example.com
        DocumentRoot /var/www/example
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        <Directory /var/www/example>
                Options Indexes FollowSymLinks
                AllowOverride None
                Require all granted
        </Directory>
        JkMount /manager/* ajp13_worker
        JkMount /manager ajp13_worker
        JkMount /examples/* ajp13_worker
        JkMount /examples ajp13_worker
</VirtualHost>

As you can see we are using the www.example.com domain here just for instructional purpose. Since I’m not the owner of that domain and cannot make any DNS-configuration, such as adding an A-record, for that domain I will put in an entry into my client computer host file just to get this example working. The document root I set to /var/www/example so let’s create that folder first. That location is where any static content optionally will be placed if any, it depends on how you do your jkmount-mappings above. As we can see anything with /manager or /examples will be mapped to Tomcat and the rest will be searched for, by Apache, in the /var/www/example folder.

root@ubuntu01:/var/www# mkdir example

In the client machine I now temporarily set a record to map the url www.example.com to my servers ip-address. I’m using a windows client machine here and editing the hosts-file in notepad as Administrator (right-click-> Run as Administrator). Windows will first look in the host-file and then resolve names with DNS which is exactly the order of precedence we want here in order for this example to work.

C:\Windows\System32\drivers\etc\hosts
85.225.140.7  www.example.com

After a reload of Apache…

root@ubuntu01:/etc/apache2/sites-available# service apache2 reload

We can now point the browser on the windows client machine to try out if everything works:

tomcat_examples

The Tomcat examples webapp is indeed working. Now trying /manager…

tomcat_manager_auth_required

After login with your admin/password this is what welcomes you…

tomcat_manager

That is all for now. Everything works as expected. Please consider if you really want the /manager mappings to be enabled all of the time. For security reasons I prefer to enable that mapping only when I have to do some deployment. Keep in mind that any password sent over http is sent “in the clear” for any eavesdropper to pick up, you better use https in that case. I will later blog about setting up SSL using SNI with Apache. Edit! Now available here: http://www.creang.com/howtoforge/setting_up_sni_with_apache_2_4/