Code Jamming Everyday IT problems, solutions and discussions

TeamCity 8 on CentOS 6.4 from scratch

In this post I’ll describe whole TeamCity installation process on a fresh CentOS (on the moment I’m writing it’s 6.4) for your private project or startup.

First, proceed to the CentOS downloads page and download CentOS distro through .iso, .torrent or whatever-you-like and start the installation process. If you’re familiar with any  linux distro installation, it won’t take you much time to complete the installation. I’m using the minimal configuration without any Desktop Environment and with minimum core- and other system utils. Nonetheless, consider installing iptables, elinks and java (openjdk).

After the installation is over, login, add a user for yourself with adduser and let’s start with TeamCity (maybe you’ll also consider adding yourself to the sudoers file).

First, create /opt/jetbrains/ directory and download latest TeamCity using wget.

mkdir /opt/jetbrains
cd /opt/jetbrains
wget http://download.jetbrains.com/teamcity/TeamCity-8.0.5.tar.gz
tar -xpzf TeamCity-8.0.5.tar.gz

Now lets create a system user (e.g. no home directory) for TeamCity to resolve security issues correctly:

adduser -r teamcity
passwd teamcity
chown -R teamcity:teamcity TeamCity

We’ll use PostgreSQL for the internal database for TeamCity. So let’s install postgresql packages (8.4 for CentOS 6.4). For details of the PostgreSQL installation please refer to official webpage.

yum install postgresql
service postgresql initdb
chkconfig postgresql on

Also edit the /var/lib/pgsql/data/pg_hba.conf file to allow authorization from localhost. Go to the end and replace ident to trust for localhost in the configuration for hosts. Now lets create another user for the future TeamCity database and create a database for that user.

sudo -u postgres psql postgres
password postgres
sudo -u postgres createuser -D -A -P teamcity_user
sudo -u postgres createdb -O teamcity_user teamcity_db

(D = Cannot create databases, A = Cannot add users, P = Force password prompt)

To start TeamCity as a service in CentOS, you’ll have to register it with chkconfig and to do so, let’s create startup script in the /etc/init.d/ directory and save it with any name (e.g. teamcity-script):

#!/bin/bash
#
# chkconfig: 235 10 90
# description: TeamCity startup script
#

TEAMCITY_USER=teamcity
TEAMCITY_DIR=/opt/jetbrains/TeamCity/
TEAMCITY_SERVER=bin/teamcity-server.sh

TEAMCITY_DATADIR="/opt/jetbrains/TeamCity/.BuildServer"

. /etc/rc.d/init.d/functions

case "$1" in
start)
    sudo -u $TEAMCITY_USER -s -- sh -c "cd $TEAMCITY_DIR; <strong>TEAMCITY_DATA_PATH</strong>=$TEAMCITY_DATADIR $TEAMCITY_SERVER start"
    ;;
stop)
    sudo -u $TEAMCITY_USER -s -- sh -c "cd $TEAMCITY_DIR; TEAMCITY_DATA_PATH=$TEAMCITY_DATADIR $TEAMCITY_SERVER stop"
    ;;
*)
    echo "Usage: $0 {start|stop}"
    exit 1
    ;;
esac

exit 0

Note the TEAMCITY_DATA_PATH system variable which is used to overwrite default ~/.BuildServer path for the teamcity data. First commented lines exist for chkconfig compatability. Now you’re able to register it:

chkconfig --add teamcity-script
chkconfig teamcity-script on

Now our script would autostart on system startup in 2, 3 and 5 runlevels.

But what does actually teamcity-server.sh script do? It’s located in the bin/ directory of the TeamCity installation directory and it launches Tomcat server with initial config (conf/server.xml file). This config can be useful for us, so let’s modify it slightly:

Another important thing is iptables. This is a server, right? So let’s configure a firewall properly. You can paste below config as a working one for a server in the /etc/sysconfig/iptables file:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p ah -j ACCEPT
-A INPUT -p esp -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 53 -j ACCEPT
<strong>-A INPUT -m state --state NEW -m tcp -p tcp --dport 8111 -j ACCEPT</strong>
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

The most valuable line for us is highlighted and allows packets on 8111 port (the one Tomcat is listening to). You can easily configure Tomcat to listen to another port in the conf/server.xml file on your TeamCity installation. You can also find lots of articles on the web about making a proxy with apache or lighttpd for Tomcat just in order to enter urls like http://my-server/teamcity instead of http://my-server:8111/teamcity/. Believe me, java and tomcat are not worth normal url in your browser! Besides, you’ll have to spend your time to deal with several issues:

So, I assume, you have enough reasons to leave the 8111 port as the default one. Let’s ensure that iptables function properly:

# service iptables restart
# chkconfig iptables on
# service teamcity-script start

Now you can launch a browser and navigate to http://my_server.my_domain:8111 (TeamCity data is stored in webapps/ROOT directory and you’re able to move it to some other like webapps/teamcity but in this case your address would be http://my_server.my_domain:8111/teamcity) and see TeamCity page with a correct DATA_PATH (check if it’s same like the one you specified in the /etc/init.d/teamcity-script). Check if user teamcity is able to create a directory DATA_PATH.  If everything is correct, proceed, agree to the license terms and wait while TeamCity will finish with basic installation. Please, note, that for now TeamCity is using internal DB which is not for the production purposes! Let’s fix this using the official how-to by downloading proper postgresql jdbc driver (for postgresql version on current CentOS) and configuring PostgreSQL authentication:

service teamcity-script stop
cd YOUR_DATA_PATH
cd lib/jdbc
su - teamcity
wget jdbc.postgresql.org/download/postgresql-8.4-703.jdbc4.jar
cd ../../config/
cp database.postgresql.properties.dist database.properties

Now edit database.properties with you favorite editor (say, vi) and replace placeholder credentials with those you’ve specified in the PostgreSQL post-installation configuration.

connectionUrl=jdbc:postgresql://<host>/<database name>
connectionProperties.user=<user>
connectionProperties.password=<password>

After you’re done, relaunch TeamCity:

service teamcity-script start

Open your browser, go to the teamcity page and you should see TeamCity complaining about missing database. You’ll have only one-button choice, so proceed. Now teamcity will try to create another database (many thanks to this tutorial) but it will require an authorization key, which can be found at the end of logs/teamcity-server.log file in your TeamCity main directory. Copy it and paste in the browser textbox, press Next and now TeamCity should launch correctly with PostgreSQL in the backend.

A plenty of useful links:

Buy me a coffeeBuy me a coffee
comments powered by Disqus