[关闭]
@armink 2014-04-10T15:17:20.000000Z 字数 14531 阅读 2181

Ubuntu Server12.04+Nginx安装Redmine2.5.1

参考安装文档:
- http://www.redmine.org/projects/redmine/wiki/RedmineInstall#fn1
- http://blog.csdn.net/csfreebird/article/details/18138869


1、安装MySQL

sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev

删除匿名用户

#登陆MySQL数据库
mysql -u root -p
#查看所有用户
mysql> select user,host from mysql.user;
#删除所有空用户(匿名用户)
mysql> delete from mysql.user where user='';
#检查删除结果
mysql> select user,host from mysql.user;
#退出MySQL数据库
mysql> \q

2、安装Nginx

sudo apt-get install -y nginx

3、安装RMagick

sudo apt-get install imagemagick libmagickcore-dev libmagickwand-dev

4、安装Ruby

如果存在旧版本Ruby1.8及1.9请先卸载

sudo apt-get remove ruby1.8 ruby1.9

下载、编译Ruby2.0

mkdir /tmp/ruby && cd /tmp/ruby
curl --progress ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p353.tar.gz | tar xz
cd ruby-2.0.0-p353
./configure --disable-install-rdoc
make
sudo make install

国内用户建议更换Ruby Gem源为淘宝源,提高Gem安装速度

sudo gem sources --remove https://rubygems.org/
sudo gem sources -a http://ruby.taobao.org/
#更新缓存
sudo gem sources -u
#查看源,请确保只有 ruby.taobao.org
gem sources -l

安装Bundler Gem

sudo gem install bundler --no-ri --no-rdoc

安装ImageMagick Gem

sudo gem install rmagick -v '2.13.2'

5、下载Redmine2.5.1

#创建Redmine用户
sudo adduser --disabled-login --gecos 'Redmine' redmine
#进入Redmine用户目录
cd /home/redmine
#下载解压源码
curl --progress http://www.redmine.org/releases/redmine-2.5.1.tar.gz | tar xz
#修改文件夹名为redmine
sudo mv redmine-2.5.1 redmine

6、配置MySQL数据库

初始化数据库

#登陆数据库
mysql -u root -p
#创建Redmine数据库
mysql> CREATE DATABASE redmine CHARACTER SET utf8;
#创建Redmine用户,密码'my_password'可以自己设定,后面需要用到
mysql> CREATE USER 'redmine'@'localhost' IDENTIFIED BY 'my_password';
mysql> GRANT ALL PRIVILEGES ON redmine.* TO 'redmine'@'localhost';

数据库连接配置

#进入Redmine目录
cd /home/redmine/redmine
#复制Redmine数据库默认配置
sudo cp config/database.yml.example config/database.yml

修改配置信息

sudo gedit config/database.yml

找到如下内容

production:
  adapter: mysql2    
  database: redmine    
  host: localhost    
  username: root    
  password: ""    
  encoding: utf8

默认password为空,将其修改为之前设置的MySQL中Redmine用户密码,保存即可。

7、安装Redmine需要的Gem依赖

#进入Redmine目录
cd /home/redmine/redmine
#通过bundle安装Gem依赖
sudo bundle install --without development test

8、Redmine会话配置、数据库初始化及文件系统权限设置

#生成session store
sudo rake generate_secret_token
#创建数据库结构
sudo RAILS_ENV=production rake db:migrate
#插入默认数据,根据提示信息选择指定语言。我这里选择中文,对应选项为zh
sudo RAILS_ENV=production rake redmine:load_default_data
sudo mkdir -p tmp tmp/pdf public/plugin_assets  
sudo chown -R redmine:redmine files log tmp public/plugin_assets
sudo chmod -R 755 files log tmp public/plugin_assets

9、测试

#启动服务用于测试
sudo ruby script/rails server webrick -e production

在浏览器中输入http://localhost:3000即可看到Redmine的站点了
默认账号:admin
默认密码:admin

10、集成unicorn app server

nginx 是一个非常高效的 http server, 而 unicorn 是一个非常高效的 app server。
首先编辑Gemfile文件

sudo gedit Gemfile

打开文件后,在增加unicorn配置,将下面代码插入文件中。(我这里是放到openid组的后面)

# Application server add by armink
group :unicorn do
  gem "unicorn", '~> 4.6.3'
  gem 'unicorn-worker-killer'
end

通过bundle更新Gem依赖,此时会看到unicorn被安装。

sudo bundle install --without development test

增加unicorn配置文件,通过gedit命令打开config/unicorn.rb

sudo gedit config/unicorn.rb

打开空文件后,在里面添加如下内容,我这里端口设置为8082。(里面内容都是参考Gitlab中的unicorn配置修改的)

  1. # Sample verbose configuration file for Unicorn (not Rack)
  2. #
  3. # This configuration file documents many features of Unicorn
  4. # that may not be needed for some applications. See
  5. # http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb
  6. # for a much simpler configuration file.
  7. #
  8. # See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete
  9. # documentation.
  10. # Use at least one worker per core if you're on a dedicated server,
  11. # more will usually help for _short_ waits on databases/caches.
  12. worker_processes 2
  13. # Since Unicorn is never exposed to outside clients, it does not need to
  14. # run on the standard HTTP port (80), there is no reason to start Unicorn
  15. # as root unless it's from system init scripts.
  16. # If running the master process as root and the workers as an unprivileged
  17. # user, do this to switch euid/egid in the workers (also chowns logs):
  18. # user "unprivileged_user", "unprivileged_group"
  19. # Help ensure your application will always spawn in the symlinked
  20. # "current" directory that Capistrano sets up.
  21. working_directory "/home/redmine/redmine" # available in 0.94.0+
  22. # listen on both a Unix domain socket and a TCP port,
  23. # we use a shorter backlog for quicker failover when busy
  24. listen "/home/redmine/redmine/tmp/sockets/redmine.socket", :backlog => 64
  25. listen "127.0.0.1:8082", :tcp_nopush => true
  26. # nuke workers after 30 seconds instead of 60 seconds (the default)
  27. timeout 30
  28. # feel free to point this anywhere accessible on the filesystem
  29. pid "/home/redmine/redmine/tmp/pids/unicorn.pid"
  30. # By default, the Unicorn logger will write to stderr.
  31. # Additionally, some applications/frameworks log to stderr or stdout,
  32. # so prevent them from going to /dev/null when daemonized here:
  33. stderr_path "/home/redmine/redmine/log/unicorn.stderr.log"
  34. stdout_path "/home/redmine/redmine/log/unicorn.stdout.log"
  35. # combine Ruby 2.0.0dev or REE with "preload_app true" for memory savings
  36. # http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
  37. preload_app true
  38. GC.respond_to?(:copy_on_write_friendly=) and
  39. GC.copy_on_write_friendly = true
  40. # Enable this flag to have unicorn test client connections by writing the
  41. # beginning of the HTTP headers before calling the application. This
  42. # prevents calling the application for connections that have disconnected
  43. # while queued. This is only guaranteed to detect clients on the same
  44. # host unicorn runs on, and unlikely to detect disconnects even on a
  45. # fast LAN.
  46. check_client_connection false
  47. before_fork do |server, worker|
  48. # the following is highly recomended for Rails + "preload_app true"
  49. # as there's no need for the master process to hold a connection
  50. defined?(ActiveRecord::Base) and
  51. ActiveRecord::Base.connection.disconnect!
  52. # The following is only recommended for memory/DB-constrained
  53. # installations. It is not needed if your system can house
  54. # twice as many worker_processes as you have configured.
  55. #
  56. # This allows a new master process to incrementally
  57. # phase out the old master process with SIGTTOU to avoid a
  58. # thundering herd (especially in the "preload_app false" case)
  59. # when doing a transparent upgrade. The last worker spawned
  60. # will then kill off the old master process with a SIGQUIT.
  61. old_pid = "#{server.config[:pid]}.oldbin"
  62. if old_pid != server.pid
  63. begin
  64. sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
  65. Process.kill(sig, File.read(old_pid).to_i)
  66. rescue Errno::ENOENT, Errno::ESRCH
  67. end
  68. end
  69. #
  70. # Throttle the master from forking too quickly by sleeping. Due
  71. # to the implementation of standard Unix signal handlers, this
  72. # helps (but does not completely) prevent identical, repeated signals
  73. # from being lost when the receiving process is busy.
  74. # sleep 1
  75. end
  76. after_fork do |server, worker|
  77. # per-process listener ports for debugging/admin/migrations
  78. # addr = "127.0.0.1:#{9293 + worker.nr}"
  79. # server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true)
  80. # the following is *required* for Rails + "preload_app true",
  81. defined?(ActiveRecord::Base) and
  82. ActiveRecord::Base.establish_connection
  83. # if preload_app is true, then you may also want to check and
  84. # restart any other shared sockets/descriptors such as Memcached,
  85. # and Redis. TokyoCabinet file handles are safe to reuse
  86. # between any number of forked children (assuming your kernel
  87. # correctly implements pread()/pwrite() system calls)
  88. end

11、配置Redmine开机自启动

我这里思路和Gitlab是一样的,首先在script文件夹中增加脚本文件对unicorn实现启动、停止等命令控制,再在/etc/init.d文件夹中增加开机自启动脚本,注册启动服务即可。详细过程如下。
增加unicorn控制脚本,通过gedit命令打开script/web

sudo gedit script/web

打开空白文件后,再里面添加如下内容。

  1. #!/usr/bin/env bash
  2. cd $(dirname $0)/..
  3. app_root=$(pwd)
  4. unicorn_pidfile="$app_root/tmp/pids/unicorn.pid"
  5. unicorn_config="$app_root/config/unicorn.rb"
  6. function get_unicorn_pid
  7. {
  8. local pid=$(cat $unicorn_pidfile)
  9. if [ -z $pid ] ; then
  10. echo "Could not find a PID in $unicorn_pidfile"
  11. exit 1
  12. fi
  13. unicorn_pid=$pid
  14. }
  15. function start
  16. {
  17. bundle exec unicorn_rails -D -c $unicorn_config -E $RAILS_ENV
  18. }
  19. function stop
  20. {
  21. get_unicorn_pid
  22. kill -QUIT $unicorn_pid
  23. }
  24. function reload
  25. {
  26. get_unicorn_pid
  27. kill -USR2 $unicorn_pid
  28. }
  29. case "$1" in
  30. start)
  31. start
  32. ;;
  33. stop)
  34. stop
  35. ;;
  36. reload)
  37. reload
  38. ;;
  39. *)
  40. echo "Usage: RAILS_ENV=your_env $0 {start|stop|reload}"
  41. ;;
  42. esac

设置该脚本文件属性为可执行文件

sudo chmod 755 script/web

增加开机自启动脚本,实现对Redmine中的unicorn开机自启动,通过gedit命令打开/etc/init.d/redmine

sudo gedit /etc/init.d/redmine

在该空白启动脚本文件中加入以下内容

  1. #! /bin/sh
  2. # REDMINE
  3. # Maintainer: @armink
  4. # Authors: armink.ztl@gmail.com, @armink
  5. ### BEGIN INIT INFO
  6. # Provides: redmine
  7. # Required-Start: $local_fs $remote_fs $network $syslog redis-server
  8. # Required-Stop: $local_fs $remote_fs $network $syslog
  9. # Default-Start: 2 3 4 5
  10. # Default-Stop: 0 1 6
  11. ### END INIT INFO
  12. ###
  13. # DO NOT EDIT THIS FILE!
  14. # This file will be overwritten on update.
  15. # Instead add/change your variables in /etc/default/redmine
  16. # An example defaults file can be found in lib/support/init.d/redmine.default.example
  17. ###
  18. ### Environment variables
  19. RAILS_ENV="production"
  20. # Script variable names should be lower-case not to conflict with
  21. # internal /bin/sh variables such as PATH, EDITOR or SHELL.
  22. app_user="redmine"
  23. app_root="/home/$app_user/redmine"
  24. pid_path="$app_root/tmp/pids"
  25. socket_path="$app_root/tmp/sockets"
  26. web_server_pid_path="$pid_path/unicorn.pid"
  27. # Read configuration variable file if it is present
  28. test -f /etc/default/redmine && . /etc/default/redmine
  29. # Switch to the app_user if it is not he/she who is running the script.
  30. if [ "$USER" != "$app_user" ]; then
  31. sudo -u "$app_user" -H -i $0 "$@"; exit;
  32. fi
  33. # Switch to the redmine path, exit on failure.
  34. if ! cd "$app_root" ; then
  35. echo "Failed to cd into $app_root, exiting!"; exit 1
  36. fi
  37. ### Init Script functions
  38. ## Gets the pids from the files
  39. check_pids(){
  40. if ! mkdir -p "$pid_path"; then
  41. echo "Could not create the path $pid_path needed to store the pids."
  42. exit 1
  43. fi
  44. # If there exists a file which should hold the value of the Unicorn pid: read it.
  45. if [ -f "$web_server_pid_path" ]; then
  46. wpid=$(cat "$web_server_pid_path")
  47. else
  48. wpid=0
  49. fi
  50. }
  51. ## Called when we have started the two processes and are waiting for their pid files.
  52. wait_for_pids(){
  53. i=0;
  54. while [ ! -f $web_server_pid_path ]; do
  55. sleep 0.1;
  56. i=$((i+1))
  57. if [ $((i%10)) = 0 ]; then
  58. echo -n "."
  59. elif [ $((i)) = 301 ]; then
  60. echo "Waited 30s for the processes to write their pids, something probably went wrong."
  61. exit 1;
  62. fi
  63. done
  64. echo
  65. }
  66. # We use the pids in so many parts of the script it makes sense to always check them.
  67. # Only after start() is run should the pids change.
  68. check_pids
  69. ## Checks whether the different parts of the service are already running or not.
  70. check_status(){
  71. check_pids
  72. # If the web server is running kill -0 $wpid returns true, or rather 0.
  73. # Checks of *_status should only check for == 0 or != 0, never anything else.
  74. if [ $wpid -ne 0 ]; then
  75. kill -0 "$wpid" 2>/dev/null
  76. web_status="$?"
  77. else
  78. web_status="-1"
  79. fi
  80. if [ $web_status = 0 ]; then
  81. redmine_status=0
  82. else
  83. # http://refspecs.linuxbase.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
  84. # code 3 means 'program is not running'
  85. redmine_status=3
  86. fi
  87. }
  88. ## Check for stale pids and remove them if necessary.
  89. check_stale_pids(){
  90. check_status
  91. # If there is a pid it is something else than 0, the service is running if
  92. # *_status is == 0.
  93. if [ "$wpid" != "0" -a "$web_status" != "0" ]; then
  94. echo "Removing stale Unicorn web server pid. This is most likely caused by the web server crashing the last time it ran."
  95. if ! rm "$web_server_pid_path"; then
  96. echo "Unable to remove stale pid, exiting."
  97. exit 1
  98. fi
  99. fi
  100. }
  101. ## If no parts of the service is running, bail out.
  102. exit_if_not_running(){
  103. check_stale_pids
  104. if [ "$web_status" != "0" ]; then
  105. echo "Redmine is not running."
  106. exit
  107. fi
  108. }
  109. ## Starts Unicorn if it's not running.
  110. start() {
  111. check_stale_pids
  112. if [ "$web_status" != "0" ]; then
  113. echo -n "Starting the Redmine Unicorn."
  114. fi
  115. # Then check if the service is running. If it is: don't start again.
  116. if [ "$web_status" = "0" ]; then
  117. echo "The Unicorn web server already running with pid $wpid, not restarting."
  118. else
  119. # Remove old socket if it exists
  120. rm -f "$socket_path"/redmine.socket 2>/dev/null
  121. # Start the web server
  122. RAILS_ENV=$RAILS_ENV script/web start &
  123. fi
  124. # Wait for the pids to be planted
  125. wait_for_pids
  126. # Finally check the status to tell wether or not Redmine is running
  127. print_status
  128. }
  129. ## Asks the Unicorn if it would be so kind as to stop, if not kills it.
  130. stop() {
  131. exit_if_not_running
  132. if [ "$web_status" = "0" ]; then
  133. echo -n "Shutting down the Redmine Unicorn"
  134. fi
  135. # If the Unicorn web server is running, tell it to stop;
  136. if [ "$web_status" = "0" ]; then
  137. RAILS_ENV=$RAILS_ENV script/web stop
  138. fi
  139. # If something needs to be stopped, lets wait for it to stop. Never use SIGKILL in a script.
  140. while [ "$web_status" = "0" ]; do
  141. sleep 1
  142. check_status
  143. printf "."
  144. if [ "$web_status" != "0" ]; then
  145. printf "\n"
  146. break
  147. fi
  148. done
  149. sleep 1
  150. # Cleaning up unused pids
  151. rm "$web_server_pid_path" 2>/dev/null
  152. print_status
  153. }
  154. ## Prints the status of Redmine and it's components.
  155. print_status() {
  156. check_status
  157. if [ "$web_status" = "0" ]; then
  158. echo "The Redmine is \033[32mrunning\033[0m.\nThe Redmine Unicorn web server pid is $wpid."
  159. else
  160. printf "The Redmine is \033[31mnot running\033[0m.\n"
  161. fi
  162. }
  163. ## Tells unicorn to reload it's config
  164. reload(){
  165. exit_if_not_running
  166. if [ "$wpid" = "0" ];then
  167. echo "The Redmine Unicorn Web server is not running thus its configuration can't be reloaded."
  168. exit 1
  169. fi
  170. printf "Reloading Redmine Unicorn configuration... "
  171. RAILS_ENV=$RAILS_ENV script/web reload
  172. echo "Done."
  173. wait_for_pids
  174. print_status
  175. }
  176. ## Restarts Unicorn.
  177. restart(){
  178. check_status
  179. if [ "$web_status" = "0" ]; then
  180. stop
  181. fi
  182. start
  183. }
  184. ### Finally the input handling.
  185. case "$1" in
  186. start)
  187. start
  188. ;;
  189. stop)
  190. stop
  191. ;;
  192. restart)
  193. restart
  194. ;;
  195. reload|force-reload)
  196. reload
  197. ;;
  198. status)
  199. print_status
  200. exit $redmine_status
  201. ;;
  202. *)
  203. echo "Usage: service redmine {start|stop|restart|reload|status}"
  204. exit 1
  205. ;;
  206. esac
  207. exit

设置该脚本文件属性为可执行文件

chmod 755 /etc/init.d/redmine

存放redmine启动脚本默认运行参数到系统目录
新建并打开/etc/default/redmine文件

sudo gedit /etc/default/redmine

将以下内容拷贝至此空白文件

# RAILS_ENV defines the type of installation that is running.
# Normal values are "production", "test" and "development".
RAILS_ENV="production"

# app_user defines the user that Redmine is run as.
# The default is "redmine".
app_user="redmine"

# app_root defines the folder in which redmine and it's components are installed.
# The default is "/home/$app_user/redmine"
app_root="/home/$app_user/redmine"

# pid_path defines a folder in which the redmine and it's components place their pids.
# This variable is also used below to define the relevant pids for the redmine components.
# The default is "$app_root/tmp/pids"
pid_path="$app_root/tmp/pids"

# socket_path defines the folder in which redmine places the sockets
#The default is "$app_root/tmp/sockets"
socket_path="$app_root/tmp/sockets"

# web_server_pid_path defines the path in which to create the pid file fo the web_server
# The default is "$pid_path/unicorn.pid"
web_server_pid_path="$pid_path/unicorn.pid"

设置此文件属性为可执行文件

chmod 755 /etc/default/redmine

设置Redmine开机自启动

sudo update-rc.d redmine defaults 21

安装过程中遇到问题汇总

问题1:Bundler安装出错

在安装Bundler时,可能会报如下错误:

ERROR:  Loading command: install (LoadError)
    cannot load such file -- openssl
ERROR:  While executing gem ... (NoMethodError)
    undefined method `invoke_with_build_args' for nil:NilClass

原因是没有安装openssl,如果在之前安装了Gitlab默认依赖包里面会包括openssl,否则需要手动安装openssl,方法如下:

#安装libssl-dev
sudo apt-get install libssl-dev
#进入之前解压Ruby2.0源码的目录
cd /tmp/ruby
#进入openssl目录
cd ext/openssl
#编译安装openssl
ruby extconf.rb
make
sudo make install

问题2:ImageMagick安装出错

在进行到 Step 4 - Dependencies installation时,sudo bundle install --without development test命令总是会报ImageMagick安装出错,部分出错日志如下:

ERROR:  Error installing rmagick:
    ERROR: Failed to build gem native extension.
/usr/bin/ruby1.8 extconf.rb
checking for Ruby version >= 1.8.5... yes
checking for gcc... yes
checking for Magick-config... yes
checking for ImageMagick version >= 6.4.9... yes
checking for HDRI disabled version of ImageMagick... yes
checking for stdint.h... yes
checking for sys/types.h... yes
checking for wand/MagickWand.h... no

终于在这里找到答案,前面两个回答对我都没有效果,只有第三个手动安装方式终于尝试安装成功,手动安装ImageMagick步骤如下:

curl --progress ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick.tar.gz | tar xz
#进入ImageMagick源码目录
cd ImageMagick-6.8.8-10
./configure --prefix=/usr/local --with-x=no --disable-static --with-modules --without-perl --without-magick-plus-plus --with-quantum-depth=8 --disable-openmp
make
sudo make install
sudo /sbin/ldconfig /usr/local
sudo ln -f /usr/local/bin/Magick-config /usr/bin/Magick-config
sudo PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ gem install rmagick

安装完成后,再重新执行sudo bundle install --without development test即可完成gems的相关依赖安装。


添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注