pvillega’s posterous

pvillega’s posterous

Pere Villega  //  Born in Barcelona, living in Dublin, and tagged as geek since youth. Developer in the path to becoming a software architect. I swear this is not a proper blog :)

Feb 16 / 7:59am

Redmine on Ubuntu 9.04 with NGinx

Originally I wanted to install Launchpad on my server to manage my projects. As of 17th of August of 2009, Launchpad is not yet ready for production. The only way to install it is using an script, only available for Ubuntu 9.04, which doesn't work too well on a server. I'll keep an eye on it as I like the way Canonical does things (and applications), but in the meantime I decided to use Redmine as I found Trac lacking on some areas.

Redmine

Redmine is an open source, web-based project management and bug-tracking tool, written in Ruby on Rails and heavily influenced by Trac. It improves on several areas, like providing multiple project support, integrating with several source control systems (from popular SVN to less popular Bazaar or Darcs) and allowing extension of its functionalities through plugins. This guide describes how to install Redmine in an Ubuntu 9.04 server using Mongrel as web server, Nginx as proxy and MySQL as database. To achieve this we have to follow 3 steps:

  • install ruby and rails and MySQL
  • install Redmine
  • install Mongrel and Nginx

This guide can be adapted to older versions of Ubuntu and most Linux distributions, just replacing the tools/packages by the specific ones available in that distribution. The guide is a quick overview of the main steps, for  more information on configuration options check the documentation of the corresponding tool.

Install Ruby and Rails and MySQL

To install the components first ensure the system is up to date:

sudo apt-get update
sudo apt-get dist-upgrade

Then run the following command:

sudo apt-get install build-essential ruby ri rdoc mysql-server libmysql-ruby ruby1.8-dev irb1.8 libdbd-mysql-perl libdbi-perl
libmysql-ruby1.8 libmysqlclient15off libnet-daemon-perl libplrpc-perl libreadline-ruby1.8 libruby1.8 rdoc1.8 ri1.8 ruby1.8
irb libopenssl-ruby libopenssl-ruby1.8 libhtml-template-perl mysql-client-5.0 mysql-common mysql-server-5.0 mysql-server-core-5.0

Now that we have Ruby installed, we use Gems to install Rails:

sudo gem update
sudo gem install rails --no-rdoc –no-ri

The flags –no-rdoc and –no-ri are included to reduce the RAM footprint of the component, feel free to remove them if your machine has more than enough RAM. To finish this part, open the MySQL client and create the Redmine database:

create database redmine character set utf8;

Install Redmine

Get the code from the download page. Although the stable release is recommended, if you are going to use Bazaar the svn contains some fixes you want to use, so do an export from the trunk and use that. (Note: if you use the trunk, you'll have to install a newer Rails using Gems due to version requirements). Select a folder in your server (from now on, APP) and copy the downloaded code there. Move to the APP folder and run:

sudo cp config/database.yml.example config/database.yml
sudo cp config/email.yml.example config/email.yml

Edit the new yml files and change the configuration as required (MySQL details, mail server, etc).  Now run these commands to create the database and populate it:

rake db:migrate RAILS_ENV="production"
rake redmine:load_default_data RAILS_ENV="production"

We also need ImageMagick  (although is optional):

sudo apt-get install imagemagick libmagickwand-dev
sudo gem install rmagick

Install Mongrel and Nginx

To run Redmine we will use a standard setup for Rails applications, consistent on Mongrel as web server and Nginx as proxy that interacts with the network. We will run Mongrel as Mongrel Cluster, to improve the performance as Mongrel is single threaded and we will need multiple instances to server multiple clients. First we need to install Mongrel and Mongrel Cluster:

sudo gem install mongrel
sudo gem install mongrel_cluster

Now move to APP folder and run:

mongrel_rails cluster::configure -e production -p 8000 -N 2 -c APP -a 127.0.0.1

The flag -p indicates the initial port to use by Mongrel. Flag -N tells how many instances you want running in the cluster. Flag -a shows the bind address of the cluster. Once created, we need to set it up so it starts automatically with the server:

sudo mkdir /etc/mongrel_cluster
sudo ln -s APP/config/mongrel_cluster.yml /etc/mongrel_cluster/your-app-name.yml
sudo cp /var/lib/gems/1.8/gems/mongrel_cluster-1.0.5/resources/mongrel_cluster /etc/init.d/
sudo chmod +x /etc/init.d/mongrel_cluster
sudo /usr/sbin/update-rc.d mongrel_cluster defaults

Now you can control the cluster with the commands:

mongrel_cluster_ctl start
mongrel_cluster_ctl stop
mongrel_cluster_ctl restart

Now install nginx (if you don't have it):

sudo apt-get install nginx

We need to create a virtual host for Nginx, that will receive the requests and forward them to Redmine. Assuming your public domain will be “domain.com”:

sudo nano /usr/local/nginx/sites-available/domain.com

And copy inside:

upstream domain1 {
 server 127.0.0.1:5000;
server 127.0.0.1:5001;
server 127.0.0.1:5002;
}
server {
 listen   80;
server_name  www.domain.com;
rewrite ^/(.*) http://domain.com/$1 permanent;
}
server {
 listen   80;
server_name domain.com;
 access_log /home/demo/public_html/railsapp/log/access.log;
error_log /home/demo/public_html/railsapp/log/error.log;
 root   /home/demo/public_html/railsapp/public/;

index  index.html;

 location / {
      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;
proxy_redirect false;
      if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
      if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
      if (!-f $request_filename) {
proxy_pass http://domain1;
break;
}
 }

}

Be careful to change the port numbers and domain name to the ones you'll use on your server. Now enable the site:

sudo ln -s /usr/local/nginx/sites-available/domain.com /usr/local/nginx/sites-enabled/domain.com

and once you restart Nginx your Redmine installation is ready to go. Configure Bazaar First we need to edit the file config/environment.rb to add new environment variables related to Python, to avoid problems while accessing Bazaar:

ENV['PYTHONPATH'] = '/usr/lib/python2.6'
ENV['PATH'] = "#{ENV['PATH']}:/usr/bin"

When you create a project you just need to point Redmine to your Bazaar main folder, this will allow you to browse the repository. Be aware it still has some limitations when displaying contents, but it works quite well. To work with Bazaar, let's set up a repository on  our server. This will be a dumb repository, it means is nothing more than a  folder that can be accessed via sftp that stores the data of the repository. First of all, in Ubuntu 9.04 (our server) let's install the needed tools (sftp) and enable them as accepted shell:

$apt-get install ssh openssh-server
$echo '/usr/lib/sftp-server' >> /etc/shells

Then create a user to connect via sftp to the server:

$sudo useradd --create-home --home-dir /home/bzr --shell /usr/lib/sftp-server bzr

And that's it, we have a folder (/home/bzr/) ready to receive our Bazaar projects. Is a good practice to give write rights to that folder to members of group “bzr”, and to add a password to the 'bzr' user. On your client machine, install Bazaar (using apt-get or similar). Then download the Uploader plugin which eases the task to commit changes to “dumb servers”:

$ mkdir /home/pvillega/.bazaar/plugins
$ bzr co lp:bzr-upload ~/.bazaar/plugins/upload

or if you use Ubuntu/Debian with:

$sudo apt-get install bzr-upload

Then create the base repository. There are two ways of doing this, you can create a shared repository which stores every child branch revision, or you can create standalone repositories, which are good if you don’t want to share revision information with other branches. Here we create a shared repository:

bzr init-repository some_directory
bzr init some_directory/trunk
bzr init some_directory/branches

Now, to interact with the server we created before, first run:

bzr push --create-prefix sftp://bzr@server:port/~/test

This pushes the project to the server and creates the folder 'test' if needed. After that, all the interaction with the server can be (usually) reduced to:

 bzr pull sftp://bzr@server:port/~/test   #update changes from the server to our client
bzr co sftp://bzr@server:port/~/test      #checkout the project
bzr push sftp://bzr@server:port/~/test  #push changes to the server

Ok, is not the nicest way to do that, but remember this is a distributed repository, you won't update or push changes too often, usually only when you are done with a piece of work.  There's an alternative method, using what is called a “smart server”, which is faster than the previous way (but not always possible to use for several reasons). In this case we will use an ssh connection to communicate with the repository, but this requires that our user belongs to the group “bzr” to be able to write in that folder. The command for the first commit is:

bzr push --create-prefix bzr+ssh://server:port/home/bzr/test #requires full path, from root

In a similar way we interact with the server using:

 bzr pull bzr+ssh://bzr@server:port/~/test   #update changes from the server to our client
bzr co bzr+ssh://bzr@server:port/~/test      #checkout the project
bzr push bzr+ssh://bzr@server:port/~/test  #push changes to the server

Install Redmine Themes

You can install some new themes for Redmine, available at here. Although is mainly a cosmetic change, some themes provide enhancements like colouring tickets according to priority and they are really easy to manage. For example, to install the Basecamp theme:

  1. Download application.css
  2. Create required directories: mkdir -p redmine/public/themes/basecamp/stylesheets
  3. Copy downloaded file:  cp application.css redmine/public/themes/basecamp/stylesheets

That's it .. now restart your instance running Redmine and select the new basecamp theme from /settings

Install Redmine Plugins

Redmine provides several plugins that enhance the capabilities of the tool. Amongst them you can find some nice ones like:

  • Bots Filter: avoids bots from accessing certain areas of the application
  • Charts: adds some project based charts
  • Exception Handler: notifies admins when an exception occurs
  • Hudson: integrates Redmine and Hudson, allowing you to see Hudson reports
  • Status updates: allows users to say what are they doing, kind of Twitter per project.
  • Vote: allows users to vote on issues so you see which ones are important to them

You can find these and many more in this page . To install a plugin, follow the instructions on the “Installation” section of its page. Then restart Redmine and you are good to go.

Connect Mylyn to Redmine

If you use Mylyn (and you should!) use these instructions to connect it to your Redmine repository.

Loading mentions Retweet

Filed under // nginx redmine ubuntu

Comments (1)

Feb 16 / 7:56am

Ubuntu server maintenance

This guide will show some basic stuff you might need to maintain an Ubuntu server. You might not need all of them, but thy are handy enough and I've had to use them at least once.

Secure a fresh Ubuntu installation (via Mensk)

When you install your fresh server, you have a completely unsafe Ubuntu installation. To make it a bit safer, follow these steps (change names and ports accordingly): Login as root (via ssh or using the console, it depends on your physical access to the machine) and change root password:

passwd

Add new username - yourself:

adduser jsmith
visudo

Append this line to end of file (to navigate within 'vi' editor to create next line - use these: L, $, a, <ENTER>):

jsmith ALL=(ALL) ALL

To save and exit do: <ESC>, :wq, <ENTER>. Now let's set up SSH configuration:

nano /etc/ssh/sshd_config

Find Port 22 and change number to something different (12345) to make hacking more difficult.Then change the following settings:

PermitRootLogin no
X11Forwarding no
UsePAM no

Append these lines to the very end:

UseDNS no
AllowUsers jsmith

After this, we must secure the server with iptables

iptables-save > /etc/iptables.up.rules
nano /etc/iptables.test.rules

Copy contents of this file (content below) and paste it into 'iptables.test.rules'

*filter


# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -i ! lo -d 127.0.0.0/8 -j REJECT


# Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


# Allows all outbound traffic
# You can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT


# Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

# Allows SSH connections
#
# THE -dport NUMBER IS THE SAME ONE YOU SET UP IN THE SSHD_CONFIG FILE
#
-A INPUT -p tcp -m state --state NEW --dport 30000 -j ACCEPT

# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT


# log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT
-A FORWARD -j REJECT

COMMIT

Change port number to your SSH port number on this line:

-A INPUT -p tcp -m state --state NEW --dport 30000 -j ACCEPT

Save and exit (Ctrl+O, Ctrl+X). To apply new iptables rules:

iptables-restore < /etc/iptables.test.rules

Then save iptables rules permanently:

iptables-save > /etc/iptables.up.rules

Make sure iptables rules will apply when server is rebooted as well:

nano /etc/network/interfaces

Add new line after these 2:

auto lo
iface lo inet loopbackpre-up iptables-restore < /etc/iptables.up.rules

Save and exit. Reload SSH to use new ports and configurations:

 /etc/init.d/ssh reload

Keep 'root' session running and open second session. SSH login to your slice to new port, with your new username and password:

ssh -p 12345 jsmith@123.45.6.78

If you logged on successfully via your new username: 'jsmith' - you may close 'root' session now. If not - you still have 'root' session opened to fix problems. As your user, edit .bashrc file to make terminal window a bit more helpful:

nano ~/.bashrc

Append these lines to the end of it:

export PS1="\[\e[32;1m\]\u\[\e[0m\]\[\e[32m\]@\h\[\e[36m\]\w \[\e[33m\]\$ \[\e[0m\]"
alias ll="ls -la"
alias a2r="sudo /etc/init.d/apache2 stop && sleep 2 && sudo /etc/init.d/apache2 start"
alias n2r="sudo /etc/init.d/nginx stop && sleep 2 && sudo /etc/init.d/nginx start"
alias ver="cat /etc/lsb-release"

Save and exit. Reload .bashrc to make changes active:

source ~/.bashrc

Update sources:

sudo aptitude update

Set system locale:

sudo locale-gen en_US.UTF-8
sudo /usr/sbin/update-locale LANG=en_US.UTF-8

Upgrade system now:

sudo aptitude -y safe-upgrade
sudo aptitude -y full-upgrade

Clean the server (via UbuntuGeek)

I have a special fixation on cleaning my servers. I don't want any extra file (package, log, whatever) to be there if it is not needed. That's why when I discovered UbuntuCleaner I got quite happy. This tools does this for you:

  • Cleans apt cache
  • Removes config files left from uninstalled .deb packages(it happens if you don’t use the --purge switch with apt-get)
  • Removes every kernel except the one you are using
  • Empties the trashes of every user(including root)

It uses apt and the kernel removing thing searches for ubuntu-only packages, so it can’t work on non-debian system and the result is undetermined for other debian-based system, but you can still use the other features of the script(you’ll just have to comment the parts you don’t want).

The script assumes that you are using the text-based Aptitude application, rather than apt-get and dpkg. If you are not using Aptitude, you should also replace the reference to aptitude clean with apt-get clean and the reference to aptitude purge to dpkg –purge.This can be done done by editing the following script. First you need to download the script from here or using the following command

wget http://www.opendesktop.org/CONTENT/content-files/71529-ubucleaner.sh

Now you should have 71529-ubucleaner.sh file you need to give execute permissions using the following command

sudo chmod +x 71529-ubucleaner.sh

Run the script using the following command

./71529-ubucleaner.sh

Upgrading to a new release (via HowToForge)

For an Ubuntu server, the main advice is to stick to LTS releases, due to their stability. That said, sometimes you might need to upgrade to a non-LTS release, as it happened to me when Launchpad was released and I wanted to install it (it required 9.04). So here I will describe the steps needed to update your distribution. It assumes you are running a server (no X11 installed) and this is your first upgrade:

First become root:

sudo su

Then run

apt-get update

and install the package update-manager-core:

apt-get install update-manager-core

If you are running a LTS release, open the file /etc/update-manager/release-upgrades

vi /etc/update-manager/release-upgrades

and change Prompt=lts to Prompt=normal. Then run

do-release-upgrade

to start the distribution upgrade.

Enabling PHP-FastCGI (via HowToForge)

If you need to run fastcgi scripts on your Ubuntu 9.04 machine, you are lucky as this version provides a FastCGI-enabled PHP5 package. To activate it: Install PHP5 on Ubuntu:

aptitude install php5-cgi php5-mysql php5-curl
php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt
php5-memcache php5-mhash php5-ming php5-pspell php5-recode php5-snmp
php5-sqlite php5-tidy php5-xmlrpc php5-xsl

Then open /etc/php5/cgi/php.ini and add the line

 cgi.fix_pathinfo = 1

right at the end of the file. This enables the FastCGI package. But there's no standalone FastCGI daemon package for Ubuntu 9.04, therefore we use the spawn-fcgi program from lighttpd. We install lighttpd as follows:

aptitude install lighttpd
update-rc.d -f lighttpd remove

so that lighttpd will not start at boot time, as we've installed lighttpd because we need just one program that comes with the package, /usr/bin/spawn-fcgi, which we can use to start FastCGI processes. Of course, you don't want to type in that command manually whenever you boot the system, so to have the system execute the command automatically at boot time, open /etc/rc.local

vi /etc/rc.local

and add the command at the end of the file (before the exit line):

/usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u www-data -g www-data -f /usr/bin/php5-cgi -P /var/run/fastcgi-php.pid
Loading mentions Retweet

Comments (0)