wikiの引越し

昨日は MySQL をインストールするところから始めて、MediaWiki を動かすところまで書いたけど、そのあと Windows マシンで運用している既存の wiki の引越しもしたのだった。今日はその手順について、(うろ覚えで)書く。

データベースとファイルのバックアップ

まずはデータベースの中身をファイルに吐き出させる。msqldump をいうコマンドを使うんだけど、パスが通ってなかったのでフルパスで指定。

^o^ > C:\VertrigoServ\Mysql\bin\mysqldump -u root -p wiki > wiki.sql

それから、アップロードしたファイルが保存されているフォルダを zip で固める。

^o^ > cd \www\wiki
^o^ > zip -r images.zip images

2つのファイルを持って、Ubuntu のマシンに移動。

データベースの更新とファイルの配置

Windows マシンから持ってきた wiki.sql ファイルを MySQL に読み込ます。

takatoh@nightschool $ mysql -u root -p wiki < wiki.sql

それから、images.zip を展開。すでに images フォルダがあるけどそのまま上書きする。

takatoh@nightschool $ cd /var/www/html/wiki
takatoh@nightschool $ unzip images.zip

これで一応完了。

エラー発生

ところがブラウザでアクセスしてみると、エラーが発生した。画面には「A database query error has occurred. This may indicate a bug in the software.」とか出ている。どうもデータベースのエラーのよう。ググってみたら↓このページを見つけた。

 cf. [RESOLVED] Database error in upgrading from 1.18 to 1.22

どうやら、mw-config/index.php にアクセスしてインストールをやり直せってことらしい。そのとおりにする。インストールの画面になり、進めていくとLocalSettings.php の中の $wgUpgradeKey の値を入力しろと促されるので入力する。そしたら何やらデータベースをアップグレードしているようになり、完了。
再度ブラウザでアクセスすると、ちゃんと表示された。

画像が表示されない

これは単にファイルのパーミッションの問題だった。images フォルダを展開、上書きした時に所有者が takatoh になってしまって、wiki のユーザーからアクセスできないようになっていた。なので、次のようにして解決。

takatoh@nightschool $ sudo chown -R 2246:500 images
takatoh@nightschool $ sudo chmod -R 755 images

Windowsマシンからだと表示がおかしい

Ubuntu マシンから、localhost でアクセスするぶんには問題は解決したけど、Windows マシンからアクセスすると表示がおかしい。おかしいというのは、本文は表示されるんだけど、スタイルシートなんかが読み込まれていない感じ。
ググって見つけたページがここのコメント欄。

 cf. XAMPP1.81が社内のLANに公開できない – QA@IT

LocalSettings.php の中の $wgServer の値が localhost になっているのが原因らしい。次のようにホスト名に変えた。

$wgServer = "http://nightschool";

これで、無事 Windows マシンからもちゃんと使えるようになった。

UbuntuでMediaWikiを動かす

関連パッケージをインストール。

takatoh@nightschool $ sudo -s
root@nightschool # apt-get install php5-intl php5-gd texlive php5-xcache

MediaWiki を公式サイトからダウンロード。

root@nightschool # wget http://releases.wikimedia.org/mediawiki/1.24/mediawiki-1.24.2.tar.gz

ファイルを展開して、出来たフォルダの名前を変更。

root@nightschool # tar zxvf mediawiki-1.24.2.tar.gz
root@nightschool # mv mediawiki-1.24.2 wiki

あとはブラウザで http://localhost/wiki/ にアクセスするとセットアップ画面になるので、Wiki の名前とかデータベースとかを促されるとおりに入力して行けばOK。最後に LocalSettings.php をダウンロードして、/var/www/html/wiki にコピー。

root@nightschool # cp /home/takatoh/Downloads/LocalSettings.php wiki

これでインストールは完了。Wiki のページにアクセスするとちゃんとできていた。

wiki-mainpage

[追記]

ついでにちょっと設定をかえておく。
まずはロゴ。$wgLogo を設定しろと表示されてるんではかっこ悪いので、標準で付属しているロゴを表示するようにする。LocalSettings.php の $wgLogo を変更。

wgLogo = "$wgScriptPath/skins/MonoBook/wiki.png";

ファイルのアップロードを有効にする。LocalSettings.php の $wgEnableUploads を true にする。

$wgEnableUploads = true;

それから、アップロード可能なファイルサイズを変更。これは MediaWiki じゃなくて PHP の設定。/etc/php5/fpm/php.ini を次のように変更。

upload_max_filesize = 8M

phpMyAdminをインストール

昨日、PHP をインストールしたので、MySQL のついでに phpMyAdmin をインストールしてみた。

参考ページ:

 cf. UbuntuにphpMyAdminをインストールするには – 初心者がWEB開発に挑戦

takatoh@nightschool $ sudo apt-get install phpmyadmin

インストールの途中で、Webサーバを聞いてくるけど Apache と Lighttpd しか選択肢がないので、Esc キーを押して続行。少しすると今度は phpmyadmin を設定するかと訊かれるので、YES。ユーザーとパスワードを設定しただけであとは何やらやっているよう。しばらくすると終わる。

これで http://localhost/phpmyadmin にアクセスすると行けるようだけど…あれ?だめだ。やっぱりさっきの Webサーバ選択のところで Nginx がなかったからか。ググってみた結果、/usr/share/phpmyadmin のシンボリックリンクを Nginx のドキュメントルートに作ればいいようだ。

takatoh@nightschool $ sudo ln -s /usr/share/phpmyadmin /var/www/html

今度はどうだ。
phpmyadmin

うまくいったようだ。

UbuntuにMySqlをインストール

apt-get でインストール。

takatoh@nightschool $ sudo apt-get install mysql-server

途中で root ユーザーのパスワードを入力するように促されるので、入力する(2回)。
バージョンの確認。

takatoh@nightschool $ mysql --version
mysql  Ver 14.14 Distrib 5.5.41, for debian-linux-gnu (x86_64) using readline 6.3

/etc/mysql に移動して、設定ファイル my.cnf に文字コードなど追記。…の前にバックアップをとっておく。

takatoh@nightschool $ sudo cp my.cnf my.cnf.orig
takatoh@nightschool $ sudo vim my.cnf

以下を追記。

[client]
default-character-set = utf8

[mysqld]
skip-character-set-client-handshake
character-set-server = utf8
collation-server = utf8_general_ci
init-connect = SET NAMES utf8

MySQL を再起動。

takatoh@nightschool $ sudo service mysql restart
mysql stop/waiting
mysql start/running, process 30969

MySQL にログイン。

takatoh@nightschool $ mysql -u root -p

ステータスを確認。

mysql> status
--------------
mysql  Ver 14.14 Distrib 5.5.41, for debian-linux-gnu (x86_64) using readline 6.3

Connection id:		36
Current database:	
Current user:		root@localhost
SSL:			Not in use
Current pager:		stdout
Using outfile:		''
Using delimiter:	;
Server version:		5.5.41-0ubuntu0.14.04.1 (Ubuntu)
Protocol version:	10
Connection:		Localhost via UNIX socket
Server characterset:	utf8
Db     characterset:	utf8
Client characterset:	utf8
Conn.  characterset:	utf8
UNIX socket:		/var/run/mysqld/mysqld.sock
Uptime:			1 min 48 sec

Threads: 1  Questions: 109  Slow queries: 0  Opens: 171  Flush tables: 1  Open tables: 41  Queries per second avg: 1.009
--------------

うまくいってるっぽい?
プロセスの確認。

takatoh@nightschool $ ps aux | grep mysqld
mysql    30969  0.0  1.0 484440 42984 ?        Ssl  21:44   0:00 /usr/sbin/mysqld
takatoh  31111  0.0  0.0  16904   932 pts/4    S+   21:47   0:00 grep --color=auto mysqld

参考にしたページ:

 cf. UbuntuにMySQLをインストール – うまとま君の技術めも

UbuntuのNginxでPHPを動かす

ここのページが参考になった。

 cf. ubuntuのnginxでphpの環境設定と動作確認と使い方 – Joppot

php5-fpm をインストール

まずは、apt-get のリポジトリを最新にする。

takatoh@nightschool $ sudo add-apt-repository ppa:ondrej/php5
[sudo] password for takatoh: 
 This branch follows latest PHP packages as maintained by me & rest of the Debian pkg-php team.

You can get more information about the packages at https://sury.org

If you need to stay with PHP 5.4 you can use the oldstable PHP repository:

    ppa:ondrej/php5-oldstable

BUGS&FEATURES: This PPA now has a issue tracker: https://deb.sury.org/pages/bugreporting.html

PLEASE READ: If you like my work and want to give me a little motivation, please consider donating: https://deb.sury.org/pages/donate.html
 詳しい情報: https://launchpad.net/~ondrej/+archive/ubuntu/php5
[ENTER] を押すと続行します。ctrl-c で追加をキャンセルできます

gpg: 鍵輪「/tmp/tmpbrietwz8/secring.gpg」ができました
gpg: 鍵輪「/tmp/tmpbrietwz8/pubring.gpg」ができました
gpg: 鍵E5267A6Cをhkpからサーバーkeyserver.ubuntu.comに要求
gpg: /tmp/tmpbrietwz8/trustdb.gpg: 信用データベースができました
gpg: 鍵E5267A6C: 公開鍵“Launchpad PPA for Ondřej Surý”を読み込みました
gpg: 処理数の合計: 1
gpg:               読込み: 1  (RSA: 1)
OK

apt-get の情報をアップグレード。

takatoh@nightschool $ sudo apt-get upgrade

出力は長いので省略。

php5-fpm のインストール。

takatoh@nightschool $ sudo apt-get install php5-fpm
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージが自動でインストールされましたが、もう必要とされていません:
  ax25-node firefox-locale-en libax25 linux-headers-3.13.0-34
  linux-headers-3.13.0-34-generic linux-image-3.13.0-34-generic
  linux-image-extra-3.13.0-34-generic openbsd-inetd
これを削除するには 'apt-get autoremove' を利用してください。
以下の特別パッケージがインストールされます:
  php5-common php5-json
提案パッケージ:
  php5-user-cache php-pear
以下のパッケージが新たにインストールされます:
  php5-common php5-fpm php5-json
アップグレード: 0 個、新規インストール: 3 個、削除: 0 個、保留: 0 個。
2,667 kB のアーカイブを取得する必要があります。
この操作後に追加で 10.6 MB のディスク容量が消費されます。
続行しますか? [Y/n] Y
取得:1 http://jp.archive.ubuntu.com/ubuntu/ trusty/main php5-json amd64 1.3.2-2build1 [34.4 kB]
取得:2 http://jp.archive.ubuntu.com/ubuntu/ trusty-updates/main php5-common amd64 5.5.9+dfsg-1ubuntu4.7 [442 kB]
取得:3 http://jp.archive.ubuntu.com/ubuntu/ trusty-updates/universe php5-fpm amd64 5.5.9+dfsg-1ubuntu4.7 [2,191 kB]
2,667 kB を 1秒 で取得しました (1,354 kB/s)
以前に未選択のパッケージ php5-json を選択しています。
(データベースを読み込んでいます ... 現在 635170 個のファイルとディレクトリがインストールされています。)
Preparing to unpack .../php5-json_1.3.2-2build1_amd64.deb ...
Unpacking php5-json (1.3.2-2build1) ...
以前に未選択のパッケージ php5-common を選択しています。
Preparing to unpack .../php5-common_5.5.9+dfsg-1ubuntu4.7_amd64.deb ...
Unpacking php5-common (5.5.9+dfsg-1ubuntu4.7) ...
以前に未選択のパッケージ php5-fpm を選択しています。
Preparing to unpack .../php5-fpm_5.5.9+dfsg-1ubuntu4.7_amd64.deb ...
Unpacking php5-fpm (5.5.9+dfsg-1ubuntu4.7) ...
Processing triggers for ureadahead (0.100.0-16) ...
ureadahead will be reprofiled on next reboot
Processing triggers for man-db (2.6.7.1-1ubuntu1) ...
php5-common (5.5.9+dfsg-1ubuntu4.7) を設定しています ...

Creating config file /etc/php5/mods-available/pdo.ini with new version
php5_invoke: Enable module pdo for fpm SAPI

Creating config file /etc/php5/mods-available/opcache.ini with new version
php5_invoke: Enable module opcache for fpm SAPI
php5-fpm (5.5.9+dfsg-1ubuntu4.7) を設定しています ...

Creating config file /etc/php5/fpm/php.ini with new version
php5_invoke pdo: already enabled for fpm SAPI
php5_invoke opcache: already enabled for fpm SAPI
php5-fpm start/running, process 10089
php5-json (1.3.2-2build1) を設定しています ...
php5_invoke: Enable module json for fpm SAPI
Processing triggers for ureadahead (0.100.0-16) ...

これでインストール完了。

php-fpmのsocketを変更

/etc/php5/fpm/pool.d に www.conf というファイルがある。これを編集…と思ったら、すでにソケットを利用する設定になっていた。

listen = /var/run/php5-fpm.sock

なので、変更なし。変更してないので、すでにソケットがあるはず。

takatoh@nightschool $ ls /var/run
NetworkManager  lock                        sendsigs.omit.d
acpid.pid       motd.dynamic                shm
acpid.socket    mount                       sshd
alsa            network                     sshd.pid
atd.pid         network-interface-security  systemd
avahi-daemon    nginx.pid                   udev
crond.pid       php5-fpm.pid                udisks2
crond.reboot    php5-fpm.sock               upstart-file-bridge.pid
cups            plymouth                    upstart-socket-bridge.pid
dbus            pm-utils                    upstart-udev-bridge.pid
initramfs       pppconfig                   user
kerneloops.pid  resolvconf                  utmp
lightdm         rsyslogd.pid                wpa_supplicant
lightdm.pid     sdp

php5-fpm.sock というのがそうだ。

Nginxの設定を変更

昨日作ったデフォルトホストの設定ファイル(/etc/nginx/sites-available/nightschool)を編集して、以下を追加する。

# For PHP
location ~ \.php$ {
    root /var/www/html;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Nginx に設定を反映。

takatoh@nightschool $ sudo nginx -s reload

PHPファイルを作成

/var/www/html の中に phpinfo.php を作成。

<!--?php
  phpinfo();
?-->

ブラウザで確認

phpinfo

http://localhost/phpinfo.php にアクセスすると次のようになった。

めでたく完了。

Nginxにデフォルトのバーチャルホストを設定する

家庭内 LAN 向けにバーチャルホストをたてようというのが動機。現状では、サーバに HTTP でアクセスすると Sinatra アプリが応答してしまっていた。
設定方法は↓このページが参考になった。

 cf. nginxでデフォルトのバーチャルホストを設定する方法 – Linux入門

答えは簡単で、listen ディレクティブに default_server と書き足すだけでいい。これがないと、最初に読み込まれたバーチャルホストがデフォルトになるので、今まで Sinatra アプリのサーバが応答していたってわけだ。

/etc/nginx/sites-available に nightschool という名前で設定ファイルを作って、/etc/nginx/sites-enabled 以下にシンボリックリンクを作成。作った設定ファイルはこれ。

server {
    # port
    listen 80 default_server;

    # server name
    server_name nightschool;

    # document root
    root /var/www/html;

    # index
    index index.php index.html index.htm;

    # log files
    access_log /var/log/nginx/nightschool/access.log combined;
    error_log /var/log/nginx/nightschool/error.log warn;
}

ドキュメントルートとログファイルのためのディレクトリを作って、ドキュメントルートには index.html ファイルをおいた。

<html>
  <body>
    <h1>Hello, welcome!</h1>
    This is nightschool.
  </body>
</html>

あとは Nginx を再起動して完了。

takatoh@nightschool $ sudo service nginx stop
takatoh@nightschool $ sudo service nginx start

確認のために Windows PC からアクセスしたところ、ちゃんと index.html の内容が表示された。

default-vhost

Windows7のhostsファイルに書き込む方法

hosts ファイルは C:\Windows\System32\drivers\etc にあるんだけど、普通にやったんでは権限がないとか言われて保存できない。管理者権限を持ったユーザーでも。

どうやるのか調べた結果、次のとおりにする。

  1. スタートメニューから、メモ帳を「管理者として実行」
  2. メモ帳のファイルメニューから hosts ファイルを開く
  3. 編集して上書き保存

このやり方だとちゃんと保存できる。

Nginx+Unicorn:静的ファイルをNginxで配信しようとしてハマった

目的

Nginx + Unicorn でアプリを動かしている状態で、/static 以下の URL に対するリクエストだけ /var/www/html_doc から配信したい。

ダメだった設定

ググっていくつかのページを参照しながら、次のように location ディレクティブを設定した。

location /static {
    root /var/www/html_doc/;
    break;
}

これだとうまくいかない。

原因と解決

error.log を見てみると、/static/path/to/file.html にアクセスした時に /var/www/html_doc/static/path/to/file.html を探しているのが分かった。どうも URL の一部である /static は置き換えてくれるわけじゃないらしい。
というわけで、下のように自前で rewrite したらうまくいった。

location /static {
    root /var/www/html_doc/;
    rewrite '^/static(.*)$' $1;
    break;
}

Rubyでクイックソート

cf. RubyでクイックソートとRSpecでそのテストを書いてみる – 凸ろぐ

なんだかまどろっこしい書き方をしてるなあ。これでいいんじゃないか?

require 'benchmark'

class Array
  def qsort
    return self if self.size <= 1
    pivot = self.shift
    left = self.select{|x| x < pivot }
    right = self.select{|x| pivot <= x }
    return left.qsort + [pivot] + right.qsort
  end
end

ary = [1,2,3,4,5,6,7,8,9,10].shuffle
ary2 = ary.dup

Benchmark.bm(13) do |x|
  x.report("Array#sort: ") { ary.sort }
  x.report("Array#qsort:") { ary2.qsort }
end
takatoh@nightschool $ ruby qsort.rb
                    user     system      total        real
Array#sort:     0.000000   0.000000   0.000000 (  0.000006)
Array#qsort:    0.000000   0.000000   0.000000 (  0.000013)

Array#soft 速いな。やっぱり自前で作るよりあるものを使ったほうがいいってことか。
いや、リンク先の実装だと速いのか?

require 'benchmark'

class Array
  def qsort
    return self if self.size <= 1
    mark = self[0]
    right = Array.new
    left = Array.new
    (1..self.size-1).each do |i|
      if self[i] <= mark
        left.push(self[i])
      else
        right.push(self[i])
      end
    end
    left = left.qsort
    right = right.qsort
    return left + [mark] + right
  end
end

ary = [1,2,3,4,5,6,7,8,9,10].shuffle
ary2 = ary.dup

Benchmark.bm(10) do |x|
  x.report("Array#sort: ") { ary.sort }
  x.report("Array#qsort:") { ary2.qsort }
end
takatoh@nightschool $ ruby qsort2.rb
                 user     system      total        real
Array#sort:   0.000000   0.000000   0.000000 (  0.000006)
Array#qsort:  0.000000   0.000000   0.000000 (  0.000019)

そんなことはなかった。

100から1まで表示するコードすら書けないプログラマ

cf. 100から1まで表示するコードすら書けないプログラマ – 新・日々録 by TRASH BOX@Eel

詳しくはリンク先を読んでもらうとして、100から1まで表示するだけのプログラムを10分たっても書けないプログラマが14%もいたという調査結果があるんだそうだ。話の雰囲気からして職業プログラマの話だろうに、FizzBuzz の話もそうだけど、こんな簡単なプログラムも書けなくて普段どうやって仕事してるんだろう?

それはともかくとして、リンク先にはいくつかの言語で書いたコードがあるけど、JavaScript がないので書いてみた。そしたら、一発じゃできなかったよ…orz。というのが今日のオチ。
以下、恥を晒しておく。

最初に書いたのがこれ。

for var i = 100, i < 0, i-- {
  console.log(i);
}

実行してみると:

takatoh@nightschool $ node countdown.js

/home/takatoh/w/nodejs/countdown.js:1
(function (exports, require, module, __filename, __dirname) { for var i = 100,
                                                                  ^^^
SyntaxError: Unexpected token var
    at Module._compile (module.js:439:25)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

ああ、for のあとには括弧がいるんだっけ。

for (var i = 100, i < 0, i--) {
  console.log(i);
}

今度はいいだろう。

takatoh@nightschool $ node countdown2.js

/home/takatoh/w/nodejs/countdown2.js:1
orts, require, module, __filename, __dirname) { for (var i = 100, i > 0, i-- )
                                                                    ^
SyntaxError: Unexpected token >
    at Module._compile (module.js:439:25)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

おおい、どういうこった。
眺めてもわからないので Google 先生に聞くことに。そしたら、for の初期値とか終了条件とかはカンマじゃなくてセミコロンで区切るんだった。ああ、まだ身についてないな。というか、普段書いてる Ruby やら Python じゃこういう for ループ書かないからなあ(言い訳)。
というわけで、最終的にはこれで正解。

for (var i = 100; i < 0; i--) {
  console.log(i);
}