wiki:HowTo/SakuraVpsSetup3b

Version 4 (modified by 村山 俊之, 5 years ago) ( diff )

--

さくらの VPS セットアップメモ 〜2G プラン据え置き Ubuntu16.04 入れ替え編 (パート2)〜

パート1 からの続きです…。

Web サーバー設定ふたたび (Nginx 移行)

最近は割といろんなものが Nginx で動くっぽいですね (というより大抵 FastCGI でどうにかするっぽい)。一度触ってみておきたかったというのもあるのですが、 Apache のモジュールモデルに若干疲れたというのもあり…。

で、構成を単純化するため、全般的に Nginx で動かす想定で、まずは Apache2 を削除してしまうことにしました。上の方で書いた内容が全て無駄になりますが… (((((((;/^o^)/

$ sudo su -
# apt remove apache2
# apt install nginx

MySQL は代わりに mariadb をインストール済みなので不要ですね。手元 PC の HOSTS 書き換えでとりあえず Nginx がちゃんと動いているのは確認。

SSL 設定

たまたまこの時点で Let's Encrypt による mail.harapeko.jp ドメインが証明期限切れ近かったので、 certbot-auto を実行。なお Apache から Nginx に環境を換えた影響か、この時点では ./certbot-auto renew はうまく動かなかった。

# exit
$ cd ~/certbot
$ ./certbot-auto
Requesting to rerun ./certbot-auto with root privileges...

(中略... 何故か名前の設定が見つからんと言われるのでドメイン名を入力)
No names were found in your configuration files. Please enter in your domain
name(s) (comma and/or space separated)  (Enter 'c' to cancel): mail.harapeko.jp 
Cert is due for renewal, auto-renewing...

(中略... どうやら Apache を使う場合と Nginx を使う場合とで設定を残す場所が異なる模様)
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/default

(ここからおせっかい機能が走り出す... せっかくなので HTTPS へリダイレクトする設定を施してもらった)
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/default

(残りの出力は略... どうやらうまくいったようだ)
$ 

実際 http://mail.harapeko.jp/ にアクセスすると https://mail.harapeko.jp/ にリダイレクトされるようになった。メーラーも問題なく動いている模様。

certbot による Nginx の設定の変更は /etc/nginx/sites-available/default に対して行われた模様。

メインコンテンツ

/etc/nginx/sites-available/default の設定内容によれば、メインコンテンツは /var/www/html を参照している模様。ここに配置すれば良いはず。 (以下、コメント行の類は概ね省略しています)

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                try_files $uri $uri/ =404;
        }
}

既に当該ディレクトリには旧会社時代のコンテンツを置いていたものの、 PHP 駆動だったので index.html は置いておらず、 http://www.harapeko.jp/ としてアクセスすると nginx のデフォルトページが表示される状態でした。試しに index.html を配置してみたところ、それが代わりに表示されるようになりました。

と、ここで https://mail.harapeko.jp/ にアクセスしてみたら同じものが表示される状態だったので、こちらは別のファイルが表示されるよう設定を修正。

server {
        root /var/www/vhosts/mail/html; # <--- ここを修正

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;
    server_name mail.harapeko.jp; # managed by Certbot

        location / {
                try_files $uri $uri/ =404;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mail.harapeko.jp/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mail.harapeko.jp/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

当該ディレクトリを作成し、 index.html も別途作成したところ、そちらが表示されるようになりました。

メインサイトの名前解決

サブドメイン www を新サーバーに切り替えます。ついでなのでこのタイミングでネームサーバーの切り替えも行ってしまうことにします。

まずは旧サーバー側のネームサーバーで www の IP アドレスを新サーバーに向くように変更。

# vim /var/named/chroot/var/named/harapeko.jp.zone

(...設定を修正)

# service named restart
$TTL    1D
@               IN      SOA     onaka.harapeko.jp. root.onaka.harapeko.jp. (
                        2019102101      ; serial
                        3600            ; refresh 1h
                        900             ; retry 15m
                        3600000         ; expiry 1000h
                        3600            ; minimum 24h
                )
;
                IN      NS      ns.harapeko.jp.
                IN      MX      0 mail.harapeko.jp.
mail            IN      MX      0 mail.harapeko.jp.
onaka           IN      A       49.212.128.142
ns              IN      A       49.212.128.142
mail            IN      A       153.126.157.107
www             IN      CNAME   mail    ; <--- 現状新サーバー用に使っている mail サブドメインを参照するよう変更
daiyokujo       IN      CNAME   onaka   ; for harapeko.asablo.jp/blog
blog            IN      CNAME   onaka
developer       IN      CNAME   onaka
svn             IN      CNAME   onaka
test            IN      CNAME   onaka

すぐには反映されない模様。やっぱりしばらくは待つ必要があるか…。

新サーバーの設定もやってしまうことにした。 chroot で動かすつもりだったが、うまく動かせなかったので、一旦 chroot を使わない設定を施しました。 chroot を使う設定についてはこの辺のサイトにまとまっているようなので、後ほど再チャレンジしてみることにします。

設定に際しては、この辺の記事を参考にさせていただきました…。

設定対象ファイルをまるっと編集してしまいましょう。

# cd /etc/bind
# vim -p named.conf

named.conf は他の設定ファイルを include しているだけですが、そのうち、デフォルトゾーンの設定を記述した named.conf.default-zones は権威 DNS サーバーを設定するなら不要なので、コメントアウトしてしまいます。

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
//include "/etc/bind/named.conf.default-zones";  // <--- 不要

named.conf.options では notify norecursion no を追記、 auth-nxdomainyes に変更しました。

options {
        directory "/var/cache/bind";

        //========================================================================
        // If BIND logs error messages about the root key being expired,
        // you will need to update your keys.  See https://www.isc.org/bind-keys
        //========================================================================
        dnssec-validation auto;

        //auth-nxdomain no;    # conform to RFC1035
        auth-nxdomain yes;     // <--- ドメインが存在しない場合の応答時に AA ビットを必ず立てる設定。いちおう。
        listen-on-v6 { any; };

        notify no;     // <--- ゾーンデータの更新通知はデフォルトで no にしておき、個別のゾーンに対して yes に設定する。
        recursion no;  // <--- 自分がマスターではないゾーンについてのクエリーを、再帰的に問い合わせしない設定。権威 DNS サーバーの場合は必須。
};

named.conf.local はコメントアウトされている zones.rfc1918 を include するの ではなく 、独自に作成するファイル zones.harapeko.jp を include するようにします。

// Consider adding the 1918 zones here, if they are not used in your
// organization
// include "/etc/bind/zones.rfc1918";   // <--- これはこのまま
include "/etc/bind/zones.harapeko.jp";  // <--- こっちを追記

そして新たに :tabe zones.harapeko.jp して、以下の内容を書いて保存。

zone "harapeko.jp" {
    type master;
    file "/var/cache/bind/harapeko.jp.zone";
    notify yes;
};
zone "107.157.126.153.in-addr.arpa" {
    type master;
    file "/var/cache/bind/harapeko.jp.rev";
    notify yes;
};

実際の正引き・逆引きファイルも作成します。

# cd /var/cache/bind
# vim harapeko.jp.zone

(...正引きファイル編集)

# vim harapeko.jp.rev

(...逆引きファイル編集)

正引きファイルは旧サーバーからコピったものを一部編集。

$TTL    1D
@               IN      SOA     onaka.harapeko.jp. root.onaka.harapeko.jp. (
                        2019102102      ; serial
                        3600            ; refresh 1h
                        900             ; retry 15m
                        3600000         ; expiry 1000h
                        3600            ; minimum 24h
                )
;
harapeko.jp     IN      NS      ns.harapeko.jp.    ; <-- このへんちょこっと書き方を変えてみた
harapeko.jp     IN      MX  0   mail.harapeko.jp.  ; <--
onaka           IN      A       49.212.128.142
ns              IN      A       153.126.157.107    ; <---- レジストラに登録するネームサーバーを新サーバーに切り替えた想定
mail            IN      A       153.126.157.107
www             IN      CNAME   mail
daiyokujo       IN      CNAME   onaka   ; for harapeko.asablo.jp/blog
blog            IN      CNAME   onaka
developer       IN      CNAME   onaka
svn             IN      CNAME   onaka
test            IN      CNAME   onaka

逆引きファイルはまんまコピってシリアル番号だけ書き換えただけなので略。

あとは bind9 を登録、再起動すれば ok 。

# systemctl enable bind9
# service bind9 restart
# nslookup ns.harapeko.jp localhost
Server:         localhost
Address:        ::1#53

Name:   ns.harapeko.jp
Address: 153.126.157.107

# 

旧サーバーで設定した www サブドメインの参照先変更はこの時点でとっくに反映されていましたが、せっかくなので JPDirect のホスト登録も変更します。 サイトログイン後、「ドメイン名共通 > ホスト情報変更申請」を選択し、ホスト名に「NS.HARAPEKO.JP」と入力 (ドロップメニューによる選択肢ではありません)。新しい IP アドレスを入力して完了。

www の SSL を設定

ふつうに certbot を動かすだけでいいはず。これは root からではなく一般ユーザーから。

$ ./certbot-auto -d www.harapeko.jp
Requesting to rerun ./certbot-auto with root privileges...

(中略 ...HTTP アクセス検証)
Performing the following challenges:
http-01 challenge for www.harapeko.jp
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/default

(おせっかい機能のリダイレクト設定)
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/default

(どうやら成功したらしい)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://www.harapeko.jp

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=www.harapeko.jp
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

(後略...認証鍵の在り処などの情報が表示されます)

murachi@ik1-314-17353:~/certbot$ 

certbot による HTTPS へのリダイレクト設定は、 /etc/nginx/sites-available/default にひたすら追記する形で施されるらしい。 あとで手でファイルを分けたほうが良いかもしれんね(´・_・`)

ブログの稼働と名前解決

ブログの引っ越し自体は済んでいるので、 PHP を動かせるようにして名前解決と SSL 化までやってしまいましょう。

ちなみに今更ですが、 /etc/nginx/nginx.conf を確認すると、ユーザーは apache2 の場合と同じ www-data で動いているようですね。

user www-data;
worker_processes auto;
pid /run/nginx.pid;

さて、 PHP を FastCGI で動かすため、 php-fpm パッケージを導入します。

# apt install php-fpm

Nginx の設定にブログドメイン用の設定を追加します。まず /etc/nginx/sites-available/blog-wp を作成。

# cd /etc/nginx/sites-available
# vim blog-wp

内容は、いくつかのサイトを参考にさせていただいた結果、以下の通りになりました。この時点ではまだ SSL は考慮していません。

server {
  listen 80;
  server_name blog.harapeko.jp;

  location / {
    root /var/www/vhosts/blog/html;
    index index.php;
    try_files $uri $uri/ @wordpress;  # パーマリンクのための設定
  }

  location ~* /wp-config.php {
    deny all;
  }

  location ~ \.php$ {
    root /var/www/vhosts/blog/html;
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
  }

  # パーマリンク URI の場合、 index.php を使うようにする
  location @wordpress {
    root /var/www/vhosts/blog/html;
    fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    include fastcgi_params;
  }

  location ~ /\.ht {
    deny all;
  }
}

で、これのシンボリックリンクを /etc/nginx/sites-enabled の下に作ります。

# cd ../sites-enabled
# ln -s ../sites-available/blog-wp

PHP の FastCGI 用の設定ファイル /etc/php/7.0/fpm/pool.d/www.conf については、 Nginx のユーザーを www-data のまま変更していないため、こちらも特に変更すべき点はありません。 (この辺、 Apache2 と併用して動かす場合なんかはユーザーを別途作って区別したほうが良いのかもしれません)

PHP-FPM をサービス登録し、 Nginx と共に再起動すれば準備完了です。

# systemctl enable php7.0-fpm
Synchronizing state of php7.0-fpm.service with SysV init with /lib/systemd/systemd-sysv-install...
Executing /lib/systemd/systemd-sysv-install enable php7.0-fpm
# service php7.0-fpm restart
# service nginx restart

ローカルマシンの /etc/hosts を書き換えてアクセスしてみたところ、ちゃんとブログが動いているのを確認できました。

名前解決は /var/cache/bind/harapeko.jp.zone を書き換えて bind9 を restart させるだけです。 blog サブドメインの CNAME 先を mail に切り替えるだけなのでこれは流石に略。

ローカルマシンからサブドメイン名で新サーバーにアクセスできることを確認後、一般ユーザーから certbot-auto を実行し、 blog サブドメインも SSL 化。これも他のサブドメインの場合とやってることは変わらないので略。なお、 https へのリダイレクト設定もやってもらったところ、ちゃんとよしなに /etc/nginx/sites-available/blog-wp に対して設定を施してくれた。ホント便利 (´・_・`)

大浴場の画像等

まだファイルを移動してなかったですね。空っぽの perl ディレクトリはおいら自身用途を覚えていないので (^_^;、とりあえずスタティックファイルだけガッと移動します。

まず新サーバー側で場所を用意。

# mkdir -p /var/www/vhosts/daiyokujo/html
# chown murachi:www-data /var/www/vhosts/daiyokujo/html

新サーバーに旧サーバーへアクセスするための秘密鍵は持ってきていないので、旧サーバーから新サーバーへ rsync 。

$ cd /var/www/vhosts/daiyokujo/htdocs
$ rsync -ae ssh * murachi@mail.harapeko.jp:/var/www/vhosts/daiyokujo/html/
Enter passphrase for key '/home/murachi/.ssh/id_rsa': 
$ 

新サーバー側でコピーされたファイルの所有権が murachi:murachi になっちゃっているのを murachi:www-data に修正。

$ cd /var/www/vhosts/daiyokujo/html
$ sudo chown -R murachi:www-data *

/etc/nginx/sites-available/daiyokujo を作成。

$ sudo su -
# cd /etc/nginx/
# vim sites-available/daiyokujo

(...大浴場用ファイル置き場の設定を記述)

# cd sites-enabled/
# ln -s ../sites-available/daiyokujo
# service nginx restart

内容は以下の通り。

server { 
  listen 80;
  listen [::]:80;
  
  root /var/www/vhosts/daiyokujo/html;
  index index.html index.htm;
  server_name daiyokujo.harapeko.jp;
  
  location / {
    try_files $uri $uri/ =404;
  }
}

後は名前解決と SSL 化。この辺は略。

Trac 設定

Trac インストールしてから大分時間が経っているので、 Python モジュール関連を一通り最新に upgrade してしまうことにします。

$ sudo su -
# pip install --upgrade pip
# pip list --outdated --format=freeze | perl -pe 's/^(.+?)==(.+)$/$1/' | xargs pip install --upgrade

かなり強引ですが…。

最後の最後に

OSError: [Errno 2] No such file or directory: '/usr/local/lib/python2.7/dist-packages/Trac-1.2.3-py2.7.egg'

とかいうエラーが出ちゃいましたが、その後 pip list --outdated しても何も出てこないので、まぁ良しとします。

ていうかリスト確認したら Trac が 1.4 になってる…。

# pip list

(2.7系は 2020年からはサポート無くなるぜという警告メッセージは略)

Package           Version
----------------- -------
Babel             2.7.0  
docutils          0.15.2 
Genshi            0.7.3  
Jinja2            2.10.3 
MarkupSafe        1.1.1  
MySQL-python      1.2.5  
pip               19.3.1 
Pygments          2.4.2  
pytz              2019.3 
setuptools        41.4.0 
Trac              1.4    
TracFootNoteMacro 1.6    
virtualenv        16.7.7 
wheel             0.33.6 
# 

いつの間に 1.4 がリリースされてたの… orz

そんなわけで ideanote を upgrade

# exit
$ cd /var/Developer/trac/original/ideanote
$ trac-admin .
Trac [/var/Developer/trac/original/ideanote]> upgrade
エラー: Unable to check for upgrade of trac.db.api.DatabaseManager: TracError: "mysql" データベースをサポートしていません
Trac [/var/Developer/trac/original/ideanote]> 

ひぇっ(´・_・`)

リリースノート見てみたら MySQL-python から PyMySQL に乗り換えていらっさった模様…(´・_・`)

$ sudo pip install PyMySQL

(...インストール)

$ trac-admin .
trac-admin 1.4 へようこそ
Trac 管理コンソール(対話モード)です。
Copyright (C) 2003-2019 Edgewall Software

'?' コマンドか 'help' コマンドでヘルプを表示します。
        
Trac [/var/Developer/trac/original/ideanote]> upgrade
アップグレードが失敗しました。問題を解消させてもう一度試してください。

TracError: すべてのテーブルは照合順序として utf8_bin または utf8mb4_bin で作成されている必要があります。次のテーブルがその照合順序で作成されていません: attachment, auth_cookie, cache, component, enum, milestone, node_change, permission, report, repository, revision, session, session_attribute, system, ticket, ticket_change, ticket_custom, version, wiki
Trac [/var/Developer/trac/original/ideanote]> 

あー、前回中断したときと同じエラーまでたどり着きました(´・_・`)

えーっと。こんな感じかな。

$ cd
$ echo attachment, auth_cookie, cache, component, enum, milestone, node_change, permission, report, repository, revision, session, session_attribute, system, ticket, ticket_change, ticket_custom, version, wiki >trac_tables.txt
$ perl -e '$l=<>; chomp $l; @t=split /\s*,\s*/, $l; print "alter table $_ collate utf8mb4_bin;\n" for @t' trac_tables.txt > trac_tables_mod_u8b.sql
$ mysql -u trac_master -pパスワード trac_ideanote < trac_tables_mod_u8b.sql

これでどうか。

$ cd /var/Developer/trac/original/ideanote/
$ trac-admin .
trac-admin 1.4 へようこそ
Trac 管理コンソール(対話モード)です。
Copyright (C) 2003-2019 Edgewall Software

'?' コマンドか 'help' コマンドでヘルプを表示します。
        
Trac [/var/Developer/trac/original/ideanote]> upgrade
アップグレードが失敗しました。問題を解消させてもう一度試してください。

TracError: データベースのキャラクタセットと照合順序が 'utf8' と 'utf8_general_ci' になっています。データベースは (('utf8', 'utf8_bin'), ('utf8mb4', 'utf8mb4_bin')) の1つでなければいけません。
Trac [/var/Developer/trac/original/ideanote]> 

(゚Д゚)ハァ?

そもそも今の DB の状態で utf8mb4 を選ぶべきではなかったかも(´・_・`) 'utf8', 'utf8_bin' の組み合わせで行きますか(´・_・`)

$ cd
$ perl -e '$l=<>; chomp $l; @t=split /\s*,\s*/, $l; print "alter table $_ collate utf8_bin;\n" for @t' trac_tables.txt > trac_tables_mod_u8b.sql
$ mysql -u trac_master -pパスワード trac_ideanote < trac_tables_mod_u8b.sql
murachi@ik1-314-17353:~$ sudo mysql -u root
[sudo] murachi のパスワード: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 6829
Server version: 10.0.38-MariaDB-0ubuntu0.16.04.1 Ubuntu 16.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> alter database trac_ideanote collate utf8_bin;
Query OK, 1 row affected (0.01 sec)

MariaDB [(none)]> Bye
$

今度こそどうだ…

$ cd /var/Developer/trac/original/ideanote/
$ trac-admin .
trac-admin 1.4 へようこそ
Trac 管理コンソール(対話モード)です。
Copyright (C) 2003-2019 Edgewall Software

'?' コマンドか 'help' コマンドでヘルプを表示します。
        
Trac [/var/Developer/trac/original/ideanote]> upgrade
レポート 1, 2, 3, 4, 5, 7, 8 をアップグレードできなかったため
"ambiguous column name" エラーが起きないように手動で変更する必要が
あるかも知れません。
詳細は https://trac.edgewall.org/wiki/1.3/TracUpgrade#enum-description-field を参照してください。

アップグレードが終了しました。

次のコマンドを実行すると Trac のドキュメントをアップグレードできます:

  trac-admin "/var/Developer/trac/original/ideanote" wiki upgrade
Trac [/var/Developer/trac/original/ideanote]> 

一部で失敗しているみたいですが、とりあえずアップグレードを完了させられました。

さて、ここまでやったところで Trac リポジトリの所有者が murachi:murachi になっちゃっていたことに気づいたので、所有者を変更。

$ cd /var/Developer/
$ sudo chown -R murachi:www-data trac
$ sudo chmod g+s trac

リポジトリの準備が出来たと思うので、 uWSGI を使って動かしてみることにします。 uWSGI に関しては以下のサイトを参考にさせていただいています。

uWSGI をインストール。 pip で入れちゃいましょう。

$ sudo su -
# pip install uWSGI
Collecting uWSGI
  Downloading https://files.pythonhosted.org/packages/e7/1e/3dcca007f974fe4eb369bf1b8629d5e342bb3055e2001b2e5340aaefae7a/uwsgi-2.0.18.tar.gz (801kB)
     |████████████████████████████████| 808kB 2.1MB/s 
Building wheels for collected packages: uWSGI
  Building wheel for uWSGI (setup.py) ... done
  Created wheel for uWSGI: filename=uWSGI-2.0.18-cp27-cp27mu-linux_x86_64.whl size=519527 sha256=0e76554e1428e185c0ccb066bb4afaeac1c3c97da5af73c127dd86ccc531f89a
  Stored in directory: /root/.cache/pip/wheels/2d/0c/b0/f3ba1bbce35c3766c9dac8c3d15d5431cac57e7a8c4111c268
Successfully built uWSGI
Installing collected packages: uWSGI
Successfully installed uWSGI-2.0.18
# 

WSGI ファイルは既にあるので、 uwsgi コマンドを使えば適当なポートで動作確認できるはず。動作確認用に穴を開けますか。

# cd
# vim -p ip*tables.sh

(両方とも編集...)

# ./iptables.sh
# ./ip6tables.sh
# service netfilter-persistent save
# service netfilter-persistent reload

iptables.ship6tables.sh は以下の通りに穴を開けたいポート番号を追記するだけ。

#/sbin/ip6tables -A INPUT -p tcp -m state --state NEW -m multiport --dports 22,25,587,993,80,443 -j ACCEPT
/sbin/ip6tables -A INPUT -p tcp -m state --state NEW -m multiport --dports 22,25,587,993,80,443,6543 -j ACCEPT

uwsgi を実行してみます。

# exit
$ cd /var/Developer/trac/original
$ uwsgi --http=0.0.0.0:6543 --wsgi-file=trac-original.wsgi --callable=application

http://mail.harapeko.jp:6543/ideanote にアクセスしてみたところ、それっぽい画面が表示されました。ちなみに --callable 引数に指定するのは実際の WSGI ファイルが caller として用意しているオブジェクト名 (関数名) で良いみたいです。

uWSGI の動作確認は出来たので、これを Nginx 経由で動かせるように設定していきます。まずは uwsgi のパラメータを定義するファイルを /var/Developer/trac/original/trac-original.ini に作成します。

$ vim trac-original.ini

内容としては以下の通りになりました。

[uwsgi]
uid = www-data
gid = www-data

current_release = /var/Developer/trac/original
chdir = %(current_release)

#wsgi-file = %(current_release)/trac-original.wsgi
mount = /trac/original=%(current_release)/trac-original.wsgi
callable = application
manage-script-name = true
socket = /var/Developer/trac/run/uwsgi-original.sock
pidfile = /var/Developer/trac/run/uwsgi-original.pid
chmod-socket = 666
vacuum = true

daemonize = /var/Developer/trac/log/uwsgi-original.log
log-reopen = true
log-maxsize = 5242880
logfile-chown = on
logfile-chmod = 644

processes = 1
threads = 4
max-requests = 500
max-requests-delta = 300
master = true

軽く解説入れます。

uwsgi コマンドを実行するときのカレントディレクトリにしたいディレクトリを指定したい場合、 current_release にそのディレクトリパスを指定し、それと同じ値を chdir にも指定すれば良いようです。

wsgi-file パラメータを指定する代わりに mount パラメータを使用しています。これを使うと、実際に公開するときの URL prefix を指定できます。 Idea note は http(s)://developer.harapeko.jp/trac/original/ideanote として公開したいので、 prefix に /trac/original を指定しています。

mount パラメータは複数指定できるらしいので、同じ場所に複数アプリを置いて同時に公開するような書き方もできるっぽいです。

manage-script-name は URI prefix を uWSGI 側で管理するかどうかを決めるパラメータで、 true を指定すると、リクエストに渡された URL から mount に指定した prefix を取り除いた値を URL としてアプリに渡すようになります。例えば /trac/original/ideanote/wiki/HowTo という URL でリクエストされた場合、これを /ideanote/wiki/HowTo に置き換えた値がアプリに渡されます。これを実現するために Nginx 側の設定を工夫する方法もあるのですが (location を正規表現指定にして抜き出したい部分をキャプチャし、 SCRIPT_NAMEPATH_INFO を指定する)、今回はこの方法で書いてみました。

HTTP の公開は Nginx に任せるので、 Nginx との通信のために UNIX socket だけを公開します。それを指定するのが socket パラメータです。 pidfile パラメータはプロセス ID を書き出すファイルで、デーモン実行した uWSGI プロセスを閉じるのに必要になるものです。 vacuum = true を指定しておくと、デーモンを開く際にソケットファイルや PID ファイルが残っていても、ちゃんとクリアしてから起動してくれるようになります。

deamonize パラメータを指定すると、 uWSGI はデーモンモードで起動するようになります。パラメータには実行中のログを吐き出すファイル名を指定します。 master パラメータはマスタープロセスを持つべきか否かを指定するもので、デーモン実行する場合は通常 true を指定するものらしいです (この辺に詳しい解説がありました)。

重要そうなのはそんなところでしょうか。

Unix ソケットと PID ファイルを置くディレクトリと、ログファイルを吐き出すディレクトリを用意します。これらのディレクトリはオーナーが murachi:www-data になるので、グループに書き込み権限を与えておきます。

$ cd ..
$ mkdir run
$ mkdir log
$ chmod g+w run log

uWSGI の準備は整ったので、とりあえず動かしておきましょう。

$ cd original/
$ uwsgi --ini trac-original.ini

デーモンモードで動くので、すぐにシェルに処理が返されます。先程作った run ディレクトリの下にソケットファイルと PID ファイルが生成されているのが確認できます (そのへんは省略)。

Nginx の設定も施しましょう。 /etc/nginx/sites-available/developerdeveloper.harapeko.jp サブドメイン用の設定を作成します。

$ sudo su -
# cd /etc/nginx/
# vim sites-available/developer

(設定を記述...)

# cd sites-enabled/
# ln -s ../sites-available/developer

設定内容はとりあえず以下の通りです。(HTTPS 化は相変わらず certbot 任せ)

server {
  listen 80;
  listen [::]:80;

  root /var/www/vhosts/developer/html;
  index index.html index.htm;
  server_name developer.harapeko.jp;

  location /trac/original {
    include uwsgi_params;
    uwsgi_pass unix:/var/Developer/trac/run/uwsgi-original.sock;
  }

  location ~ ^/trac/original/[^/]+/login$ {
    include uwsgi_params;
    uwsgi_param REMOTE_USER $remote_user;
    uwsgi_pass unix:/var/Developer/trac/run/uwsgi-original.sock;
    auth_basic "trac authentication";
    auth_basic_user_file /var/Developer/trac/original/.htpasswd;
  }

  location / {
    try_files $uri $uri/ =404;
  }
}

当面 developer サブドメインを Idea Note 以外の用途で使う予定はないのですが、一応 /trac/original 以外のところにアクセスされた場合用にドキュメントルートも設定してあります。ファイルは用意していないので単に 404 になります。

Trac 用の設定としては、基本は単に UNIX ソケットとの通信設定を施すのみです。 uwsgi_params というのを include していますが、このファイルは pip install uWSGI した時点で /etc/nginx の下によしなに作られたようで (もしくは元からそこにあった?)、 uWSGI に渡す基本的なパラメータのデフォルト値が定義されています。

Trac ではログイン処理も施す必要があるので、ログイン用の URL にアクセスした場合に REMOTE_USER パラメータに基本認証されたユーザー名を渡す設定と、基本認証自体が動くようにする設定を追加しています。なお、 Nginx には Apache2 で使えていた Digest 認証には対応していません (対応させるにはパッチを使ってソースからコンパイルしてあげる必要がある)。元々 Digest 認証用のパスワードファイルがあって、それを使っていたのですが、今見たら昔仕事で共用していたユーザーの設定がそのまま残っていて、むしろこれは捨てたほうが良いなと思ったので、基本認証に切り替えて済ませることにしました (SSL を使うつもりなので問題はないはず)。

ドキュメントルートを作っていなかったので用意します。

# mkdir -p /var/www/vhosts/developer/html
# chown murachi:www-data /var/www/vhosts/developer/html

それから基本認証用のパスワードファイルも用意します。

# exit
$ cd /var/Developer/trac/original/
$ htpasswd -c .htpasswd murachi
New password: 
Re-type new password: 
Adding password for user murachi
$ 

Nginx を再起動します。

$ sudo service nginx restart

ローカルマシン上の /etc/hosts を書き換えて、所定の URL で Idea Note にアクセスできることが確認できました。

もはや動作確認用のポート開放は不要なので、 iptables の設定をもとに戻しておきましょう。

$ sudo su -
# vim ip*tables.sh

(ポート 6543 を含まない設定に戻す)

# ./iptables.sh
# ./ip6tables.sh
# service netfilter-presistent save
# service netfilter-presistent reload

名前解決と SSL の設定も施します。これは略。

さて、 uWSGI はデーモンとして動いてはいますが、サーバーを再起動した場合に自動で起動する設定にはなっていません。最後にその設定を施しておくことにします。

Note: See TracWiki for help on using the wiki.