Gem in a Boxでオレオレgemサーバをたてる

自分でしか使わない、外部には公開できないような gem がいくつかあるので、gem サーバをたてることにした。Gem in a Box (geminabox)は、プライベートな gem サーバだ。gem コマンドでインストールして、ちょっと設定ファイルを書くだけで使えるようになる。

じゃ、いってみよう。

環境

  • Ubuntu 16.04 LTS
  • Ruby 2.3.1p112

インストールと設定

前述したように gem コマンドでインストールできる。

takatoh@wplj $ sudo gem install geminabox

~/geminabox ディレクトリを作って、設定ファイルを書く。

takatoh@wplj $ mkdir ~/geminabox
takatoh@wplj $ cd ~/geminabox
takatoh@wplj $ vim config.ru

設定ファイルはこんな感じ、っていうかこれだけ。

require "geminabox"

Geminabox.data = "/home/takatoh/geminabox/data"
run Geminabox::Server

gem ファイルが格納される data ディレクトリを作る。

takatoh@wplj $ mkdir data

これで Gem in a Box 自体のインストールと設定は完了。

Supervisord で管理

さて、これをデーモンにする必要があるんだけど、昨日 Supvervisord を試したので今日も同じようにしてみる。設定ファイル /etc/supervisord.d/geminabox.ini をつぎのように書いた。

[program:geminabox]
command=/usr/local/bin/rackup -p 9999
process_name=geminabox
user=takatoh
directory=/home/takatoh/geminabox
autostart=true
autorestart=true
stdout_logfile=/home/takatoh/geminabox/geminabox.log
stdout_logfile_maxbytes=1M
stdout_logfile_backups=7
stdout_capture_maxbytes=1M
redirect_stderr=true

これで OK のはず。動かしてみよう。

takatoh@wplj $ supervisorctl reload
Restarted supervisord
takatoh@wplj $ supervisorctl status
geminabox RUNNING pid 26835, uptime 0:00:08
sulaiman RUNNING pid 26836, uptime 0:00:08

ちゃんと動いてるようだ。

Nginxのバーチャルホスト設定

gembox というホスト名でアクセスできるように Nginx を設定する。/etc/nginx/sites-available/gembox が設定ファイルだ。

upstream geminabox {
    server 127.0.0.1:9999;
}

server {
    # port
    listen      80;

    # server name
    server_name gembox;

    # document root
    root        /home/takatoh/geminabox;

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

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

    keepalive_timeout     60;
    proxy_connect_timeout 60;
    proxy_read_timeout    60;
    proxy_send_timeout    60;

 
    location / {
        proxy_set_header Host $http_host;
        proxy_pass http://geminabox;
    }
}

/etc/nginx/sites-enabled/gembox にリンクをはる。

takatoh@wplj $ sudo ln -s /etc/nginx/sites-available/gembox sites-enabled/gembox

ログファイル用のディレクトリを作成。

takatoh@wplj $ sudo mkdir /var/log/nginx/gembox

そして、Ngixn をリロード。

takatoh@wplj $ sudo systemctl reload nginx

これで完了。ほかのマシンからブラウザで http://gembox/ にアクセスすると、期待どおり Gem in a Box のページにアクセスできた。

[追記]

アクセスはできたけど、試しに gem ファイルを1つアップロードしてみたら「uninitialized constant Gem::Util」というエラーが出てしまった。なんだこりゃ?

[追記2]

解決編。rubygems 自体が古いのが原因だったようだ。

takatoh@wplj $ sudo gem update --system
takatoh@wplj $ gem -v
3.0.1

念のため、データ置き場を作りなおす。

takatoh@wplj $ cd ~/geminabox
takatoh@wplj $ rm -rf data
takatoh@wplj $ mkdir data

リスタート。

takatoh@wplj $ supervisorctl restart geminabox
geminabox: stopped
geminabox: started

これで無事、オレオレgemをアップロードできるようになった。

Supervisorで自作プログラムをデーモン化

自作のプログラムやスクリプトをデーモン化したい場合がある。でも、デーモンとして動作するようには作っていない……そういう時には Supervisor の出番だ。

Supervisor は Python 製のツールで、デーモンとして動作するように作られていないプログラムでもデーモン化できる。Supervisor 自体は root 権限でデーモンとして動かす必要があるけど、その下にぶら下がるプログラムはユーザー権限で管理できるのがいい点だ。

今日は、Ubuntu マシンの wplj に Supervisor をインストールして、以前 Go で作った画像アップローダを動かしてみる。

環境

  • Ubuntu 16.04 LTS
  • Python 2.7.12

Supervisorのインストールといろいろ下準備

Supervisor 自体は pip でインストールできる。

takatoh@wplj $ sudo pip install supervisor

/etc/supervisord.conf にデフォルトの設定ファイルを生成。

takatoh@wplj $ sudo echo_supervisord_conf > /etc/supervisord.conf
-bash: /etc/supervisord.conf: 許可がありません

あれ、sudo つけてるのになんでだ?よくわからないけど sudo -s してからやってみよう。

takatoh@wplj $ sudo -s
root@wplj # echo_supervisord_conf > /etc/supervisord.conf

今度はできた。つぎ、include 設定ファイル用のディレクトリを作成。

root@wplj # mkdir /etc/supervisord.d

supervisord 自体のはくログ周りの設定。デフォルトでは /tmp/supervisord.log に吐き出すことになっているので、設定ファイル /etc/supervisord.conf を修正して /var/log/supervisord.log に吐くようにする。

[supervisord]
;logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile=/var/log/supervisord.log

PID ファイルの設定。/var/run 以下に置くように変更。

;pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
pidfile=/var/run/supervisord.pid

/etc/supervisord.d 以下のファイルを include するように変更。これで設定ファイルの修正は終了。

[include]
files = supervisord.d/*.ini

supervisord自体のサービス登録

/etc/systemd/system/supervisord.service ファイルを作成する。

[Unit]
Description=Supervisor process control system for UNIX
Documentation=http://supervisord.org/
After=network.target

[Service]
ExecStart=/usr/local/bin/supervisord -n -c /etc/supervisord.conf
ExecStop=/usr/local/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/local/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=50s

[Install]
WantedBy=multi-user.target

起動と自動起動の登録

root@wplj # systemctl start supervisord
root@wplj # systemctl enable supervisord.service
Created symlink from /etc/systemd/system/multi-user.target.wants/supervisord.service to /etc/systemd/system/supervisord.service.

自作プログラムの配置

Go で作った画像アップローダ sulaiman を配置する。こんなふうにした。

takatoh@wplj $ tree ~/sulaiman
/home/takatoh/sulaiman
├── config.json
├── photos
│   ├── img
│   └── thumb
├── static
│   ├── css
│   │   └── style.css
│   ├── html
│   │   └── index.html
│   └── js
│   └── sulaiman.js
└── sulaiman

試しに動かしてみる。

takatoh@wplj $ ./sulaiman
_ _ / // /
/ // / \/ _ \
//__////_/ v3.3.5
High performance, minimalist Go web framework
https://echo.labstack.com
_________________________________O/_

O\
⇨ http server started on [::]:9099

大丈夫そうだ。

プロセス管理登録と起動確認

配置したプログラムを supervisord の管理下に登録する。/etc/supervisord.d 以下に設定ファイル sulaiman.ini を作る。

[program:sulaiman]
command=/home/takatoh/sulaiman/sulaiman
process_name=sulaiman
user=takatoh
directory=/home/takatoh/sulaiman
autostart=true
autorestart=true
stdout_logfile=/home/takatoh/sulaiman/sulaiman.log
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=7
stdout_capture_maxbytes=1MB
redirect_stderr=true

これで OK のはずだ。確認してみよう。

takatoh@wplj $ supervisorctl start sulaiman
error: , [Errno 13] Permission denied: file: /usr/lib/python2.7/socket.py line: 228

はぁ?どういうこと?

問題解決

ソケット周りでエラーが出てるようだ。権限がないとかいってる。supervisord の設定ファイルを眺めてみると、ソケットファイルのモードを設定する項目が見つかった。これを変更してみよう。

[unix_http_server]<br>file=/tmp/supervisor.sock   ; the path to the socket file<br>;chmod=0700                 ; socket file mode (default 0700)<br>chmod=0777

supervisord をリロード。

takatoh@wplj $ sudo systemctl reload supervisord

確認。

takatoh@wplj $ supervisorctl status sulaiman
sulaiman RUNNING pid 19356, uptime 0:00:22

こんどは OK。

これで、プログラムやスクリプトを簡単にデーモン化できるようになった。

参考ページ

 cf. Supervisorで簡単にデーモン化 – Qiita

「ソフトウェアエンジニアならば1時間以内に解けなければいけない5つの問題」をRubyで

ちょっと、というか結構古いけど 「ソフトウェアエンジニアならば1時間以内に解けなければいけない5つの問題」 というのを見つけた。

 cf. 1時間以内に解けなければプログラマ失格となってしまう5つの問題が話題に – SOFTANTENNA BLOG

大元のページはもうなくなっているようだけど、上のページに問題が載っているので Ruby でやってみた。

問題1

forループ、whileループ、および再帰を使用して、リスト内の数字の合計を計算する3つの関数を記述せよ。

def solv1(ary)
  result = 0
  for i in ary
    result += i
  end
  result
end

def solv2(ary)
  result = 0
  while ary.size > 0
    result += ary.shift
  end
  result
end

def solv3(ary)
  if ary.empty?
    0
  else
    x = ary.shift
    x + solv3(ary)
  end
end

puts solv1([1,2,3,4,5])
puts solv2([1,2,3,4,5])
puts solv3([1,2,3,4,5])

問題2

交互に要素を取ることで、2つのリストを結合する関数を記述せよ。例えば [a, b, c]と[1, 2, 3]という2つのリストを与えると、関数は [a, 1, b, 2, c, 3]を返す。

def solv(a1, a2)
  result = []
  until a1.empty?
    result << a1.shift
    result << a2.shift
  end
  result
end

p solv(['a', 'b', 'c'], [1, 2, 3])

問題3

最初の100個のフィボナッチ数のリストを計算する関数を記述せよ。定義では、フィボナッチ数列の最初の2つの数字は0と1で、次の数は前の2つの合計となる。例えば最初の10個のフィボナッチ数列は、0, 1, 1, 2, 3, 5, 8, 13, 21, 34となる。

require 'pp'

def fib(a, b, acc, n)
  if n == 0
    acc
  else
    acc << a
    fib(b, a + b, acc, n - 1)
  end
end

def solv
  fib(0, 1, [], 100)
end

pp solv

問題4

正の整数のリストを与えられたとき、数を並び替えて可能な最大数を返す関数を記述せよ。例えば、[50, 2, 1, 9]が与えられた時、95021が答えとなる。

def solv(ary)
  ary.map{|x| x.to_s }.sort.reverse.join("").to_i
end

puts solv([50, 2, 1, 9])

問題5

1,2,…,9の数をこの順序で、”+”、”-“、またはななにもせず結果が100となるあらゆる組合せを出力するプログラムを記述せよ。例えば、1 + 2 + 34 – 5 + 67 – 8 + 9 = 100となる 。

def combi(ary)
  if ary.size == 1
    ary
  else
    result = []
    x = ary.shift
    c = combi(ary)
    ["+", "-", ""].each do |op|
      result += c.map{|e| x + op + e }
    end
    result
  end
end

def solv
  a = [1,2,3,4,5,6,7,8,9].map{|n| n.to_s }
  result = []
  combi(a).each do |e|
    if eval(e) == 100
      result << e
    end
  end
  result
end

solv.each do |e|
  puts e + " = 100"
end

俺はソフトウェアエンジニアじゃないけど、どうにか1時間以内に5問ともできた。一番難しかったのは問題5だけど、意外にてこずったのは問題1。Ruby の for の使い方(というか for があること自体)を忘れていて、結局ここだけググった。

sshで接続できるようにする

bigswifty を WiMAX に接続したので、他のマシンとはネットワーク的に切り離されてしまった。まぁ、これは意図した通りなんだけど、ssh で接続できないのも不便なので、インターネット経由で接続できるように設定する。

ここからは bitswifty 上での作業。

sshdの設定

ポートを変更。

Port 12345

root でのログインを禁止。

PermitRootLogin no

設定を反映するために sshd を再起動。

[lcstorage@bigswifty ~]$ sudo systemctl restart sshd

ファイアウォールの設定

ポートを開ける。

[lcstorage@bigswifty ~]$ sudo firewall-cmd --add-port=12345/tcp --zone=public --permanent
success

設定をリロード。

[lcstorage@bigswifty ~]$ sudo firewall-cmd --reload
success

WiMAX端末のポートマッピング

192.168.100.1 にブラウザで接続して、設定ページから、ファイアウォール設定→ポートマッピングと進んで、WAN ポートの12345 を bitswifty の12345 番ポートに接続するようにする。と、ここで気が付いたんだけど bigswifty のポートは変更しなくても良かったんじゃないか?まぁいいか。

接続テスト

別のマシンからインターネット経由で ssh 接続してみると、無事接続できた。

公開鍵での認証

認証方法をパスワード認証から公開鍵認証に切り替える。公開鍵は GitHub からもってきた。

[lcstorage@bigswifty ~]$ mkdir .ssh
mkdir: ディレクトリ `.ssh' を作成できません: ファイルが存在します
[lcstorage@bigswifty ~]$ cd .ssh
[lcstorage@bigswifty .ssh]$ wget -O authorized_keys https://github.com/takatoh.keys
--2018-12-15 05:32:26--  https://github.com/takatoh.keys
github.com (github.com) をDNSに問いあわせています... 192.30.255.112, 192.30.255.113
github.com (github.com)|192.30.255.112|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 特定できません [text/plain]
`authorized_keys' に保存中

    [ <=>                                   ] 381         --.-K/s 時間 0s

      2018-12-15 05:32:27 (2.28 MB/s) - `authorized_keys' へ保存終了 [381]

[lcstorage@bigswifty .ssh]$ chmod 600 authorized_keys
[lcstorage@bigswifty .ssh]$ ls -al
合計 12
drwx------.  2 lcstorage lcstorage   48 12月 15 05:32 .
drwx------. 19 lcstorage lcstorage 4096 12月 15 04:34 ..
-rw-------   1 lcstorage lcstorage  381 12月 15 05:32 authorized_keys
-rw-r--r--.  1 lcstorage lcstorage  185 12月  4 03:56 known_hosts

接続テスト

再び、別のマシンから接続テスト。ちゃんと公開鍵認証で接続できた。

パスワード接続を禁止

最後に、もう一度 /etc/ssh/sshd_config ファイルを編集して、パスワード接続を禁止する。

PasswordAuthentication no

sshd を再起動。

[lcstorage@bigswifty .ssh]$ sudo systemctl restart sshd

これで完了。

参考ページ

MyDNS.JPを利用してDDNSを設定した

昨日はグローバル IP での接続に成功した。今日はDDNS(ダイナミック DNS)を使ってドメイン名で接続することに挑戦する。

無料の DDNS にはいくつか選択肢があるけど、日本語であること、更新に専用のクライアントソフトが不要であること、が決め手となって MyDNS.JP を利用することにした。

ユーザ登録(マスターIDの発行)

まずはユーザ登録。↓このページの JOIN US から登録ページに入る。

 cf. https://www.mydns.jp/

名前とかメールアドレスとかを入力して CHECK をクリックすると、確認画面になる。登録するドメイン名は1つなので子 ID の数は 0 のまま OK をクリック。すると登録したメールアドレスにマスター ID とパスワードが送られてくる。

ドメインの登録

送られてきたマスター ID とパスワードでログイン。DOMAIN INFO からドメインの登録ページに進んで、登録する。Domain 欄には希望するドメイン名(FQDN)、MX 欄は空欄、その下にはホスト名、A、マスター IDを設定。ドメインは無料で使える mydns.jp のサブドメインにした。CHECK →OK とクリックして登録完了。

IPアドレスの通知

ドメインの登録はできたはずなので、使用している IP アドレスの通知をする。通知の方法はいくつかあるけど、HTTP-BASIC を利用することにした。

[takatoh@bigswifty ~]$ wget -O - --http-user マスターID --http-password パスワード http://www.mydns.jp/login.html

↓こんな感じのレスポンスが返ってくれば OK。

<html>
<head>
<title>Free Dynamic DNS (DDNS) for Home Server and VPS etc  | MyDNS.JP</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<LINK href="./site.css" rel=stylesheet type=text/css>
</head>
<BODY BGCOLOR="#FFFFFF"
      TEXT="#304040"
      leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">

Login and IP address notify OK.<BR>
login_status = 1.<BR>
<BR>
<DT>MASTERID :</DT><DD>mydnsxxxxxx</DD>
<DT>REMOTE ADDRESS:</DT><DD>xxx.xxx.xxx.xxx</DD>
<DT>ACCESS DAYTIME:</DT><DD>2018/12/12 19:42:26 UTC</DD>
<DT>SERVER ADDRESS:</DT><DD>168.235.75.38</DD>
<BR>

</body>
</html>

確認

他のマシンから、ドメイン名でアクセスできるか確認したところ、ちゃんとアクセスできた。

cronで自動通知

最後に、cron を使って自動でアドレスを通知するようにする。とりあえず↓こんなスクリプトをかいて、

#!/usr/bin/sh

wget -O - --http-user マスターID --http-password パスワード http://www.mydns.jp/login.html > /dev/null 2> /dev/null

実行権限を付与、毎時 0 分と 30 分に実行するように cron を設定した。

[takatoh@bigswifty ~]$ crontab -l
0,30 * * * * /home/takatoh/bin/mydns_update.sh

これで完了。

WiMAX端末が届いたのでセットアップした

接続

クレードルも一緒に届いたので、クレードルに差して、bigswifty を有線で接続。クレードルには有線 LAN のポートがあるのだ。bigswifty を再起動してやると、自動的に IP アドレスが割り振られて接続できた。ちゃんとインターネットも閲覧できる。カンタン。

グローバルIPの設定

WiMAX 端末にグローバル IP を割り当てる設定をする。WiMAX では、通常は IP アドレス節約のためにプライベートアドレスが割り当てられるようだ。だけど今回はサーバを公開しようとしているので、グローバルなアドレスを割り当ててもらう必要がある。これはそのための設定。

まずは、ブラウザで 192.168.100.1 にアクセス。端末の設定ツールのページになるので、ユーザー名とパスワードを入力してログイン。ユーザー名は「admin」、パスワードは端末本体の背面に書いてある IMEI という番号の下5桁だ。

ログインしたら、設定→WAN設定→プロファイル設定と進んで、新しいプロファイルを Global という名前で作成する。設定の内容は↓このページの通りにしたらうまくいった。

 cf. https://www.uqwimax.jp/service/price/files/GIPOP_manual_HW.pdf

ここで一つ注意。上の設定でグローバル IP を割り当てられるようになるけど、固定ではないということ。これについては後でダイナミック DNS をつかう。

ポートマッピング

bitswifty を WEB サーバとして公開するので、引き続きポートマッピングの設定。設定→ファイアウォール設定→ポートマッピングと進んで、HTTP(80 番ポート)を bitswifty (のアドレス)に転送するように設定する。これで完了のはず。

試してみよう。実際にどんなアドレスが割り当てられているかは、↓このページでわかる。

 cf. https://www.cman.jp/network/support/go_access.cgi

上のページで確かめたアドレスに、他のマシンからブラウザでアクセスしたところ、無事ページが表示された。成功だ!

というわけで、今日のところはここまで。

CentOS: マシンを再起動するとサービスが動かない件

一昨日のエントリでは書かなかったけど、マシンを再起動したら uWSGI のサービスが起動しなかった。仕方がないので手動で起動してたんだけど、今日、問題が解決した。
原因は、ソケットファイルを作る /run/uwsgi ディレクトリがマシンを再起動すると消えてしまうこと。何故なら、/run は tmpfs というタイプのファイルシステムだかららしい。

[lcstorage@bigswifty ~]$ df -h
ファイルシス                      サイズ  使用  残り 使用% マウント位置
/dev/mapper/centos_bigswifty-root    50G  4.3G   46G    9% /
devtmpfs                            1.8G     0  1.8G    0% /dev
tmpfs                               1.8G  8.7M  1.8G    1% /dev/shm
tmpfs                               1.8G  9.8M  1.8G    1% /run
tmpfs                               1.8G     0  1.8G    0% /sys/fs/cgroup
/dev/sdb1                           917G  3.4G  867G    1% /mnt/wiwaxia
/dev/sdc1                           917G   77M  871G    1% /mnt/ottoia
/dev/sda1                          1014M  286M  729M   29% /boot
/dev/mapper/centos_bigswifty-home   179G  507M  178G    1% /home
tmpfs                               359M   32K  359M    1% /run/user/1001

詳しくは分からないけど、↓このページに解決策があった。

 cf.  /var/run の中身が再起動すると消えてしまうので・・・ – cles::blog

要するに、次のような内容で /etc/tmpfiles.d/uwsgi.conf  ファイルを作ってやればいいようだ。

d /run/uwsgi 0777 root root

これで無事、マシンを再起動しても大丈夫になった。

bottleアプリにNginx経由で接続できるようにする

1日空いてしまった。
uWSGI でデーモンとして動かすことに成功したので、今日は Nginx をリバースプロキシにして lcstorage というホスト名で接続できるようにする。

Nginx の前に、uWSGI の設定をちょっと変更。リクエストを待ち受けるのにポートじゃなくて UNIX ソケットを利用するようにする。

[uwsgi]
uid = lcstorage
gid = lcstorage
#http = :8080
socket = /run/uwsgi/lcstorage.sock
venv = /home/lcstorage/lcstorage/env
wsgi-file = /home/lcstorage/lcstorage/index.py
master = true
pidfile = /home/lcstorage/lcstorage/lcstorage.pid
daemonize = /home/lcstorage/lcstorage/lcstorage.log

http の設定をコメントアウトして socket を設定している。
でもって、sochekt のディレクトリをつくる。

[lcstorage@bigswifty ~]$ sudo mkdir /run/uwsgi
[lcstorage@bigswifty ~]$ sudo chmod 777 /run/uwsgi

つぎに、Nginx のバーチャルホストの設定。
/etc/nginx/conf.d/lcstorage.conf ファイルを作る。

upstream uwsgi-lcstorage {
    server unix:/run/uwsgi/lcstorage.sock;
}

server {
    # port
    listen      80;

    # server name
    server_name lcstorage;

    # document root
    #root        /home/lcstorage/lcstorage;

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

    client_max_body_size    4G;

    # log files
    access_log /var/log/nginx/lcstorage/access.log main;
    error_log  /var/log/nginx/lcstorage/error.log warn;

    keepalive_timeout     60;
    proxy_connect_timeout 60;
    proxy_read_timeout    60;
    proxy_send_timeout    60;

    location / {
        #root       /home/lcstorage/lcstorage;

        include uwsgi_params;
        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;
        uwsgi_pass unix:/run/uwsgi/lcstorage.sock;
    }
}

ログファイル用のディレクトリをつくる。

[lcstorage@bigswifty ~]$ sudo mkdir /var/log/nginx/lcstorage

そして、SELinux を無効化。コレ重要。

最後に、マシンをリブートして終了。
無事にバーチャルホストにアクセスできることを確認した。

CentOS 7上でbottleアプリをuWSGIで動かす(2)

一昨日の続き。今日は、アプリをデーモンとして動かす。
まず最初に、uWSGI の設定ファイルをちょっと書き換える。

<span class="token selector">[uwsgi]</span>
<span class="token constant">uid</span> <span class="token attr-value"><span class="token punctuation">=</span> lcstorage</span>
<span class="token constant">gid</span> <span class="token attr-value"><span class="token punctuation">=</span> lcstorage</span>
<span class="token constant">http</span> <span class="token attr-value"><span class="token punctuation">=</span> :8080</span>
<span class="token constant">venv</span> <span class="token attr-value"><span class="token punctuation">=</span> /home/lcstorage/lcstorage/env</span>
<span class="token constant">wsgi-file</span> <span class="token attr-value"><span class="token punctuation">=</span> /home/lcstorage/lcstorage/index.py</span>
<span class="token constant">master</span> <span class="token attr-value"><span class="token punctuation">=</span> true</span>
<span class="token constant">pidfile</span> <span class="token attr-value"><span class="token punctuation">=</span> /home/lcstorage/lcstorage/lcstorage.pid</span>
<span class="token constant">daemonize</span> <span class="token attr-value"><span class="token punctuation">=</span> /home/lcstorage/lcstorage/lcstorage.log</span>
Ini

最後の行を変更した。logger を daemonize に変えると何故かデーモンとしてバックグラウンドで動くようになるという、uWSGI のよくわからない仕様。

無事バックグラウンドで動くようになったら、systemd のサービスになるように設定ファイル /etc/systemd/system/lcstorage.service を書く。

[Unit]
Description=lcstorage service with uWSGI

[Service]
Type=forking
ExecStart=/usr/bin/uwsgi /home/lcstorage/lcstorage/lcstorage.ini
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -QUIT $MAINPID
PIDFile=/home/lcstorage/lcstorage/lcstorage.pid
WorkingDirectory=/home/lcstorage/lcstorage
User=lcstorage
Group=lcstorage

[Install]
WantedBy=multi-user.target
Ini

これでいいはず。試してみよう。

[lcstorage@bigswifty system]$ sudo systemctl start lcstorage
[sudo] lcstorage のパスワード:
[lcstorage@bigswifty system]$ ps ax | grep uwsgi
28937 ?        S      0:00 /usr/bin/uwsgi /home/lcstorage/lcstorage/lcstorage.ini
28946 ?        S      0:00 /usr/bin/uwsgi /home/lcstorage/lcstorage/lcstorage.ini
28947 ?        S      0:00 /usr/bin/uwsgi /home/lcstorage/lcstorage/lcstorage.ini
28949 pts/1    S+     0:00 grep --color=auto uwsgi

成功のようだ。他のマシンのブラウザからも確認できた。

最後に、マシンの起動にあわせて自動的に起動するようにする。

[lcstorage@bigswifty system]$ sudo systemctl enable lcstorage
Created symlink from /etc/systemd/system/multi-user.target.wants/lcstorage.service to /etc/systemd/system/lcstorage.service.

さあ、あしたは Nginx 経由でアクセスできるようにしよう。時間があったらだけど。