From d9c81566f5663c2dcb70cad4b4fc058c4d2e544e Mon Sep 17 00:00:00 2001 From: Charles Phillips Date: Fri, 27 Sep 2013 16:20:11 -0700 Subject: [PATCH] Interative Install Script for GitLab 6.1 on Ubuntu 12.04/12.10 --- install/ubuntu/README.md | 36 +- install/ubuntu/gitlab-mysql.sql | 3 + install/ubuntu/gitlab-postgres.sql | 2 + install/ubuntu/ubuntu_server_1204.sh | 542 ++++++++++++++++++--------- 4 files changed, 398 insertions(+), 185 deletions(-) create mode 100644 install/ubuntu/gitlab-mysql.sql create mode 100644 install/ubuntu/gitlab-postgres.sql mode change 100644 => 100755 install/ubuntu/ubuntu_server_1204.sh diff --git a/install/ubuntu/README.md b/install/ubuntu/README.md index dcd53f2..cab9453 100644 --- a/install/ubuntu/README.md +++ b/install/ubuntu/README.md @@ -1,27 +1,31 @@ -One script installer for clean ubuntu 12.04 x64 -============== +# Interactive Install Script for GitLab 6.1 on Ubuntu 12.04/12.10 -Made for GitLab v4.0 +#### by doublerebel -### ABOUT +https://github.com/doublerebel/gitlab-recipes/blob/master/install/ubuntu/ubuntu_server_1204.sh -This script performs a complete installation of Gitlab for ubuntu server 12.04.1 x64: -* packages update -* redis, git, postfix etc -* ruby setup -* git, gitlab users -* gitolite fork +### Usage (run as root): + # ./ubuntu_server_1204.sh [--url ] [--db ] [--gitlab ] [--shell ] -### Notes +Requires `--url` parameter. Default database is `mysql`. -__!IMPORTANT run as root or sudo without prompting password cause script ignore any input.__ +Script provides information about current progress. If installation fails, script can be re-run safely. +#### Example -### USAGE + $ git clone https://github.com/doublerebel/gitlab-recipes.git + $ cd gitlab-recipes/install/ubuntu + $ sudo ./ubuntu_server_1204.sh --url your.gitlabdomain.com -#### 1. Run script (replace gitlab.example.com with your domain or ip address) +### More info - curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/ubuntu/ubuntu_server_1204.sh | sudo domain_var=gitlab.example.com sh + * Prompts to install Python 2 if not found. -#### 2. Reboot machine + * Prompts to install Ruby 2.0 from [Brightbox PPA](https://launchpad.net/~brightbox/+archive/ruby-ng-experimental) if not found. + + * Prompts for MySQL root password if MySQL is already installed. + + * Prompts to install Nginx and site config. + + * GitLab and dependency versions are factored out for easy update upon release of new versions. diff --git a/install/ubuntu/gitlab-mysql.sql b/install/ubuntu/gitlab-mysql.sql new file mode 100644 index 0000000..22b4660 --- /dev/null +++ b/install/ubuntu/gitlab-mysql.sql @@ -0,0 +1,3 @@ +CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password'; +CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`; +GRANT SELECT, LOCK TABLES, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost'; diff --git a/install/ubuntu/gitlab-postgres.sql b/install/ubuntu/gitlab-postgres.sql new file mode 100644 index 0000000..32eae67 --- /dev/null +++ b/install/ubuntu/gitlab-postgres.sql @@ -0,0 +1,2 @@ +CREATE USER git WITH PASSWORD '$password'; +CREATE DATABASE gitlabhq_production OWNER git; \ No newline at end of file diff --git a/install/ubuntu/ubuntu_server_1204.sh b/install/ubuntu/ubuntu_server_1204.sh old mode 100644 new mode 100755 index 901e92b..2de4469 --- a/install/ubuntu/ubuntu_server_1204.sh +++ b/install/ubuntu/ubuntu_server_1204.sh @@ -1,196 +1,400 @@ -#!/bin/sh - -# GITLAB -# Maintainer: @randx -# App Version: 4.0 - -# ABOUT -# This script performs a complete installation of Gitlab for ubuntu server 12.04.1 x64: -# * packages update -# * redis, git, postfix etc -# * ruby setup -# * git, gitlab users -# * gitolite fork -# Is should be run as root or sudo user w/o password. +#!/bin/bash # -# USAGE -# !IMPORTANT run as root or sudo without prompting password cause script ignore any input. -# curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/v4/ubuntu_server_1204.sh | sudo domain_var=gitlab.example.com sh +# Interactive Install Script for GitLab 6.1 on Ubuntu 12.04/12.10 +# by doublerebel +# https://github.com/doublerebel/gitlab-recipes/blob/master/install/ubuntu/ubuntu_server_1204.sh # - - -#== -#== 0. FQDN -#== - -if [ $domain_var ] ; then - echo "Installing GitLab for domain: $domain_var" -else - echo "Please pass domain_var" - exit +# Usage: $0 [--url ] [--db ] [--gitlab ] [--shell ] +# Requires --url parameter +# Default database is mysql +# +# If installation fails, script can be re-run safely. +# +# +# Distribution : Ubuntu 12.04/12.10 +# GitLab version : 6.1 +# Web Server : nginx (optional) +# Init system : init.d +# Database : MySQL or Postgres +# Contributors : doublerebel +# Additional Notes : the script uses ppa:brightbox/ruby-ng-experimental to install ruby + +# OPTIONS +GITLAB_URL="default.com" +DB_TYPE="mysql" + +# VERSIONS +GITLAB_VERSION="6.1.0" +GITLAB_SHELL_VERSION="1.7.1" +RUBY_PACKAGES="ruby2.0 ruby2.0-dev" +CHARLOCK_HOLMES_VERSION="0.6.9.4" + + +# GITLAB INSTALLATION +SCRIPT_DIR=$PWD + +head() { + echo "" + echo "#####################################" + echo "=== $1 ===" +} +head "Beginning GitLab Installation" + + +# PARSE ANY COMMAND LINE FLAGS +echo "Parsing arguments..." +usage() { + echo "Usage: $0 [--url ] [--db ] [--gitlab ] [--shell ]" 1>&2; + exit 1; +} + +remove_db_user() { + echo "Dropping gitlab@localhost from database..." + echo "DROP USER 'gitlab'@'localhost'" | mysql -u root -p +} + + +if ! ARGS=$(getopt -n "$0" -o hru:d:p:g:s: --long help,remove-db-user,url:,db:,gitlab:,shell: -- "$@"); then + echo "Error parsing command line arguments" 1>&2; + exit 1; +fi +eval set -- "$ARGS" + +while [ $# -gt 0 ]; do + case "$1" in + -h|--help) + usage + ;; + -r|--remove-db-user) + remove_db_user + exit 0; + ;; + -u|--url) + if [[ ! "$2" =~ "-" ]]; then + GITLAB_URL="$2" + fi + shift 2; + ;; + -d|--db) + DB_TYPE="$2" + ((DB_TYPE == "mysql" || DB_TYPE == "postgres")) || usage + shift 2; + ;; + -g|--gitlab) + GITLAB_VERSION="$2" + shift 2; + ;; + -s|--shell) + GITLAB_SHELL_VERSION="$2" + shift 2; + ;; + *) + break + ;; + esac +done + +echo "Arguments parsed." + +if [ -z "${GITLAB_URL}" ] || [ $GITLAB_URL == "default.com" ]; then + echo "Non-default non-empty URL is required" 1>&2; + usage fi -echo "Host localhost - StrictHostKeyChecking no - UserKnownHostsFile=/dev/null" | sudo tee -a /etc/ssh/ssh_config - -echo "Host $domain_var - StrictHostKeyChecking no - UserKnownHostsFile=/dev/null" | sudo tee -a /etc/ssh/ssh_config - - -#== -#== 1. Packages -#== -sudo apt-get update -sudo apt-get install -y wget curl build-essential checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libreadline6-dev libc6-dev libssl-dev zlib1g-dev libicu-dev redis-server openssh-server git-core libyaml-dev - - -# Python - -# Install Python -sudo apt-get install -y python - -# Make sure that Python is 2.x (3.x is not supported at the moment) -python --version - -# If it's Python 3 you might need to install Python 2 separately -sudo apt-get install python2.7 - -# Make sure you can access Python via python2 -python2 --version - -# If you get a "command not found" error create a link to the python binary -sudo ln -s /usr/bin/python /usr/bin/python2 - -# POSTFIX -sudo DEBIAN_FRONTEND='noninteractive' apt-get install -y postfix-policyd-spf-python postfix # Install postfix without prompting. +################ +# PREREQUISITES +head "1. Packages / Dependencies" + +echo "Installing git, ssh, redis, checkinstall, sudo, makepasswd, and charlock_holmes and nokogiri dependencies..." + +CHARLOCK_DEPENDENCIES="libicu-dev" +NOKOGIRI_DEPENDENCIES="libxml2-dev libxslt-dev" +apt-get install -y wget curl git-core openssh-server redis-server checkinstall sudo makepasswd $CHARLOCK_DEPENDENCIES $NOKOGIRI_DEPENDENCIES + +ask_about_python() { + read -p "Install Python 2.7 from Ubuntu repos (yes/no)? " choice + case "$choice" in + y|Y|yes|Yes) + apt-get install -y python2.7 + ;; + n|N|no|No) + echo "Python >2.5 is required. Please restart installation after Python >2.5 is available." 1>&2; + exit 1; + ;; + *) + echo "Error: invalid input $choice" + ask_about_python + ;; + esac +} + +echo "Checking Python version..." +if [[ -z $(which python2) ]]; then + echo "python2 binary not available..." + + if [[ `python --version 2>&1` =~ "Python 2." ]]; then + echo "Python 2.x found at $(which python), linking python to python2..." + ln -s $(which python) /usr/bin/python2 + else + echo "Python 2.x not installed" + ask_about_python + fi +fi -#== -#== 2. RUBY -#== -wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p327.tar.gz -tar xfvz ruby-1.9.3-p327.tar.gz -cd ruby-1.9.3-p327 -./configure -make -sudo make install -sudo gem install bundler -#== -#== 3. Users -#== -sudo adduser \ - --system \ - --shell /bin/sh \ - --gecos 'Git Version Control' \ - --group \ - --disabled-password \ - --home /home/git \ - git - - -sudo adduser --disabled-login --gecos 'GitLab' gitlab +################ +# RUBY +head "2. Ruby" + +install_ruby_from_ppa() { + echo "Adding Brightbox PPA..." + apt-get install -y python-software-properties + add-apt-repository -y ppa:brightbox/ruby-ng-experimental + apt-get update + echo "Installing Ruby..." + apt-get install -y $RUBY_PACKAGES +} + +ask_about_ruby() { + read -p "Install Ruby 2.x from Brightbox PPA (yes/no)? " choice + case "$choice" in + y|Y|yes|Yes) + install_ruby_from_ppa + ;; + n|N|no|No) + echo "Ruby 2.x is required. Please restart installation after Ruby 2.x is available." 1>&2; + exit 1; + ;; + *) + echo "Error: invalid input $choice" + ask_about_ruby + ;; + esac +} + +echo "Checking Ruby version..." +if [[ -z $(which ruby) ]] || [[ ! $(ruby --version) =~ "ruby 2." ]]; then + echo "Ruby 2.x not installed" + ask_about_ruby +fi -# Add it to the git group -sudo usermod -a -G git gitlab +echo "Installing bundler..." +gem install bundler --no-ri --no-rdoc + + +################ +# GIT USER +head "3. System Users" + +run_as_git_user() { + sudo -u git -H "$@" +} + +echo "Adding git user..." +adduser --disabled-login --gecos 'GitLab' git +run_as_git_user git config --global user.name GitLab +run_as_git_user git config --global user.email gitlab@$GITLAB_URL +run_as_git_user git config --global core.autocrlf input + +# DATABASE +echo "Creating secure database password..." +DB_GITLAB_USER_PASSWORD=$(makepasswd --char=10) +echo mysql-server mysql-server/root_password password $DB_GITLAB_USER_PASSWORD | debconf-set-selections +echo mysql-server mysql-server/root_password_again password $DB_GITLAB_USER_PASSWORD | debconf-set-selections + +ask_about_db_user() { + read -p "Drop gitlab@localhost from database (yes/no)? " choice + case "$choice" in + y|Y|yes|Yes) + remove_db_user + echo "Retrying database user initilization..." + cat $SCRIPT_DIR/gitlab-mysql.sql | sed s/\$password/$DB_GITLAB_USER_PASSWORD/ | mysql -u root -p + ;; + n|N|no|No) + echo "Unable to initialize GitLab database user. Installation may not complete correctly." 1>&2; + ;; + *) + echo "Error: invalid input $choice" + ask_about_db_user + ;; + esac +} + +if [ $DB_TYPE = "mysql" ]; then + if [[ -z $(which mysql) ]]; then + echo "MySQL not installed" + echo "Installing MySQL..." + apt-get install -y mysql-server mysql-client + else + echo "MySQL detected as installed" + fi + + echo "Installing mysql-dev for gems..." + apt-get install -y libmysqlclient-dev + + echo "Initializing GitLab database..." + cat $SCRIPT_DIR/gitlab-mysql.sql | sed s/\$password/$DB_GITLAB_USER_PASSWORD/ | mysql -u root + if [[ ! $? -eq 0 ]]; then + echo "MySQL root password exists, retrying..." + cat $SCRIPT_DIR/gitlab-mysql.sql | sed s/\$password/$DB_GITLAB_USER_PASSWORD/ | mysql -u root -p + fi + if [[ ! $? -eq 0 ]]; then + ask_about_db_user + fi + +elif [ $DB_TYPE = "postgres" ]; then + if [[ -z $(which psql) ]]; then + echo "Postgres not installed" + echo "Installing Postgres..." + apt-get install -y postgresql-9.1 + else + echo "Postgres detected as installed" + fi + + echo "Installing libpq-dev for gems..." + apt-get install -y libpq-dev + + echo "Initializing GitLab database..." + cat $SCRIPT_DIR/gitlab-postgres.sql | sed s/\$password/$DB_GITLAB_USER_PASSWORD/ | sudo -u postgres psql -d template1 +fi -# Generate the SSH key -sudo -H -u gitlab ssh-keygen -q -N '' -t rsa -f /home/gitlab/.ssh/id_rsa -#== -#== 4. Gitolite -#== +################ +# GITLAB SOURCE +head "4. GitLab Shell" +echo "Retrieving gitlab-shell source..." cd /home/git -sudo -u git -H git clone -b gl-v304 https://github.com/gitlabhq/gitolite.git /home/git/gitolite -# Add Gitolite scripts to $PATH -sudo -u git -H mkdir /home/git/bin -sudo -u git -H sh -c 'printf "%b\n%b\n" "PATH=\$PATH:/home/git/bin" "export PATH" >> /home/git/.profile' -sudo -u git -H sh -c 'gitolite/install -ln /home/git/bin' - -# Copy the gitlab user's (public) SSH key ... -sudo cp /home/gitlab/.ssh/id_rsa.pub /home/git/gitlab.pub -sudo chmod 0444 /home/git/gitlab.pub - -# ... and use it as the admin key for the Gitolite setup -sudo -u git -H sh -c "PATH=/home/git/bin:$PATH; gitolite setup -pk /home/git/gitlab.pub" - -sudo chmod -R ug+rwXs /home/git/repositories/ -sudo chown -R git:git /home/git/repositories/ - -sudo chmod 750 /home/git/.gitolite/ -sudo chown -R git:git /home/git/.gitolite/ - +run_as_git_user git clone -b v$GITLAB_SHELL_VERSION https://github.com/gitlabhq/gitlab-shell.git +cd gitlab-shell -sudo -u gitlab -H git clone git@localhost:gitolite-admin.git /tmp/gitolite-admin -sudo rm -rf /tmp/gitolite-admin +echo "Setting GitLab Shell URL to $GITLAB_URL" +run_as_git_user cp config.yml.example config.yml +run_as_git_user sed -i.bak s/gitlab_url/$GITLAB_URL/g config.yml +echo "Installing GitLab Shell" +run_as_git_user ./bin/install -#== -#== 5. MySQL -#== -sudo apt-get install -y makepasswd # Needed to create a unique password non-interactively. -userPassword=$(makepasswd --char=10) # Generate a random MySQL password -# Note that the lines below creates a cleartext copy of the random password in /var/cache/debconf/passwords.dat -# This file is normally only readable by root and the password will be deleted by the package management system after install. -echo mysql-server mysql-server/root_password password $userPassword | sudo debconf-set-selections -echo mysql-server mysql-server/root_password_again password $userPassword | sudo debconf-set-selections -sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev -#== -#== 6. GitLab -#== -cd /home/gitlab -sudo -u gitlab -H git clone https://github.com/gitlabhq/gitlabhq.git gitlab -cd /home/gitlab/gitlab -# Checkout v4 -sudo -u gitlab -H git checkout 4-0-stable +head "5. Database" +echo "Delaying Database until GitLab available..." -# Copy the example GitLab config -sudo -u gitlab -H cp config/gitlab.yml.example config/gitlab.yml -sudo -u gitlab -H cp config/database.yml.mysql config/database.yml -sudo sed -i 's/"secure password"/"'$userPassword'"/' /home/gitlab/gitlab/config/database.yml # Insert the mysql root password. -sudo sed -i "s/ host: localhost/ host: $domain_var/" /home/gitlab/gitlab/config/gitlab.yml -sudo sed -i "s/ssh_host: localhost/ssh_host: $domain_var/" /home/gitlab/gitlab/config/gitlab.yml -sudo sed -i "s/notify@localhost/notify@$domain_var/" /home/gitlab/gitlab/config/gitlab.yml -# Copy the example Unicorn config -sudo -u gitlab -H cp config/unicorn.rb.example config/unicorn.rb +head "6. GitLab" -cd /home/gitlab/gitlab - -sudo gem install charlock_holmes --version '0.6.9' -sudo -u gitlab -H bundle install --deployment --without development postgres test - -sudo -u gitlab -H git config --global user.name "GitLab" -sudo -u gitlab -H git config --global user.email "gitlab@localhost" - -sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive -sudo chown git:git /home/git/.gitolite/hooks/common/post-receive - -sudo -u gitlab -H bundle exec rake gitlab:app:setup RAILS_ENV=production - -sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/4-0-stable/init.d/gitlab -P /etc/init.d/ -sudo chmod +x /etc/init.d/gitlab +echo "Retrieving GitLab source..." +cd /home/git +run_as_git_user git clone -b v$GITLAB_VERSION https://github.com/gitlabhq/gitlabhq.git gitlab +cd gitlab -sudo update-rc.d gitlab defaults 21 +echo "Setting GitLab URL to $GITLAB_URL" +run_as_git_user cp config/unicorn.rb.example config/unicorn.rb +run_as_git_user cp config/gitlab.yml.example config/gitlab.yml +run_as_git_user sed -i.bak s/localhost/$GITLAB_URL/g config/gitlab.yml -#== -#== 7. Nginx -#== -sudo apt-get install -y nginx -sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/4-0-stable/nginx/gitlab -P /etc/nginx/sites-available/ -sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab +################ +# DB CONFIGURE +head "5. Database" +echo "Copying database configuration..." +if [ $DB_TYPE = "mysql" ]; then + run_as_git_user cp config/database.yml.mysql config/database.yml +elif [ $DB_TYPE = "postgres" ]; then + run_as_git_user cp config/database.yml.postgresql config/database.yml +fi -sudo sed -i 's/YOUR_SERVER_IP:80/80/' /etc/nginx/sites-available/gitlab # Set Domain -sudo sed -i "s/YOUR_SERVER_FQDN/$domain_var/" /etc/nginx/sites-available/gitlab +echo "Inserting secure database password into configuration..." +run_as_git_user sed -i.bak s/root/gitlab/g config/database.yml +run_as_git_user sed -i.bak s/"secure\spassword"/$DB_GITLAB_USER_PASSWORD/g config/database.yml +run_as_git_user chmod o-rwx config/database.yml -# Start all +echo "Installing charlock_holmes $CHARLOCK_HOLMES_VERSION..." +gem install charlock_holmes --version $CHARLOCK_HOLMES_VERSION -sudo service gitlab start -sudo service nginx start +echo "Installing database bundle..." +if [ $DB_TYPE = "mysql" ]; then + run_as_git_user bundle install --deployment --without development test postgres aws +elif [ $DB_TYPE = "postgres" ]; then + run_as_git_user bundle install --deployment --without development test mysql aws +fi +echo "Setting up database bundle..." +run_as_git_user bundle exec rake gitlab:setup RAILS_ENV=production + + +################ +# GITLAB PERMISSIONS +head "6. GitLab (continued)" + +set_perms() { + chmod u+rwX "$@" +} + +create_and_set_perms() { + run_as_git_user mkdir $@ + set_perms "$@" +} + +echo "Creating GitLab directories and setting permissions..." +chown -R git {log,tmp} +set_perms {log,tmp} + +run_as_git_user mkdir /home/git/gitlab-satellites +create_and_set_perms tmp/{pids,sockets} +create_and_set_perms public/uploads + +# INIT SCRIPT +echo "Installing GitLab init script..." +cp lib/support/init.d/gitlab /etc/init.d/gitlab +chmod +x /etc/init.d/gitlab +update-rc.d gitlab defaults 21 + +# CHECK ENVIRONMENT +echo "Checking GitLab environment..." +run_as_git_user bundle exec rake gitlab:env:info RAILS_ENV=production + + +################ +# NGINX +head "7. Nginx" + +install_nginx() { + echo "Installing Nginx..."; + apt-get install -y nginx + cp lib/support/nginx/gitlab /etc/nginx/sites-available/gitlab + ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab + sed -i.bak s/YOUR_SERVER_FQDN/$GITLAB_URL/g /etc/nginx/sites-available/gitlab + service nginx restart +} + +ask_about_nginx() { + read -p "Install Nginx and site config (yes/no)? " choice + case "$choice" in + y|Y|yes|Yes) + install_nginx + ;; + n|N|no|No) + echo "Not installing Nginx."; + ;; + *) + echo "Error: invalid input $choice" + ask_about_nginx + ;; + esac +} + +# OPEN GITLAB TO THE OUTSIDE WORLD +ask_about_nginx +service gitlab start + +echo "Checking GitLab installation..." +run_as_git_user bundle exec rake gitlab:check RAILS_ENV=production + +echo "GitLab install complete" +echo "" +echo "Visit $GITLAB_URL for your first GitLab login." +echo "The setup has created an admin account for you. You can use it to log in:" +echo "admin@local.host" +echo "5iveL!fe" \ No newline at end of file