Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Install Openproject 5.0 on Uberspace
#!/usr/bin/env bash
#===============================================================================
# AUTHOR: Manoel Brunnen, manoel.brunnen@gmail.com
# CREATED: 22.07.2016
# LICENSE: MIT
# FILE: openproject-5.0.sh
# USAGE: ./openproject-5.0.sh
#
# DESCRIPTION: Installing openproject 5 on uberspace
#
# No warranty! For nothing. Use it at your own risk.
#===============================================================================
#### Based on: ####
################################################################################
################################################################################
# Author: Frank Zisko, 2015
# Version: 3.2.0.5
# Licence: MIT
# Website: https://frank.zisko.io/leitstelle/2015-03-25-openproject-uberspace/
#
# No warranty! For nothing. Use it at your own risk.
#
# See also: https://www.openproject.org/open-source/manual-installation/manual-installation-guide/
################################################################################
################################################################################
set -e
set -o nounset # Treat unset variables as an error
### Logging ### ################################################################
LOG_PATH=$(cd `dirname "${BASH_SOURCE[0]}"` && pwd)/`basename "${BASH_SOURCE[0]}"`
# Backup stdout and stderr at fd 3 and fd 4
exec 3>&1 4>&2
# Restore stdout and stderr
trap 'exec 2>&4 1>&3' 0 1 2 3
# Use tee to redirect fd 1 to logfile.out and to stdout
exec 1> >(tee ${LOG_PATH}.out.log >&3)
# Use tee to redirect fd 2 to logfile.err and to stderr
exec 2> >(tee ${LOG_PATH}.err.log >&4)
### Log ### ####################################################################
JOB_NAME="Install OpenProject"
echo " "
echo "### Start Job: ${JOB_NAME} at $(date "+%Y-%m-%dT%H:%M:%S"). ###"
echo " " 1>&2
echo "### Start Job: ${JOB_NAME} at $(date "+%Y-%m-%dT%H:%M:%S"). ###" 1>&2
time_begin=$(date +"%s")
################################################################################
### Variables ### ##############################################################
################################################################################
# You just have to adjust these three variables:
# Subdomain for this service.
SUBDOMAIN=openproject
# Domain.
# An Uberspace domain (<projectname>.<uberuser>.<uberserver>.uberspace.de) will be automatically added.
DOMAINNAME="${SUBDOMAIN}.example.com"
# Free usable port. Will be tested before the installation.
PORT=65432
# UTF encoding.
LANG=en_US.UTF-8
# Project name. Used for installation and "virtual" home dir.
PROJECTNAME=openproject
# Place where all (other) projects are installed.
WORKSPACE=${HOME}/workspace
# The real home dir.
REALHOME=${HOME}
# Virtual home dir. It'll be usen for a clean installation and uninstallation.
VIRTHOME=${WORKSPACE}/${PROJECTNAME}-home
# This home dir.
HOME=${VIRTHOME}
# Versions.
OPENPROJECT_V="5"
RUBY_V="2.3.0" # 2.0.0, 2.1.2, 2.2.2
RUBYVERSION="2.3.0" # 2.0, 2.1, 2.2
RUBYGEM_V="2.3.0" # 2.0.0, 2.1.0, 2.2.0
NODE_V="0.12.7"
# Paths:
# Home bin.
PATH=${HOME}/bin:${HOME}/.local/bin:${PATH}
# Ruby.
PATH=/package/host/localhost/ruby-${RUBY_V}/bin:${PATH}
PATH=${HOME}/.gem/ruby/${RUBYGEM_V}/bin:${PATH}
# Node.js.c
PATH=/package/host/localhost/nodejs-${NODE_V}/bin:${PATH}
################################################################################
### Uninstall ### ##############################################################
################################################################################
if [[ ("${1}" == "uninstall") || ("${1}" == "uninstallall") ]]; then
echo "Uninstallation ..."
HOME=${REALHOME}
#### Services ####
echo " services ..."
# OpenProject Web.
SVC="${PROJECTNAME}-web"
if [ -d "${HOME}/service/${SVC}" ]; then
cd ${HOME}/service/${SVC}
svc -dx . log
rm ${HOME}/service/${SVC}
fi
if [ -d "${HOME}/etc/run-${SVC}" ]; then
rm -rf ${HOME}/etc/run-${SVC}
fi
if [ -f "${HOME}/service/${SVC}" ]; then
rm ${HOME}/service/${SVC}
fi
# OpenProject Worker.
SVC="${PROJECTNAME}-worker"
if [ -d "${HOME}/service/${SVC}" ]; then
cd ${HOME}/service/${SVC}
svc -dx . log
rm ${HOME}/service/${SVC}
fi
if [ -d "${HOME}/etc/run-${SVC}" ]; then
rm -rf ${HOME}/etc/run-${SVC}
fi
if [ -f "${HOME}/service/${SVC}" ]; then
rm ${HOME}/service/${SVC}
fi
#### HTML links ####
echo " html links ..."
if [ -n "${SUBDOMAIN}" ]; then
cd /var/www/virtual/${USER}/
rm -rf ${SUBDOMAIN}.${USER}.$(hostname -a).uberspace.de
fi
# Prevent deleting ${USER}s www directory, if ${DOMAINNAME} is empty.
if [ -n "${DOMAINNAME}" ]; then
cd /var/www/virtual/${USER}/
rm -rf ${DOMAINNAME}
fi
#### Installation folder and all its content ####
echo " project dir and virtual home dir ..."
# Virtual home directory.
if [ -d "${WORKSPACE}/${PROJECTNAME}-home" ]; then
rm -rf ${WORKSPACE}/${PROJECTNAME}-home
fi
# Project directory.
if [ -d "${WORKSPACE}/${PROJECTNAME}" ]; then
rm -rf ${WORKSPACE}/${PROJECTNAME}
fi
# Git directory.
if [ "${1}" == "uninstallall" ]; then
if [ -d "${WORKSPACE}/${PROJECTNAME}-git" ]; then
rm -rf ${WORKSPACE}/${PROJECTNAME}-git
fi
fi
#### Databases ####
if [[ ("${1}" == "uninstallall") || ("${1}" == "uninstalldb") ]]; then
echo " database ..."
# Drop existing databases.
# Check if database is existing.
# Connect to database and instantly exiting database returns nothing.
# No exisitng database returns an error.
if [ -z "$(mysql --user="${USER}" --password=`my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'` --database="${USER}_${PROJECTNAME}" --execute=exit)" ]; then
echo " Drop existing database ${USER}_${PROJECTNAME}."
mysql -e "DROP DATABASE ${USER}_${PROJECTNAME};"
fi
if [ -z "$(mysql --user="${USER}" --password=`my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'` --database="${USER}_${PROJECTNAME}_dev" --execute=exit)" ]; then
echo " Drop existing database ${USER}_${PROJECTNAME}_dev."
mysql -e "DROP DATABASE ${USER}_${PROJECTNAME}_dev;"
fi
if [ -z "$(mysql --user="${USER}" --password=`my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'` --database="${USER}_${PROJECTNAME}_test" --execute=exit)" ]; then
echo " Drop existing database ${USER}_${PROJECTNAME}_test."
mysql -e "DROP DATABASE ${USER}_${PROJECTNAME}_test;"
fi
fi
#### End uninstallation ####
echo "Uninstallation finished."
exit 0
fi
################################################################################
### Check ### ##################################################################
################################################################################
echo "Checking existing installation ..."
#### Exist ####
# Check existing installation of openproject-web.
if [ -f ${HOME}/bin/${PROJECTNAME}-web ]; then
echo "~/bin/${PROJECTNAME}-web exists."
IS_INSTALLED=true
fi
# Check existing installation of openproject-worker.
if [ -f ${HOME}/bin/${PROJECTNAME}-worker ]; then
echo "~/bin/${PROJECTNAME}-worker exists."
IS_INSTALLED=true
fi
# Check termination condition.
if [ -n "${IS_INSTALLED}" ]; then
echo "OpenProject files found. Maybe it is already installed. Aborting."
exit 1
fi
echo "Checking server port, ruby and node ..."
#### Port ####
# Check if port is (already) unused.
if [ -z "$(netstat -tulpen | grep ${PORT})" ]; then
echo " Your choosen port (${PORT}) is available."
else
echo " Your choosen port (${PORT}) is not available. Choose another."
echo " Aborting the script."
exit 2
fi
#### Ruby ####
# Check if ruby is available.
if [ -z "$(command -v ruby)" ]; then
echo " 'ruby' command not found."
RUBY_FOUND=false
else
echo " 'ruby' command found."
RUBY_FOUND=true
fi
# Check if gem is available.
if [ -z "$(command -v gem)" ]; then
echo " 'gem' command not found."
GEM_FOUND=false
else
echo " 'gem' command found."
GEM_FOUND=true
fi
# Check termination condition.
if [[ ! ( (${RUBY_FOUND} == true) && (${GEM_FOUND} == true) ) ]]; then
echo " Ruby is not complete. Aborting."
exit 3
fi
#### Node ####
# Check if node is available.
if [ -z "$(command -v node)" ]; then
echo " 'node' command not found."
echo " You may add 'export PATH=/package/host/localhost/nodejs-${NODE_V}/bin:\$PATH' into your ~/.bashrc file."
NODE_FOUND=false
else
echo " 'node' command found."
NODE_FOUND=true
fi
# Check if npm is available.
if [ -z "$(command -v npm)" ]; then
echo " 'npm' command not found."
echo " You may add 'export PATH=/package/host/localhost/nodejs-${NODE_V}/bin:\$PATH' into your ~/.bashrc file."
NPM_FOUND=false
else
echo " 'npm' command found."
NPM_FOUND=true
fi
# Check termination condition.
if [[ ! ( (${NODE_FOUND} == true) && (${NPM_FOUND} == true) ) ]]; then
echo " Node is not complete. Aborting."
exit 4
fi
################################################################################
### Setup environment ### ######################################################
################################################################################
echo "Setup build environment ..."
mkdir -p ${WORKSPACE}
mkdir -p ${WORKSPACE}/${PROJECTNAME}-home
# When you load this from your shell, you're in the installing environment.
cat > ${HOME}/.bashrc <<__EOF__
LANG=en_US.UTF-8
SUBDOMAIN=${SUBDOMAIN}
DOMAINNAME=${DOMAINNAME}
PORT=${PORT}
PROJECTNAME=${PROJECTNAME}
WORKSPACE=${WORKSPACE}
# The real home dir.
REALHOME=${REALHOME}
# Virtual home dir.
VIRTHOME=${VIRTHOME}
# This home dir.
HOME=${HOME}
alias getmyhomeback='HOME=${REALHOME}'
PATH=\${HOME}/bin:\${HOME}/.local/bin:\${PATH}
PATH=/package/host/localhost/ruby-${RUBY_V}/bin:\${PATH}
PATH=\${HOME}/.gem/ruby/${RUBYGEM_V}/bin:\${PATH}
PATH=/package/host/localhost/nodejs-${NODE_V}/bin:\${PATH}
__EOF__
################################################################################
### Download ### ###############################################################
################################################################################
echo "Cloneing OpenProject directory from repo ..."
if [ -d ${WORKSPACE}/${PROJECTNAME}-git ]; then
cd ${WORKSPACE}/${PROJECTNAME}-git
git checkout stable/${OPENPROJECT_V}
git pull --depth 1
else
git clone https://github.com/opf/openproject.git --branch stable/${OPENPROJECT_V} --depth 1 ${WORKSPACE}/${PROJECTNAME}-git
fi
if [ -d ${WORKSPACE}/${PROJECTNAME} ]; then
rm -rf ${WORKSPACE}/${PROJECTNAME}
cp -r ${WORKSPACE}/${PROJECTNAME}-git ${WORKSPACE}/${PROJECTNAME}
rm -rf ${WORKSPACE}/${PROJECTNAME}/.git
else
cp -r ${WORKSPACE}/${PROJECTNAME}-git ${WORKSPACE}/${PROJECTNAME}
rm -rf ${WORKSPACE}/${PROJECTNAME}/.git
fi
################################################################################
### Configure ### ##############################################################
################################################################################
echo "Configure OpenProject, its database and its gems ..."
#### configuration.yml ####
cat > ${WORKSPACE}/${PROJECTNAME}/config/configuration.yml <<__EOF__
production:
email_delivery:
delivery_method: :sendmail
sendmail_settings:
location: /usr/sbin/sendmail
arguments: -i
rails_cache_store: :memcache
__EOF__
#### database.yml ####
cat > ${WORKSPACE}/${PROJECTNAME}/config/database.yml <<__EOF__
production:
adapter: mysql2
database: ${USER}_${PROJECTNAME}
host: localhost
username: ${USER}
password: `my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'`
encoding: utf8
development:
adapter: mysql2
database: ${USER}_${PROJECTNAME}_dev
host: localhost
username: ${USER}
password: `my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'`
encoding: utf8
__EOF__
#### Gemfile ####
cat > ${WORKSPACE}/${PROJECTNAME}/Gemfile.local <<__EOF__
gem 'rails_12factor'
__EOF__
################################################################################
### Gems ### ###################################################################
################################################################################
mkdir -p ${HOME}/etc
echo "RUBYVERSION=${RUBYVERSION}" > ${HOME}/etc/rubyversion
echo "gem: --user-install --no-rdoc --no-ri" > ${HOME}/.gemrc
cd ${WORKSPACE}/${PROJECTNAME}
echo "Installing bundler via gem ..."
gem install --user bundler
echo "Installing ruby dependencies (gems) via bundler ..."
bundle install --path $HOME/.gem --without postgres:sqlite:development:test:therubyracer:docker
# bundle install --without postgres:sqlite:development:test:therubyracer:docker
################################################################################
### Databases ### ##############################################################
################################################################################
echo "Set up the database ..."
cd ${WORKSPACE}/${PROJECTNAME}
if [ "${1}" == "installclean" ]; then
echo " delete old ones ..."
# Drop existing databases.
# Check if database is existing.
# Connect to database and instantly exiting database returns nothing.
# A non existing database returns an error.
if [ -z "$(mysql --user="${USER}" --password=`my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'` --database="${USER}_${PROJECTNAME}" --execute=exit)" ]; then
echo "Drop existing database ${USER}_${PROJECTNAME}."
mysql --user="${USER}" --password=`my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'` -e "DROP DATABASE ${USER}_${PROJECTNAME}"
fi
if [ -z "$(mysql --user="${USER}" --password=`my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'` --database="${USER}_${PROJECTNAME}_dev" --execute=exit)" ]; then
echo "Drop existing database ${USER}_${PROJECTNAME}_dev."
mysql -e "DROP DATABASE ${USER}_${PROJECTNAME}_dev;"
fi
if [ -z "$(mysql --user="${USER}" --password=`my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'` --database="${USER}_${PROJECTNAME}_test" --execute=exit)" ]; then
echo "Drop existing database ${USER}_${PROJECTNAME}_test."
mysql -e "DROP DATABASE ${USER}_${PROJECTNAME}_test;"
fi
echo " create new one ..."
# Create new database.
mysql --user="${USER}" --password=`my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'` -e "CREATE DATABASE ${USER}_${PROJECTNAME} CHARACTER SET utf8"
#mysql --user="${USER}" --password=`my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'` -e "CREATE DATABASE ${USER}_${PROJECTNAME}_dev CHARACTER SET utf8"
#mysql --user="${USER}" --password=`my_print_defaults --defaults-file=${REALHOME}/.my.cnf client | grep -- --password | awk -F = '{ print $2 }'` -e "CREATE DATABASE ${USER}_${PROJECTNAME}_test CHARACTER SET utf8"
fi
echo " create, migrate and seed the database ..."
SECRET_KEY_BASE=$(./bin/rake secret)
echo "export SECRET_KEY_BASE=$SECRET_KEY_BASE" >> $HOME/.bashrc
RAILS_ENV=production bundle exec rake db:create db:migrate db:seed
################################################################################
### Node Package Manager & Bower ### ###########################################
################################################################################
cd ${WORKSPACE}/${PROJECTNAME}
# Node Package Manager.
cat > ${HOME}/.npmrc <<__EOF__
prefix = $HOME
umask = 077
__EOF__
# "Bower - A package manager for the web"
cat > ${HOME}/.bowerrc <<__EOF__
{
"interactive": false
}
__EOF__
# cat > ${WORKSPACE}/${PROJECTNAME}/.bowerrc <<__EOF__
# {
# "directory": "vendor/assets/components"
# }
# __EOF__
# Help: https://docs.npmjs.com/cli/install
echo "Installing bower via npm ..."
npm install -g bower
echo "Installing node modules via npm ..."
npm install
# echo "Installing bower components via bower ..."
# bower install
################################################################################
### Precompile OpenProject ### #################################################
################################################################################
echo "Precompile assets ..."
RAILS_ENV=production bundle exec rake assets:precompile
################################################################################
### Startscripts ### ###########################################################
################################################################################
echo "Create OpenProject start scripts ..."
# OpenProject web starter.
mkdir -p ${HOME}/bin
cat > ${HOME}/bin/${PROJECTNAME}-web <<__EOF__
#!/usr/bin/env bash
HOME=${WORKSPACE}/${PROJECTNAME}-home
PATH=\${HOME}/bin:\${HOME}/.local/bin:\${PATH}
PATH=/package/host/localhost/ruby-${RUBY_V}/bin:\${PATH}
PATH=\${HOME}/.gem/ruby/${RUBYGEM_V}/bin:\${PATH}
PATH=/package/host/localhost/nodejs-${NODE_V}/bin:\${PATH}
export SECRET_KEY_BASE=$SECRET_KEY_BASE
# Start the application in the project folder.
cd ${WORKSPACE}/${PROJECTNAME}
exec bundle exec unicorn --port ${PORT} --env production
__EOF__
chmod +x ${HOME}/bin/${PROJECTNAME}-web
# OpenProject worker starter.
mkdir -p ${HOME}/bin
cat > ${HOME}/bin/${PROJECTNAME}-worker <<__EOF__
#!/usr/bin/env bash
HOME=${WORKSPACE}/${PROJECTNAME}-home
PATH=\${HOME}/bin:\${HOME}/.local/bin:\${PATH}
PATH=/package/host/localhost/ruby-${RUBY_V}/bin:\${PATH}
PATH=\${HOME}/.gem/ruby/${RUBYGEM_V}/bin:\${PATH}
PATH=/package/host/localhost/nodejs-${NODE_V}/bin:\${PATH}
# Use the production database.
export RAILS_ENV=production
# Start the application in the project folder.
cd ${WORKSPACE}/${PROJECTNAME}
exec bundle exec rake jobs:work
__EOF__
chmod +x ${HOME}/bin/${PROJECTNAME}-worker
################################################################################
### Start Services ### #########################################################
################################################################################
echo "Install OpenProject services ..."
# We change $HOME back to the real one.
# We need this for managing the project as service.
HOME=${REALHOME}
test -d ${HOME}/service || uberspace-setup-svscan
uberspace-setup-service ${PROJECTNAME}-web ${WORKSPACE}/${PROJECTNAME}-home/bin/${PROJECTNAME}-web
uberspace-setup-service ${PROJECTNAME}-worker ${WORKSPACE}/${PROJECTNAME}-home/bin/${PROJECTNAME}-worker
################################################################################
### Rewrite Proxy ### ##########################################################
################################################################################
echo "Install OpenProject apache rewrite proxy ..."
mkdir -p /var/www/virtual/${USER}/${SUBDOMAIN}.${USER}.$(hostname -a).uberspace.de
if [ -n "${DOMAINNAME}" ]; then
ln -s /var/www/virtual/${USER}/${SUBDOMAIN}.${USER}.$(hostname -a).uberspace.de /var/www/virtual/${USER}/${DOMAINNAME}
fi
cat > /var/www/virtual/${USER}/${SUBDOMAIN}.${USER}.$(hostname -a).uberspace.de/.htaccess <<__EOF__
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{ENV:HTTPS} !=on
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
RewriteRule (.*) http://localhost:${PORT}/\$1 [P]
__EOF__
################################################################################
### Info ### ###################################################################
################################################################################
echo " "
echo "You can do your first login:"
echo " https://${DOMAINNAME}"
echo " user: admin"
echo " password: admin"
echo " Change the password immediately!"
echo " "
echo "To seed your OpenProject instance with roles, workflows, ...,"
echo " got to: https://${DOMAINNAME}/settings?tab=display"
echo " and set your language. "
echo " After that, got to: https://${DOMAINNAME}/admin/projects"
echo " select your language and click at 'loading default configuration'."
echo " "
echo "Restart OpenProject services:"
echo " svc -du ~/service/${PROJECTNAME}-web"
echo " svc -du ~/service/${PROJECTNAME}-worker"
echo "Logs will be written in:"
echo " ~/service/${PROJECTNAME}-web/log/main/current"
echo " ~/service/${PROJECTNAME}-worker/log/main/current"
echo " "
echo "For uninstallation call:"
echo " $(cd `dirname "${BASH_SOURCE[0]}"` && pwd)/`basename "${BASH_SOURCE[0]}"` uninstall"
echo "For uninstallation including databases and git repo use:"
echo " $(cd `dirname "${BASH_SOURCE[0]}"` && pwd)/`basename "${BASH_SOURCE[0]}"` uninstallall"
### Log ### ####################################################################
echo " "
time_end=$(date +"%s")
time_diff=$((${time_end}-${time_begin}))
echo "### Finished Job: ${JOB_NAME} at $(date "+%Y-%m-%dT%H:%M:%S"). ###"
echo " $((${time_diff} / 60)) minutes and $((${time_diff} % 60)) seconds elapsed."
echo " "
################################################################################
################################################################################
@Tschoepler

This comment has been minimized.

Copy link

Tschoepler commented Aug 30, 2016

Hi and thanks for this script. I get the following error:
openproject.sh: line 101: 1: unbound variable
Could you give a hint on how to fix this?

Also: have you tested this script with version 6 of OpenProject?

Again, thanks for sharing!

@mbrunnen

This comment has been minimized.

Copy link
Owner Author

mbrunnen commented Dec 27, 2017

Hey, sorry for that late answer. I will check that later. Seems that the missing commandline argument, e.g. install, is the problem. You can remove set -o nounset at the beginning to kill the sympton.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.