torutkのブログ

ソフトウェア・エンジニアのブログ

さくらVPSのOSをCentOS 8に更新、さらにRedmineを4.1に更新(続)

さくらVPSのOSをCentOS 8に、Redmineを4.1に更新、の続き

昨日の作業の続きです。 torutk.hatenablog.jp

Unicornのセットアップ

Unicorn gemのインストール

Unicornrubyモジュール(gem)として提供されるので、bundlerでインストールします。 Redmineをインストールしたディレクトリ下(例:/var/lib/redmine-4.1-stable)に、Gemfile.localというファイルを作成し、そこに以下を記述します。

gem "unicorn"

Redmineをインストールしたディレクトリで bundle update を実行します。

$ cd /var/lib/redmine-4.1-stable
$ bundle update
  :
Installing kgio 2.11.3 with native extensions
  :
Installing raindrops 0.19.1 with native extensions
  :
Installing unicorn 5.5.4 with native extensions
undle updated!
Gems in the groups development, test and rmagick were not installed.

Unicorn手動起動確認

一時的にファイアウォールのポート3000を開けて、コマンドラインからUnicornを実行します。

# firewall-cmd --add-port=3000/tcp
$ bundle exec unicorn_rails -l 3000 -E production
I, [2020-04-25T09:52:12.230444 #13548]  INFO -- : listening on addr=0.0.0.0:3000 fd=7
I, [2020-04-25T09:52:12.230701 #13548]  INFO -- : worker=0 spawning...
I, [2020-04-25T09:52:12.232185 #13548]  INFO -- : master process ready
I, [2020-04-25T09:52:12.232568 #13549]  INFO -- : worker=0 spawned pid=13549
I, [2020-04-25T09:52:12.232769 #13549]  INFO -- : Refreshing Gem list
I, [2020-04-25T09:52:23.309370 #13549]  INFO -- : worker=0 ready

Webブラウザからポート3000にアクセスしたところ、Redmine画面が表示されました。

気付き事項

ブラウザからのアクセス後、しばらくしてからコマンドラインを見ると、次のエラーメッセージが表示されていました。

E, [2020-04-25T09:53:43.324350 #13548] ERROR -- : worker=0 PID:13549 timeout (61s > 60s), killing
E, [2020-04-25T09:53:43.337562 #13548] ERROR -- : reaped #<Process::Status: pid 13549 SIGKILL (signal 9)> worker=0
I, [2020-04-25T09:53:43.337859 #13548]  INFO -- : worker=0 spawning...
I, [2020-04-25T09:53:43.339628 #13553]  INFO -- : worker=0 spawned pid=13553
I, [2020-04-25T09:53:43.339902 #13553]  INFO -- : Refreshing Gem list
I, [2020-04-25T09:53:49.106922 #13553]  INFO -- : worker=0 ready

タイムアウト60秒を超過したため、ワーカープロセスを再起動しているようです。 これは継続して発生してはおらず、WebブラウザからUnicornにアクセスをした後に発生しています。

Unicornの設定ファイル記述前の手動起動なので問題ないかもしれませんが、一応メモとして残しておきます。

Unicorn設定ファイル記述

Redmineインストールディレクトリ下のconfigディレクトリに、unicorn.rbというファイル名で設定を記述します。 Unicorn起動時にオプションで設定ファイルを指定します。

# -*- coding: utf-8 -*-
# Unicorn設定ファイル

# ワーカープロセスの数。1ワーカーで1つのリクエストを処理する。
# ワーカー数が上限に達すると、先行するリクエストが完了するまで待ちとなる。
worker_processes 2

# リクエスト待ち受け口、TCPとUNIXドメインとが指定可能。
# UNIXドメインソケットのパスは絶対パスで記述する。
listen "/var/run/unicorn/unicorn.sock", :backlog => 32
listen 8282, :tcp_nopush => true

# タイムアウト秒数
timeout 30

# 稼働中のプロセスのPIDを書いておくファイル。
pid "tmp/pids/unicorn.pid"

# デーモンで起動すると標準出力/標準エラー出力が/dev/nullになるので、
# それぞれログファイルに出力する。
stderr_path "log/unicorn.stderr.log"
stdout_path "log/unicorn.stdout.log"

# マスタープロセス起動時にアプリケーションをロードする(true時)。
# ワーカープロセス側でロードをしないのでメモリ消費、応答性良好になる。
# ただし、ソケットはfork後に開きなおす必要あり。
# HUPシグナルでアプリケーションはロードされない。
preload_app true

# unicornと同一ホスト上のクライアントとのコネクション限定で、維持されているかを
# アプリケーションを呼ぶ前にチェックする。
check_client_connection false

before_fork do |server, worker|
  # Railsでpreload_appをtrueにしているときは強く推奨
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
  # new master phase out the old master
  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end

after_fork do |server, worker|
  # Railsでpreload_appをtrueにしているときは必須
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

この設定ファイルは、Unicornを実行するときにカレントディレクトリが Redmineインストールディレクトリ(/var/lib/redmine-4.1-stable)にあることを前提としています。

worker_processes

応答性を良好に保つには、コア数以上のワーカーを指定します。ただし、仮想化環境ではCPU使用率とメモリ使用量を見ながらワーカー数を許容範囲まで増やします。

listen

リクエストを受け付けるプロトコルとポート、オプション設定を指定します。

UNIXドメインソケットの場合の例

listen "/var/run/unicorn/unicorn.sock", :backlog => 32

TCPソケットの場合の例

listen 8282, :tcp_nopush => true

複数のプロトコルを列挙することで複数のプロトコル・ポートを扱うことができます。

UNIXドメインソケットはUnicornプロセスとNginxプロセスの間で読み書きする特殊ファイルです。Systemd 環境および SELinux 有効下では、/tmp や Unicornディレクトリ配下に置くことが難しいので、/var/run以下に置きます。/var/run 直下にファイルを作成するにはroot権限が必要なため、Unicorn起動時にroot権限で/var/run/unicornディレクトリを作成し、その後に Unicorn が/var/run/unicorn/unicorn.sockを設ける手順を踏みます。

backlogは、workerが作業中でもコネクションのリクエストを受理して待機しておくことができる個数で、デフォルトは1024です。例えば1件平均30msで捌く処理に対して1000個バックログによる待ちがあると、新たにリクエストした処理は結果が返るまで30秒間待たされることになります。それだったらコネクションを受け付けずにエラーにした方がよいということがあります。参考までに自宅で運用しているRedmineのログからCompleted行にある処理時間の平均は約100msでした。

tcp_nopushは、TCP_CORK(Linux)を制御します。デフォルトはfalseです。trueにすると、TCPフレームの断片が小出しに送られることを抑止するので、リモートにあるNginxのタスクを早めに起こさずにすませます。

同一マシン上でNginxとUnicornとを連携してサービスを稼働する場合は、TCPソケットは使用しないので、Unicorn単独での動作確認を終えたら削除(またはコメントアウト)しておきます。

timeout

workerがこの秒数以上処理に費やすとプロセスを落とします。デフォルトは60秒です。大抵の処理はずっと短いので60秒は大きすぎる値ですが、中に時間のかかる処理があれば処理時間に応じて値を増やします。

Redmineでは、大きなサイズの添付ファイルのアップロード・ダウンロードが該当します。Redmineの添付ファイルサイズ上限のファイルを実際にアップロード・ダウンロードさせてかかる時間を計測し、それを許容できる処理時間を設定します。

ここで設定するunicornタイムアウト値とNginxのタイムアウト値が不整合だとかなり怪しい挙動となりますので、両者のタイムアウト値を整合させるようにしてください(unicornタイムアウト値+αをnginxのタイムアウト値にする、αは1ないし2秒程度、等)。

pid

unicornを起動したときにそのプロセスIDを記録しておくファイルを指定します。

stderr_path、stdout_path

Redmineインストールディレクトリ下のlogディレクトリの中にログファイルを生成します。

preload_app

trueに設定すると、マスタープロセス起動時にアプリケーションをロードし、ワーカープロセスをフォークするとアプリケーションが実行可能となります。複数ワーカープロセスでコードを共有するため、メモリ使用効率もよくなります。デメリットは、ワーカープロセスを再起動してもアプリケーションはロードされない点です。

before_fork

ワーカープロセスをforkする前にマスタープロセスによって呼ばれます。 USR2シグナルで新旧マスタープロセスが共存する場合は、旧マスタープロセスにQUITシグナルを送って終了させます。

after_fork

ワーカープロセスがforkされた後に呼び出されます。

Unicornの起動設定(Systemdのサービス定義)

Unicornを、Systemdのサービスとして定義し、マシン起動時に自動で実行されるようにします。また、systemctlコマンドで起動、終了、再読み込みといった制御をできるようにします。

サービス定義のファイルは、/usr/lib/systemd/system/redmine-unicorn.service を新規作成します。

[Unit]
Description=Redmine Unicorn Server
After=mariadb.service

[Service]
User=redmine
Group=redmine
WorkingDirectory=/var/lib/redmine-4.1-stable
Environment=RAILS_ENV=production
SyslogIdentifier=redmine-unicorn
PIDFile=/var/lib/redmine-4.1-stable/tmp/pids/unicorn.pid
PermissionsStartOnly=true
ExecStartPre=/usr/bin/install -m 755 -o redmine -g redmine -d /var/run/unicorn
ExecStart=/usr/bin/bundle exec "unicorn_rails -c config/unicorn.rb -E production"
ExecStop=/usr/bin/kill -QUIT $MAINPID
ExecReload=/usr/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target

RedmineUnicorn)は、起動時にデータベースに接続できないとエラー終了してしまいます。 そこで、[Unit]セクションにAfterで、mariadb.serviceが実行されてからredmine-unicorn.serviceが起動されるよう順序を指定します。

SystemdでExecStartにより実行したプロセスの実行ユーザーをroot以外にする場合、[Service]セクションのUser、Groupでユーザー・グループを設定します。

SELinuxの設定上、WorkingDirectoryとPIDFileに設定するパスはシンボリックリンクファイルを含まない実パスで設定します。 WorkingDirectoryを/var/lib下のシンボリックリンクファイルとすると、Systemdから生成したプロセス(タイプinit_t)がCHDIRする際に/var/lib下のリンクファイル(タイプvar_lib_t)への操作許可がないためエラーとなります。通常のファイルへの操作許可はあるので実パスを記述して回避します。

Unicorn起動時にUNIXドメインソケットファイルを/var/run/unicornディレクトリ下に作成します。/var/runディレクトリ直下にファイルを作成するにはroot権限が必要なため、ExecStartPreで/var/run/unicornディレクトリを作成します。ここではディレクトリ作成にinstallコマンドを使っていますが、これはディレクトリ作成とパーミッションの設定をまとめて実施できるためです。

PermissionsStartOnly=true を指定しておくと、UserおよびGourpを指定していてもExecStartPreはroot権限で実行されます。

サービスでのUnicorn起動確認

Systemdのサービスファイルを変更したら、Systemdに設定を再読み込みさせます。

# systemctl daemon-reload

Unicorn単独動作確認のためにポート8282を一時開きます。

# firewall-cmd --add-port=8282/tcp

Unicornサービスを起動します。サービス名は、サービス定義ファイル名から拡張子.serviceを除いた名称です。

# systemctl start redmine-unicorn

サービスが起動したかどうかを確認します。

# systemctl status redmine-unicorn
● redmine-unicorn.service - Redmine Unicorn Server
   Loaded: loaded (/usr/lib/systemd/system/redmine-unicorn.service; disabled; vendor preset: disabled)
   Active: active (running) since Sat 2020-04-25 11:15:15 JST; 1min 35s ago
  Process: 15536 ExecStartPre=/usr/bin/install -m 755 -o redmine -g redmine -d /var/run/unicorn (code=exited, status=0/SUCCESS)
 Main PID: 15538 (ruby)
    Tasks: 7 (limit: 12523)
   Memory: 119.3M
   CGroup: /system.slice/redmine-unicorn.service
           tq15538 unicorn_rails master -c config/unicorn.rb -E production
           tq15546 unicorn_rails worker[0] -c config/unicorn.rb -E production
           mq15548 unicorn_rails worker[1] -c config/unicorn.rb -E production

 4月 25 11:15:15 www.torutk.com systemd[1]: Starting Redmine Unicorn Server...
 4月 25 11:15:15 www.torutk.com systemd[1]: Started Redmine Unicorn Server.

Webブラウザでポート82828にアクセスします。Redmine画面が表示されれば動作確認OKです。

Nginxのセットアップ

CentOS 8のリポジトリ(AppStream)からNginxのモジュールが提供されています。現時点では、バージョン1.14と1.16の2つが提供されています。

# dnf module list nginx
CentOS-8 - AppStream
Name                         Stream                         Profiles                         Summary
nginx                        1.14 [d]                       common [d]                       nginx webserver
nginx                        1.16                           common                           nginx webserver

ヒント: [d]efault, [e]nabled, [x]disabled, [i]nstalled

Nginxは偶数番号のバージョンが安定版で、奇数番号のバージョンが開発版となっています。安定版は1年に1回、毎年4月にリリースされています。1.14は2018年4月、1.16は2019年4月リリースです。

CentOS 8のAppStreamでは、デフォルトは1.14ですが、ここでは1.16をインストールします。

# dnf module install nginx:1.16/common
  :

Nginxのサービスを起動、および自動起動設定します。

# systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.

サービスが起動したかどうか確認します。

# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Sat 2020-04-25 11:31:58 JST; 1min 5s ago
  Process: 17664 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 17662 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 17660 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
 Main PID: 17665 (nginx)
    Tasks: 4 (limit: 12523)
   Memory: 14.5M
   CGroup: /system.slice/nginx.service
           tq17665 nginx: master process /usr/sbin/nginx
           tq17666 nginx: worker process
           tq17667 nginx: worker process
           mq17668 nginx: worker process

 4月 25 11:31:58 www.torutk.com systemd[1]: Starting The nginx HTTP and reverse proxy server...
 4月 25 11:31:58 www.torutk.com nginx[17662]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
 4月 25 11:31:58 www.torutk.com nginx[17662]: nginx: configuration file /etc/nginx/nginx.conf test is successful
 4月 25 11:31:58 www.torutk.com systemd[1]: Started The nginx HTTP and reverse proxy server.

NginxへのHTTPおよびHTTPSアクセスを行うため、ファイアウォールにポートを開きます。これは今後継続して有効とするので永続化の指定を追加します。

# firewall-cmd --add-service={http,https} --permanent
success
# firewall-cmd --reload
success
# firewall-cmd --list-services
dhcpv6-client http https

Webブラウザから、httpおよびhttpsでアクセスしてみます。Nginxのデフォルト画面が表示されたら確認OKです。

Let's Encrypt の設定

更新前のサーバでは、SSL証明書の取得にLet's Encryptのサービスを利用していました。ドメイン名(ホスト名)は変更がないため、そのまま引き継いで利用します。

更新前のサーバにある/etc/letsencryptディレクトリ以下を丸ごとバックアップして新しいサーバの/etc/letsencryptに展開します。

# cd /etc
# tar xzfp ~/etc_letsencrypt.tgz
  :

Certbot(Let's EncryptのACMEクライアントツール)を取得します。

$ curl -O https://dl.eff.org/certbot-auto
$ sudo mv certbot-auto /usr/local/bin/
$ sudo chown root:root /usr/local/bin/certbot-auto
$ sudo chmod 0755 /usr/local/bin/certbot-auto

証明書の更新ができるかをテストします。このコマンドを実行する際は、証明書の対象サーバーのFQDN名で httpアクセスが成功する必要があります。

# certbot-auto renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/www.torutk.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for www.torutk.com
Using the webroot path /usr/share/nginx/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/www.torutk.com/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/www.torutk.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Running post-hook command: systemctl reload nginx

Nginxの設定ファイルを変更

デフォルトの/etc/nginx/nginx.conf には、以下のポート番号80のサーバー設定が含まれているので、まずこれを削除します。

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
          :
    }

それから、/etc/nginx/conf.d/redmine.conf を新規作成し、ここにポート番号80(HTTP)のサーバー設定とポート番号443(HTTPS)のサーバー設定を記述します。

/etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
}
/etc/nginx/conf.d/redmine.conf

Unicornへのリバースプロキシ設定を記述します。また、ポート80へのアクセスはすべてポート443にリダイレクトします。

upstream unicorn {
    server unix:/var/run/unicorn/unicorn.sock;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name pan;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name www.torutk.com;
    root /var/lib/redmine/public;

    ssl_certificate "/etc/letsencrypt/live/www.torutk.com/fullchain.pem";
    ssl_certificate_key "/etc/letsencrypt/live/www.torutk.com/private/privkey.pem";
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 10m;
    ssl_ciphers PROFILE=SYSTEM;
    ssl_prefer_server_ciphers on;

    include /etc/nginx/default.d/*.conf;

    client_max_body_size 1G;

    location / {
        try_files /maintenance.html $uri/index.html $uri.html $uri @app;
    }

    location @app {
        proxy_redirect off;
        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_connect_timeout 60;
        proxy_read_timeout 60;
        proxy_send_timeout 600;
        proxy_pass http://unicorn;
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}
server_name

SSLサーバー証明書のCN(Common Name)と同じサーバー名を記述します。

ssl_ciphers

SSLで使用する暗号スイートを指定。PROFILE=SYSTEM を指定すると、システム全体のポリシーを適用します。 システム全体のポリシーについては次のドキュメントを参照。

第3章 システム全体の暗号化ポリシーの使用 Red Hat Enterprise Linux 8 | Red Hat Customer Portal

try_files

try_filesの先頭に/maintenance.html を記載しています。これは、ドキュメントルート(/var/lib/redmine/public)にmaintenance.htmlが存在していたら、それを表示します。このファイルを置いている間は基本全てのアクセスに対してmaintenance.htmlの内容が返却されます。 ファイルを削除(リネーム)すると、次のアクセスからは通常の振る舞いをします。

Unicornとの連携

Unixドメインソケットのアクセス

NginxからUnicornが使用するUNIXドメインソケット(/var/run/unicorn/unicorn.sock)をSELinux下でアクセスできるように設定します。 /var/run下のファイルは基本的には var_run_t タイプが割り当てられています。nginxプロセスの httpd_t タイプからvar_run_tタイプのunix_domain_socketにアクセス許可がありません。そこで、/var/run/unicorn以下のファイルについて、var_run_tタイプに替えてhttpd_var_run_tタイプを設定します。

SELinuxでファイルにタイプを設定するには semanage コマンドを使います。コマンドが無ければ次のパッケージをインストールします。

# dnf install policycoreutils-python-utils

/var/run/unicorn 以下のファイルにhttpd_var_run_tタイプを設定します。

# semanage fcontext -a -t httpd_var_run_t '/var/run/unicorn(/.*)?'

# restorecon -R -v /var/run/unicorn
問題!再起動時はSELinuxの設定が失われる

/var/runディレクトリはtmpfsで再起動すると中身が消えてしまいます。/var/run/unicornディレクトリも消えてしまいます。そして、新たにディレクトリを作成すると、そのSELinuxのタイプは親ディレクトリのタイプを引き継ぎます。

つまり、再起動後、/var/run/unicornディレクトリを再度作成したときのSELinuxタイプは、/var/runディレクトリのタイプであるvar_run_tとなってしまいます。

回避策として、unicornサービス起動定義ファイルにrestoreconコマンドを追加します。

  ExecStartPre=/usr/bin/install -m 755 -o redmine -g redmine -d /var/run/unicorn
+ ExecStartPre=/usr/sbin/restorecon -R /var/run/unicorn
  ExecStart=/usr/bin/bundle exec "unicorn_rails -c config/unicorn.rb -E production"
シンボリックリンク作成

Nginxの設定に、/var/lib/redmine/public を記述しています。シンボリックリンクを作成します。

# ln -s /var/lib/redmine-4.1-stable /var/lib/redmine

添付ファイルの復元

昨日のデータ移行で、添付ファイルの復元が作業漏れでした。RedmineRuby on Rails)は添付ファイルを特定のディレクトリに保存しています。バックアップしていたファイルを復元します。

rsyncを使ったバックアップからの復元

バックアップを保存しているマシンから、リモートの新Redmineサーバへファイルを復元します。

rsyncコマンドは、バックアップ保存マシン側だけでなく、新Redmineサーバー側にも必要となります。

Redmineサーバーで実施

# dnf install rsync

バックアップ保存マシンで実施

$ cd backup
$ rsync -av -e "ssh -p 58132" redmine_files/ sau@www.torutk.com:/var/lib/redmine/files/
  :

Redmineプラグインのインストール

Redmineサーバーで利用していたプラグインと、新Redmineサーバーでのプラグイン利用の方針を次に示します。

No. プラグイン 旧稼働Ver. DB利用 最新Ver. Redmine 4.1対応 移行方針
1 clipboard_image_paste 1.13 1.13 放棄しRedmine 4.1標準機能を使用
2 redmine_banner 0.1.2 0.3.1 最新版をインストールしマイグレーション実施
3 redmine_github_hook 2.2.1 3.0.1 最新版をインストール
4 redmine_glossary 0.9.2 1.1.0 最新版をインストールしマイグレーション実施
5 redmine_issue_templates 0.2.2-dev 1.0.1 最新版をインストールしマイグレーション実施
6 redmine_latex_mathjax 0.3.0 --- フォーク版をインストール
7 redmine_startpage 0.1.0 0.0.3 放棄しRedmineのroutes.rbに直接設定
8 redmine_wiki_extensions 0.8.2 0.9.0 最新版をインストールしマイグレーション実施
9 redmine_wiki_lists 0.0.9 0.0.9 Redmine 4.0対応 インストールして動作すれば使用継続
10 redmine_xls_export 0.2.1.t11 0.2.1.t11 Redmine 4.0対応 インストールして動作すれば使用継続
11 sidebar_hide 0.0.8 0.0.8 インストールして動作すれば使用継続
12 view_customize 2.1.0 2.5.0 最新版をインストールマイグレーション実施
  • [1] issueでRedmine 4.0.4で動かない件あり。Redmine 4.1からクリップボードの画像をWiki編集領域でペーストすると添付ファイルと画像インライン記法が生成されます。
  • [4] Redmine 4.x向けの別実装 https://github.com/torutk/redmine_glossary
  • [6] Redmine 4.x向けのフォーク版 https://www.redmine.org/plugins/redmine_latex_mathjax
  • [11]sidebar_hideの代替を事前調査した際、PurpleMine2テーマ(サイドバーを隠す機能あり)、View Customizeでサイドバー開閉の制御をする、が候補になりました。PurpleMine2はややどぎつい色づかい(個人的な印象)、View Customizeはサイドバーがコンテンツの上に重畳されるためコンテンツ右側が隠れてしまう等あり、結果はsidebar_hideの動作を追究し、だめならあきらめることとしました。

データベースを使用するプラグインの移行

Redmineサーバーで使用したプラグインのうち、データベース使用が有りのものを移行します。

マイグレートがエラー無く完了すれば移行完了です。

redmine_banner
$ cd /var/lib/redmine/plugins
$  git clone https://github.com/akiko-pusu/redmine_banner.git
  :
$ bundle exec rails redmine:plugins:migrate RAILS_ENV=produ
ction
$
redmine_glossary
$ git clone https://github.com/torutk/redmine_glossary.git
  :
$ bundle exec rails redmine:plugins:migrate RAILS_ENV=production
== 4 RenameGlossaryTermsFromTerms: migrating ==================================
  :(中略)
== 6 RenameGlossaryViewSettingsFromGlossaryStyles: migrated (0.0066s) =========
$
redmine_issue_templates
$ git clone https://github.com/akiko-pusu/redmine_issue_templates.git
  :
$ bundle exec rails redmine:plugins:migrate RAILS_ENV=production
== 20190303082102 CreateNoteTemplates: migrating ==============================
  :(中略)
== 20200314132500 ChangeColumnNoteTemplateDescription: migrated (0.1534s) =====
$
redmine_wiki_extensions
$ git clone https://github.com/haru/redmine_wiki_extensions.git
  :
$ bundle exec rails redmine:plugins:migrate RAILS_ENV=production
$
view_customize
$ git clone https://github.com/onozaty/redmine-view-customize.git view_customize
  :
$ bundle install
  :
Installing activerecord-compatible_legacy_migration 0.1.1
  :
$ bundle exec rails redmine:plugins:migrate RAILS_ENV=production
$

データベースを使用しないプラグインの移行

Redmineサーバーで使用したプラグインのうち、データベース使用が無のものを移行します。

clipboard_image_paste

Redmine 4.1で、クリップボードの画像をWiki編集領域にペーストすると、画像を添付ファイルとし、かつペースト箇所にその画像の添付ファイルのインライン展開記法を挿入します。この機能により、clipboard_image_pasteプラグインの基本機能が代替されます。

そこで、clipboard_image_pasteはRedmine 4.1ではインストールしないこととします。なお、データベースは使用していないので、単に新しいRedmineにインストールしないだけの対処となります。

Redmine 4.1標準機能は、ペースト時に任意矩形範囲をクロップする機能や添付ファイルの名前を変える機能はないようです。

redmine_github_hook

プラグインをインストールします。

$ git clone https://github.com/koppen/redmine_github_hook.git
  :

redmine実行ユーザーでGithubアクセス用のssh鍵認証ファイルを作成します。メールアドレスはGithubアカウントに登録したものを指定します。

~$ ssh-keygen -t rsa -C "torutk@example.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/redmine/.ssh/id_rsa):
Created directory '/home/redmine/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
  :
~$

生成された公開鍵(id_rsa.pub)をcatし表示された文字列をコピーし、GithubSSH鍵管理に登録します。 Githubページ を開き、右上隅のSigned inアイコンをクリックし、[Settings] > [SSH and GPG keys] > [New SSH key] で、Title欄に任意の名称(例:Redmine Github Hook on www.torutk.com)を記入、Key欄に、コピーした文字列を入れ、[Add SSH key]ボタンをクリックします。

登録したSSH鍵で疎通確認をします。

~$ ssh -T git@github.com
  :
Hi torutk! You've successfully authenticated, but GitHub does not provide shell access.

上述のように、"successfully authenticated"と表示されれば疎通確認は良好です。疎通確認のコマンドで指定するアカウントは"git@"です。

GithubリポジトリRedmineマシンにミラー

Githubリポジトリのミラーを保持するディレクトリの基点を作成します。

# mkdir /var/lib/git_mirror
# chown redmine:redmine /var/lib/git_mirror

Githubリポジトリのミラーを作成します。

$ cd /var/lib/git_mirror
$ git clone --mirror git://github.com/torutk/redmine_glossary.git
  :

Redmineでプロジェクトのリポジトリに登録します。

WebブラウザGithubの対象リポジトリを開き、[Settings] > [Webhooks] > [Add webhook] をクリックします。

Payload URL欄には、

https://www.torutk.com/github_hook?project_id=<プロジェクト識別子>&repository_id=<リポジトリ識別子>

と入力します。Githubリポジトリ名とプロジェクト識別子が同一であれば、project_idの指定は省略可能です。プロジェクトにリポジトリが単一であればrepository_idは省略可能です。

Content type欄、Secret欄は指定不要です。

Witch events would you like to trigger this webhook? 欄は、[Just the push event]を選択し、[Add webhook]をクリックします。

redmine_latex_mathjax
$ git clone https://github.com/5inf/redmine_latex_mathjax
  :
redmine_startpage

Redmineの保守管理上、プラグインの数を制限するため、本プラグインの使用はやめて、代わりに以下の修正をRedmineに入れます。

  • config/routes.rb
  Rails.application.routes.draw do
-   root :to => 'welcome#index', :as => 'home'
+   root :to => 'wiki#show', :project_id => 'swe', :as => 'home'
redmine_wiki_lists
$ git clone https://github.com/tkusukawa/redmine_wiki_lists.git
  :
redmine_xls_export
$ git clone https://github.com/two-pack/redmine_xls_export.git
  :
$ bundle install
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
  :
Fetching ruby-ole 1.2.12.2
Installing ruby-ole 1.2.12.2
Fetching rubyzip 2.3.0
Installing rubyzip 2.3.0
Fetching spreadsheet 1.2.6
Installing spreadsheet 1.2.6
Using unicorn 5.5.4
Fetching zip-zip 0.3
Installing zip-zip 0.3
Bundle complete! 38 Gemfile dependencies, 68 gems now installed.
Gems in the groups development, test and rmagick were not installed.
Bundled gems are installed into `../vendor/bundler`
$
sidebar_hide
$ git clone https://gitlab.com/bdemirkir/sidebar_hide.git
  :

sidebar_hideがRedmine 4.1で動作するか事前調査した結果では、一応動作するがテーマにより意図しない振る舞いをするという状況となりました。ちなみに相性が悪いテーマが旧Redmine環境でつかっていたGitmikeテーマです。

Unicornを再読み込みしプラグインを反映
# systemctl reload redmine-unicorn

本日の作業はここまで

残件が少しあります。

  • SubversionおよびGitリポジトリの復元
  • SubversionおよびGitのHTTPアクセス(Redmine連携認証あり)
  • テーマの設定
  • ロールと権限の設定
  • メール通知の設定
  • Let's Encryptの証明書更新の確認、crontへの登録
  • Redmineログのログローテーション

これらは明日以降対応とします。