ブログトップ 記事一覧 ログイン 無料ブログ開設

akishin999の日記 RSSフィード Twitter


Google

2016-12-25

CentOS 7 に Crowi をインストールする


手元の CentOS 7 に Markdown で書ける Wiki「Crowi」をインストールしてみました。

Crowi
http://site.crowi.wiki/

crowi/crowi: Crowi - Wiki
https://github.com/crowi/crowi

Node.js のインストール


Crowi は Node.js 製なので、まずは Node.js をインストールします。
Github の Dependencies に「Node.js (4.x)」とあったので 4 系を入れました。

nodesource の yum リポジトリを追加します。

# curl -sL https://rpm.nodesource.com/setup_4.x | bash -

Node.js をインストールします。
また、 native addon 用にビルド用ツールもインストールしました。

# yum install -y nodejs gcc-c++ make

4.7.0 が入りました。

# node -v
v4.7.0

MongoDB のインストール


yum リポジトリの定義ファイルを作成します。

# vi /etc/yum.repos.d/mongodb.repo

内容は以下。

[mongodb]
name=MongoDB repo
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
gpgcheck=0
enabled=0

インストールします。

# yum --enablerepo=mongodb install -y mongodb-org

サーバを起動して接続。

# systemctl start mongod
# mongo

以下のバージョンがインストールされました。

> db.version()
2.6.12

Crowi 用の DB を作成します。
ここでは DB 名は crowidb としました。

> use crowidb
switched to db crowidb

続いてユーザを作成します。
ここでは簡単のため、ユーザ名「crowi」パスワード「password」としました。
実際に構築される際にはもっと複雑で適切な値を設定してください。

> db.createUser({user: "crowi", pwd: "password", roles: [{role: "readWrite", db: "crowidb"}]})
Successfully added user: {
        "user" : "crowi",
        "roles" : [
                {
                        "role" : "readWrite",
                        "db" : "crowidb"
                }
        ]
}

Redis のインストール


EPEL からインストールします。

# rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
# yum install -y http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-8.noarch.rpm
# yum --enablerepo=epel install -y redis

インストールしたらサービスを起動。

# systemctl start redis

自動起動設定も有効にしておきます。

# systemctl enable redis

接続確認してみます。

# redis-cli -h localhost INFO Server
# Server
redis_version:2.8.19
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:c0359e7aa3798aa2
redis_mode:standalone
os:Linux 3.10.0-229.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.8.3
process_id:11369
run_id:fa057241b1600d0779010d71588fb19090a42b6b
tcp_port:6379
uptime_in_seconds:149
uptime_in_days:0
hz:10
lru_clock:6192911
config_file:/etc/redis.conf

問題なさそうです。

Elasticsearch のインストール


まずは Java をインストールします。

# yum install -y java-1.8.0

yum リポジトリからインストールするため、GPG Key をインストールします。

# rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch

リポジトリ定義ファイルを作成。

# vi /etc/yum.repos.d/elasticsearch.repo

内容は以下。

[elasticsearch-2.x]
name=Elasticsearch repository for 2.x packages
baseurl=https://packages.elastic.co/elasticsearch/2.x/centos
gpgcheck=1
gpgkey=https://packages.elastic.co/GPG-KEY-elasticsearch
enabled=0

インストール、起動、自動起動設定の有効化を行います。

# yum --enablerepo=elasticsearch-2.x install -y elasticsearch
# systemctl start elasticsearch
# systemctl enable elasticsearch

日本語に対応するため、analysis-kuromoji をインストールします。

# /usr/share/elasticsearch/bin/plugin install analysis-kuromoji

elasticsearch を再起動し、プラグインが読み込まれている事を確認します。

# systemctl restart elasticsearch
# curl -X GET 'http://localhost:9200/_nodes/plugins?pretty'
{
  "cluster_name" : "elasticsearch",
  "nodes" : {
    "5u4vcPnrQhW4pDLRXRVulA" : {
      "name" : "Wild Child",
      "transport_address" : "127.0.0.1:9300",
      "host" : "127.0.0.1",
      "ip" : "127.0.0.1",
      "version" : "2.4.3",
      "build" : "d38a34e",
      "http_address" : "127.0.0.1:9200",
      "plugins" : [ {
        "name" : "analysis-kuromoji",
        "version" : "2.4.3",
        "description" : "The Japanese (kuromoji) Analysis plugin integrates Lucene kuromoji analysis module into elasticsearch.",
        "jvm" : true,
        "classname" : "org.elasticsearch.plugin.analysis.kuromoji.AnalysisKuromojiPlugin",
        "isolated" : true,
        "site" : false
      } ],
・
・
・

Crowi のインストール


これでやっと必要な環境が揃ったので、 Crowi のセットアップを進めて行きます。

まずは git と krb5-devel をインストール。

# yum install -y git krb5-devel

アプリケーション配置用ディレクトリを作成します。
ここでは「/var/apps」にしました。

# mkdir /var/apps && cd /var/apps/

crowi を Github から clone して v1.5.2 タグをチェックアウトします。

# git clone https://github.com/crowi/crowi.git && cd crowi/
# git checkout refs/tags/v1.5.2

npm install を実行します。
ここが結構時間がかかります。

# npm install

CSS, JS のビルドを実行。
画面にアクセスしてデザインが崩れている場合はこれが抜けている可能性が高いです。

# npm run build

systemd で自動起動できるようにするため、service ファイルを作成します。

# vi /etc/systemd/system/crowi.service

内容は以下のようになります。
「WorkingDirectory」は先程 crowi を配置したディレクトリ。

[Unit]
Description=Crowi
After=network.target mongod.service

[Service]
WorkingDirectory=/var/apps/crowi
EnvironmentFile=/etc/systemd/system/crowi.conf
ExecStart=/usr/bin/node app.js

[Install]
WantedBy=multi-user.target

パスワード seed に使うためにランダム文字列を生成します。
ここでは openssl コマンドを使って以下のようにしました。
この値をメモっておきます。

# openssl rand -base64 128 | head -1
t/yi260BoYViSDiamTzwMOxmV4cuSSkude1X703AnPgpIZDdRTsAJoCPET5pxD5L

service 起動時の環境変数設定ファイルを作成します。

# vi /etc/systemd/system/crowi.conf

内容は以下のようになります。
先程メモった値を「PASSWORD_SEED」に指定しています。

PORT=3000
NODE_ENV=production
MONGO_URI="mongodb://crowi:password@localhost/crowidb"
REDIS_URL="redis://localhost:6379"
ELASTICSEARCH_URI="http://localhost:9200"
PASSWORD_SEED="t/yi260BoYViSDiamTzwMOxmV4cuSSkude1X703AnPgpIZDdRTsAJoCPET5pxD5L"
FILE_UPLOAD=local

これでインストールは完了したので、crowi を起動します。

# systemctl start crowi

念のためサービスのステータスを確認。

# systemctl status crowi
● crowi.service - Crowi
   Loaded: loaded (/etc/systemd/system/crowi.service; enabled; vendor preset: disabled)
   Active: active (running) since 土 2016-12-24 23:24:46 JST; 1s ago
 Main PID: 11621 (node)
   CGroup: /system.slice/crowi.service
           mq11621 /usr/bin/node app.js

問題なく起動したようなので自動起動設定を有効化します。

# systemctl enable crowi
# systemctl is-enabled crowi
enabled

これでブラウザから対象サーバの 3000 番ポートにアクセスすると、以下のような管理者登録画面が表示されます。

f:id:akishin999:20161226010313p:image:w640

ユーザを作成しログインした後は以下のような感じです。

f:id:akishin999:20161226010311p:image:w640

まだちょっとしか触っていませんが、見た目も綺麗だしシンプルで使いやすいし、必要な機能も一通り揃っているのでかなりいい感じです。
個人的には記事を Markdown でエクスポートする機能が付いていると嬉しかったんですが、それはないようでした。
まぁ MongoDB から直接エクスポートすればいいのか・・・。

使った感じは Qiita Team と似ていると思いました。
Qiita Team は確か結構いい値段するんで、自前で構築するのが嫌でなければこっちの方が気軽に導入できていいかも。

参考サイト


Markdownで書けるWiki - Crowi - Qiita
http://qiita.com/nullsnet/items/a6e69e44087339127b35#crowi-1

Crowiで検索を有効化する(CentOS 6.8) - Qiita
http://qiita.com/oshuya/items/05883de5cc275d87a7b8

2016-03-19

Qiita に書いた記事をエクスポートするツールを作ってみた


会社で使っている Qiita Team に投稿した記事を画像ファイルも一緒にエクスポートしたくて書いたスクリプトがあったのですが、せっかくなのでコードを整理して gem にして公開してみました。

https://rubygems.org/gems/qiita-export

以下でインストールできます。

% gem install qiita-export

使い方は以下のような感じです。

# 普通の Qiita の方の記事
% qiita-export -Uakishin -i -o ./outputdir

# team の記事
% qiita-export -texample -Uakishin -i -a <API Token> -o ./outputdir

ついでに MacKobitoSQLite からエクスポートできる機能もつけてみました。

% qiita-export -k -o ./outputdir

あと毎回全部オプション指定するのはちょっと面倒だったので、$HOME 直下か、実行ディレクトリ直下に .qiita-exportrc というファイルがあればその中のオプションを読み取るようになってます。

Kobito がかなりよく出来ているので余り必要になることは無いかと思いますが良かったら使ってみてください。

2015-12-20

ngx_set_misc モジュールを組み込んだ Nginx の RPM を作成する


Nginx に URI エンコード&デコードBase64 エンコード&デコードなどの機能を追加する ngx_set_misc モジュールを組み込んだ RPM を作成してみたのでメモ。

Set Misc | NGINX
http://mogile.web.fc2.com/nginx_wiki/modules/set_misc.html

openresty/set-misc-nginx-module
https://github.com/openresty/set-misc-nginx-module

素直に OpenResty 使えば?という声が聞こえてきそうな気もしますが、ここでは敢えて公式の SRPM に組み込んでみました。
環境は CentOS 7.1 x86_64 です。

# cat /etc/redhat-release
CentOS Linux release 7.1.1503 (Core)
# uname -a
Linux centos7-test01 3.10.0-229.el7.x86_64 #1 SMP Fri Mar 6 11:36:42 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

RPM 作成環境の構築


まずは RPM 作成環境の構築です。
必要なパッケージをインストール

$ su -
# yum install -y gcc rpmdevtools redhat-rpm-config

RPM 作成用ユーザを追加。

# useradd rpmdevel
# passwd rpmdevel

作成したユーザになって rpmdev-setuptree コマンドを実行。

# su - rpmdevel
$ rpmdev-setuptree

以下のディレクトリと設定ファイルが作成されました。

$ ls -ld ~/rpmbuild/
drwxrwxr-x. 7 rpmdevel rpmdevel 67 1220 09:38 /home/rpmdevel/rpmbuild/
$ ls -la ~/.rpmmacros
-rw-rw-r--. 1 rpmdevel rpmdevel 620 1220 09:38 /home/rpmdevel/.rpmmacros

これで RPM 作成の準備は完了です。

Nginx のビルド


Nginx 公式のCentOS 用 SRPM は以下から辿っていくとダウンロードできます。

http://nginx.org/packages/centos/

CentOS 7 用は以下。

http://nginx.org/packages/centos/7/SRPMS/nginx-1.8.0-1.el7.ngx.src.rpm

RPM 作成用ユーザで SRPM を取得してインストールします。

$ rpm -ivh http://nginx.org/packages/centos/7/SRPMS/nginx-1.8.0-1.el7.ngx.src.rpm

SRPM をインストールしたら「~rpmbuild/SPECS/nginx.spec」内の「BuildRequires」の部分を確認し、一旦 root になって必要なパッケージをインストールします。

$ su -
# yum install -y openssl-devel zlib-devel pcre-devel

再度 RPM 作成用ユーザに戻り、ngx_set_misc モジュールをダウンロードして展開します。

# su - rpmdevel
$ wget https://github.com/openresty/set-misc-nginx-module/archive/v0.29.tar.gz
$ tar xzf v0.29.tar.gz

モジュールのビルドには ngx_devel_kit も必要なのでこちらもダウンロードして展開。

$ wget https://github.com/simpl/ngx_devel_kit/archive/v0.2.19.tar.gz
$ tar xzf v0.2.19.tar.gz

それぞれ展開後のパスを確認しておきます。

$ ls -ld /home/rpmdevel/set-misc-nginx-module-0.29/
drwxrwxr-x. 6 rpmdevel rpmdevel 4096  622 22:08 /home/rpmdevel/set-misc-nginx-module-0.29/

$ ls -ld /home/rpmdevel/ngx_devel_kit-0.2.19/
drwxrwxr-x. 9 rpmdevel rpmdevel 4096  926  2013 /home/rpmdevel/ngx_devel_kit-0.2.19/

SRPM に含まれていた SPEC ファイルを編集。

$ vi ~/rpmbuild/SPECS/nginx.spec

「./configure」のところに以下のように「--add-module」を使って先ほど展開した ngx_devel_kit と ngx_set_misc モジュールのパスを指定します。

--add-module=/home/rpmdevel/ngx_devel_kit-0.2.19 \
--add-module=/home/rpmdevel/set-misc-nginx-module-0.29 \

nginx.spec では「./configure」が 2 回定義されているので、ターミナルを狭くして編集している場合など見逃さないように注意が必要です(--with-debug の付いている方と付いていない方があります)。
debug の方は今は特にいらない気もしますが、ここでは取り敢えず両方につけておきました。

追記後の「./configure」の部分は以下のようになります。

%build
./configure \
        --prefix=%{_sysconfdir}/nginx \
        --sbin-path=%{_sbindir}/nginx \
        --conf-path=%{_sysconfdir}/nginx/nginx.conf \
        --error-log-path=%{_localstatedir}/log/nginx/error.log \
        --http-log-path=%{_localstatedir}/log/nginx/access.log \
        --pid-path=%{_localstatedir}/run/nginx.pid \
        --lock-path=%{_localstatedir}/run/nginx.lock \
        --http-client-body-temp-path=%{_localstatedir}/cache/nginx/client_temp \
        --http-proxy-temp-path=%{_localstatedir}/cache/nginx/proxy_temp \
        --http-fastcgi-temp-path=%{_localstatedir}/cache/nginx/fastcgi_temp \
        --http-uwsgi-temp-path=%{_localstatedir}/cache/nginx/uwsgi_temp \
        --http-scgi-temp-path=%{_localstatedir}/cache/nginx/scgi_temp \
        --user=%{nginx_user} \
        --group=%{nginx_group} \
        --with-http_ssl_module \
        --with-http_realip_module \
        --with-http_addition_module \
        --with-http_sub_module \
        --with-http_dav_module \
        --with-http_flv_module \
        --with-http_mp4_module \
        --with-http_gunzip_module \
        --with-http_gzip_static_module \
        --with-http_random_index_module \
        --with-http_secure_link_module \
        --with-http_stub_status_module \
        --with-http_auth_request_module \
        --with-mail \
        --with-mail_ssl_module \
        --with-file-aio \
        --with-ipv6 \
        --with-debug \
        --add-module=/home/rpmdevel/ngx_devel_kit-0.2.19 \
        --add-module=/home/rpmdevel/set-misc-nginx-module-0.29 \
        %{?with_spdy:--with-http_spdy_module} \
        --with-cc-opt="%{optflags} $(pcre-config --cflags)" \
        $*
make %{?_smp_mflags}
%{__mv} %{_builddir}/%{name}-%{version}/objs/nginx \
        %{_builddir}/%{name}-%{version}/objs/nginx.debug
./configure \
        --prefix=%{_sysconfdir}/nginx \
        --sbin-path=%{_sbindir}/nginx \
        --conf-path=%{_sysconfdir}/nginx/nginx.conf \
        --error-log-path=%{_localstatedir}/log/nginx/error.log \
        --http-log-path=%{_localstatedir}/log/nginx/access.log \
        --pid-path=%{_localstatedir}/run/nginx.pid \
        --lock-path=%{_localstatedir}/run/nginx.lock \
        --http-client-body-temp-path=%{_localstatedir}/cache/nginx/client_temp \
        --http-proxy-temp-path=%{_localstatedir}/cache/nginx/proxy_temp \
        --http-fastcgi-temp-path=%{_localstatedir}/cache/nginx/fastcgi_temp \
        --http-uwsgi-temp-path=%{_localstatedir}/cache/nginx/uwsgi_temp \
        --http-scgi-temp-path=%{_localstatedir}/cache/nginx/scgi_temp \
        --user=%{nginx_user} \
        --group=%{nginx_group} \
        --with-http_ssl_module \
        --with-http_realip_module \
        --with-http_addition_module \
        --with-http_sub_module \
        --with-http_dav_module \
        --with-http_flv_module \
        --with-http_mp4_module \
        --with-http_gunzip_module \
        --with-http_gzip_static_module \
        --with-http_random_index_module \
        --with-http_secure_link_module \
        --with-http_stub_status_module \
        --with-http_auth_request_module \
        --with-mail \
        --with-mail_ssl_module \
        --with-file-aio \
        --with-ipv6 \
        --add-module=/home/rpmdevel/ngx_devel_kit-0.2.19 \
        --add-module=/home/rpmdevel/set-misc-nginx-module-0.29 \
        %{?with_spdy:--with-http_spdy_module} \
        --with-cc-opt="%{optflags} $(pcre-config --cflags)" \
        $*
make %{?_smp_mflags}

これで準備はできたので rpmbuild コマンドを実行します。

$ rpmbuild -ba ~/rpmbuild/SPECS/nginx.spec

以下の RPM ファイルが作成されました。

$ ll ~/rpmbuild/RPMS/x86_64/
合計 3288
-rw-rw-r--. 1 rpmdevel rpmdevel  380228 1220 10:00 nginx-1.8.0-1.el7.centos.ngx.x86_64.rpm
-rw-rw-r--. 1 rpmdevel rpmdevel 1753000 1220 10:00 nginx-debug-1.8.0-1.el7.centos.ngx.x86_64.rpm
-rw-rw-r--. 1 rpmdevel rpmdevel 1232812 1220 10:00 nginx-debuginfo-1.8.0-1.el7.centos.ngx.x86_64.rpm

念の為ビルドされたバイナリを -V してみると、表示されるオプションに先ほど spec ファイル内で指定した --add-module が追加されている事を確認できます。

$ ./rpmbuild/BUILD/nginx-1.8.0/objs/nginx -V
nginx version: nginx/1.8.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --add-module=/home/rpmdevel/ngx_devel_kit-0.2.19 --add-module=/home/rpmdevel/set-misc-nginx-module-0.29 --with-http_spdy_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic'

問題無さそうです。

ちょっとだけ使ってみる


作成した RPM ファイルを別サーバに持って行ってインストールしてみます。

$ su -
# yum install -y ./nginx-1.8.0-1.el7.centos.ngx.x86_64.rpm

問題なくインストールされたら、動作確認のため /etc/nginx/conf.d/default.conf を編集します。

# vi /etc/nginx/conf.d/default.conf

いくつか簡単に試せるディレクティブを使ってみます。
default.conf 内の server ブロックの中に以下の設定を追加。

location /today {
    set_local_today $today;
    rewrite ^(.*)$ http://localhost?date=$today permanent;
}

location /base64encode {
    set $a $arg_str;
    set_encode_base64 $a;
    set $args "";
    rewrite ^(.*)$ http://localhost?result=$a permanent;
}

location /base64decode {
    set $a $arg_str;
    set_decode_base64 $b $a;
    set $args "";
    rewrite ^(.*)$ http://localhost?result=$b permanent;
}

設定に問題がないか確認してから Nginx を再起動します。
systemctl 使った方がいいのかも知れませんが取り敢えず使い慣れた service で・・・。

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# service nginx restart
Redirecting to /bin/systemctl restart  nginx.service

curl で動作確認してみます。
まずは set_local_today ディレクティブ。

# curl -I -L http://localhost/today
HTTP/1.1 301 Moved Permanently
Server: nginx/1.8.0
Date: Sun, 20 Dec 2015 08:33:25 GMT
Content-Type: text/html
Content-Length: 184
Connection: keep-alive
Location: http://localhost?date=2015-12-20

HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Sun, 20 Dec 2015 08:33:25 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Sun, 20 Dec 2015 01:34:20 GMT
Connection: keep-alive
ETag: "5676059c-264"
Accept-Ranges: bytes

リダイレクト先(Location) の部分に実行日が設定されているのが判ります。
次は set_encode_base64 ディレクティブ。

# curl -I -L http://localhost/base64encode?str=hello
HTTP/1.1 301 Moved Permanently
Server: nginx/1.8.0
Date: Sun, 20 Dec 2015 08:33:32 GMT
Content-Type: text/html
Content-Length: 184
Connection: keep-alive
Location: http://localhost?result=aGVsbG8=

HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Sun, 20 Dec 2015 08:33:32 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Sun, 20 Dec 2015 01:34:20 GMT
Connection: keep-alive
ETag: "5676059c-264"
Accept-Ranges: bytes

Base64 エンコードされた文字列が返って来ました。
上で返って来た文字列を使って今度は set_decode_base64 ディレクティブを使ってみます。

# curl -I -L http://localhost/base64decode?str=aGVsbG8=
HTTP/1.1 301 Moved Permanently
Server: nginx/1.8.0
Date: Sun, 20 Dec 2015 08:33:40 GMT
Content-Type: text/html
Content-Length: 184
Connection: keep-alive
Location: http://localhost?result=hello

HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Sun, 20 Dec 2015 08:33:40 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Sun, 20 Dec 2015 01:34:20 GMT
Connection: keep-alive
ETag: "5676059c-264"
Accept-Ranges: bytes

ちゃんと元の文字列に戻っています。

ngx_set_misc モジュールでは他にもいろいろなディレクティブが追加されます。

https://github.com/openresty/set-misc-nginx-module#directives

上手に使えばアプリケーションに少し楽をさせてあげることも出来そうです。