Skip to content

Instantly share code, notes, and snippets.

@jennings
Last active March 28, 2024 21:13
Show Gist options
  • Save jennings/2866413 to your computer and use it in GitHub Desktop.
Save jennings/2866413 to your computer and use it in GitHub Desktop.
Step-by-step instructions for installing RhodeCode 1.3.6 on Ubuntu Server 12.04 with Nginx 1.2.1 as the reverse proxy. This was written when these were the latest versions; add a comment if the scripts need to change to accommodate changes in newer versions.The script assumes you want to use a SQLite database. Sorry, you'll need to find another …

Setting up RhodeCode on Ubuntu Server 12.04

Goal

  • Everything running on a single Ubuntu Server
  • RhodeCode running in a virtualenv
  • Use SQLite as the database
  • Use Nginx as the HTTPS proxy

Preparation

  1. Install Ubuntu Server.

  2. Update Ubuntu with the commands:

    sudo apt-get update
    sudo apt-get upgrade
    
  3. Install pip and virtualenv with the commands:

    sudo apt-get install python-pip
    sudo pip install virtualenv
    

Installing RabbitMQ

  1. Install RabbitMQ:

    sudo apt-get install rabbitmq-server
    
  2. Create RabbitMQ user:

    sudo rabbitmqctl add_user rhodeuser rhodepass
    sudo rabbitmqctl add_vhost rhodevhost
    sudo rabbitmqctl set_permissions -p rhodevhost rhodeuser ".*" ".*" ".*"
    

Installing RhodeCode

  1. Install Python sources:

    sudo apt-get install python-dev
    
  2. Create the base directory and temporarily give yourself ownership:

    sudo mkdir /rhode
    sudo chown myusername /rhode
    
  3. Create the data directory, virtual environment, and install RhodeCode:

    virtualenv --no-site-packages /rhode/venv
    source /rhode/venv/bin/activate
    (venv) pip install pastescript
    (venv) pip install rhodecode
    
  4. Create directories and the production configuraton:

    mkdir /rhode/repos
    mkdir /rhode/data
    cd /rhode/data
    (venv) paster make-config RhodeCode production.ini
    
  5. Edit at least the following settings in production.ini:

    [server:main]
    host = 0.0.0.0
    
    [app:main]
    use_celery = true
    broker.vhost = rhodevhost
    broker.user = rhodeuser
    broker.password = rhodepass
    
  6. Generate the RhodeCode database and create the initial admin account:

    (venv) paster setup-rhodecode production.ini
    
  7. Test the system by starting Celery and RhodeCode (access the server via http://127.0.0.1:5000):

    (venv) paster celeryd production.ini &
    (venv) paster serve production.ini
    

Enabling full-text search

  1. Create a crontab file for the rhodecode user with sudo crontab -e -u rhodecode. Add this line to the crontab file:

    @hourly /rhode/venv/bin/paster make-index /rhode/data/production.ini

Starting RhodeCode on boot

  1. Create the user to run the RhodeCode daemons and set ownership on the RhodeCode directory:

    sudo adduser --no-create-home \
                 --disabled-login \
                 --disabled-password \
                 --system --group rhodecode
    sudo chown -R rhodecode:rhodecode /rhode
    
  2. Download the init.d script and modify USER, VENV_DIR, and DATA_DIR as necessary:

    wget http://raw.github.com/gist/2866413/rhodecode-init.d.sh
    vim ./rhodecode-init.d.sh
    
  3. Test the script:

    chmod +x ./rhodecode-init.d.sh
    sudo ./rhodecode-init.d.sh start
    
    ## access RhodeCode via web browser
    
    sudo ./rhodecode-init.d.sh stop
    
    ## verify that the Python processes have stopped
    
  4. Install the script:

    sudo cp ./rhodecode-init.d.sh /etc/init.d/rhodecode
    cd /etc/init.d
    sudo update-rc.d rhodecode defaults
    
  5. Test the script once more:

    sudo service rhodecode start
    sudo service rhodecode stop
    

Adding Active Directory support

  1. Install python-ldap:

    sudo apt-get install libldap2-dev libsasl2-dev
    (venv) pip install python-ldap
    
  2. Log in to RhodeCode as an administrator and open Settings --> LDAP. Add the following settings:

    Enable LDAP

    Checked

    Host

    dc.mydomain.local

    Port

    389

    Account

    <username>

    Password

    <password>

    Connection Security

    None

    Certificate Checks

    DEMAND

    Base DN

    CN=People,DC=mydomain,DC=local

    LDAP Filter

    <blank>

    LDAP Search Scope

    SUBTREE

    Login Attribute

    sAMAccountName

    First Name Attribute

    givenName

    Last Name Attribute

    sn

    E-mail Attribute

    mail

Adding Nginx as a front-end for SSL

  1. Install the PCRE headers and essential build tools:

    sudo apt-get install libpcre3-dev build-essential
    
  2. Create the user for nginx:

    sudo adduser --no-create-home \
                 --disabled-login \
                 --disabled-password \
                 --system --group nginx
    
  3. Download and extract Nginx:

    wget http://nginx.org/download/nginx-1.2.1.tar.gz
    tar -zxcf nginx-1.2.1.tar.gz
    cd nginx-1.2.1
    ./configure --prefix=/opt/nginx --with-http_ssl_module
    make
    sudo make install
    
  4. Create SSL keys:

    cd /opt/nginx/conf
    
    sudo openssl genrsa -des3 -out server.key 1024
    sudo openssl req -new -key server.key -out server.csr
    sudo cp server.key server.key.orig
    sudo openssl rsa -in server.key.orig -out server.key
    sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
    sudo rm server.csr
    sudo chmod 600 server.crt server.key
    
  5. Replace /opt/nginx/conf/nginx.conf with nginx.conf from this repository.

  6. Place rhodecode.conf from this repository into /opt/nginx/conf/rhodecode.conf.

  7. Start and stop Nginx with the commands:

    /opt/nginx/sbin/nginx
    /opt/nginx/sbin/nginx -s stop
    
  8. Download the init.d script and modify PREFIX:

    wget http://raw.github.com/gist/2866413/nginx-init.d.sh
    vim ./nginx-init.d.sh
    
  9. Test the script:

    chmod +x ./nginx-init.d.sh
    sudo ./nginx-init.d.sh start
    
    ## access Nginx via web browser
    
    sudo ./nginx-init.d.sh stop
    
    ## verify that the Nginx processes have stopped
    
  10. Install the script:

    sudo cp ./nginx-init.d.sh /etc/init.d/nginx
    cd /etc/init.d
    sudo update-rc.d nginx defaults
    
  11. Test the script once more:

    sudo service nginx start
    sudo service nginx stop
    
#!/bin/sh
### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts Nginx
### END INIT INFO
PREFIX=/opt/nginx
PID_FILE=$PREFIX/logs/nginx.pid
start() {
/sbin/start-stop-daemon \
--start \
--pidfile $PID_FILE \
--exec $PREFIX/sbin/nginx
}
stop() {
/sbin/start-stop-daemon \
--stop \
--pidfile $PID_FILE \
--exec $PREFIX/sbin/nginx -- -s stop
}
case "$1" in
start)
echo "Starting Nginx"
start
;;
stop)
echo "Stopping Nginx"
stop
;;
restart)
echo "Stopping Nginx"
stop
echo "Starting Nginx"
start
;;
*)
echo "Usage: ./nginx {start|stop|restart}"
exit 2
;;
esac
exit 0
user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream rhodecode {
server 127.0.0.1:5000;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate server.crt;
ssl_certificate_key server.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
include rhodecode.conf;
location / {
try_files $uri @rhodecode;
}
location @rhodecode {
proxy_pass http://rhodecode;
}
}
}
#!/bin/sh
### BEGIN INIT INFO
# Provides: rhodecode
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts RhodeCode
### END INIT INFO
USER=rhodecode
VENV_DIR=/rhode/venv
DATA_DIR=/rhode/data
CELERY_ARGS="$VENV_DIR/bin/paster celeryd $DATA_DIR/production.ini"
RHODECODE_ARGS="$VENV_DIR/bin/paster serve $DATA_DIR/production.ini"
CELERY_PID_FILE=/var/run/celeryd.pid
RHODECODE_PID_FILE=/var/run/rhodecode.pid
start_celery() {
/sbin/start-stop-daemon \
--start \
--background \
--chuid $USER \
--pidfile $CELERY_PID_FILE \
--make-pidfile \
--exec $VENV_DIR/bin/python -- $CELERY_ARGS
}
start_rhodecode() {
/sbin/start-stop-daemon \
--start \
--background \
--chuid $USER \
--pidfile $RHODECODE_PID_FILE \
--make-pidfile \
--exec $VENV_DIR/bin/python -- $RHODECODE_ARGS
}
stop_rhodecode() {
/sbin/start-stop-daemon \
--stop \
--user $USER \
--pidfile $RHODECODE_PID_FILE
}
stop_celery() {
/sbin/start-stop-daemon \
--stop \
--user $USER \
--pidfile $CELERY_PID_FILE
}
case "$1" in
start)
echo "Starting Celery"
start_celery
echo "Starting RhodeCode"
start_rhodecode
;;
start_celery)
echo "Starting Celery"
start_celery
;;
start_rhodecode)
echo "Starting RhodeCode"
start_rhodecode
;;
stop)
echo "Stopping RhodeCode"
stop_rhodecode
echo "Stopping Celery"
stop_celery
;;
stop_rhodecode)
echo "Stopping RhodeCode"
stop_rhodecode
;;
stop_celery)
echo "Stopping Celery"
stop_celery
;;
restart)
echo "Stopping RhodeCode and Celery"
stop
echo "Starting Celery"
start_celery
echo "Starting RhodeCode"
start_rhodecode
;;
*)
echo "Usage: ./rhodecode {start|stop|restart|start_celery|stop_celery|start_rhodecode|stop_rhodecode}"
exit 2
;;
esac
exit 0
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Url-Scheme $scheme;
proxy_set_header X-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy-host $proxy_host;
client_max_body_size 400m;
client_body_buffer_size 128k;
proxy_buffering off;
proxy_connect_timeout 7200;
proxy_send_timeout 7200;
proxy_read_timeout 7200;
proxy_buffers 8 32k;
@ftonello
Copy link

ftonello commented Jan 5, 2013

Awesome, thank you!

@jmalm
Copy link

jmalm commented May 3, 2013

Excellent rundown! (I used apache for proxying, though...)

@peterdemin
Copy link

Please fix:
/opt/nbinx/sbin/nginx -s stop
with:
/opt/nginx/sbin/nginx -s stop

@CodeAndWeb
Copy link

Great!

Small flaw:
"Enabling full-text search" can only be done after the user is created in the next step.

@valentijnscholten
Copy link

To make the nginx work correctly behind another (nginx or other) proxy:

Replace

proxy_set_header X-Real-IP $remote_addr;

with

proxy_set_header X-Real-IP $proxy_add_x_forwarded_for;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment