岡竜之介のブログ

岡竜之介のブログです。

ロリポップレンタルサーバーでDjango??

もはやテーマがとっちらかっていて何を書いたらいいんだかわからなくなっているこのブログですが

まあ、いいや。

なんか混乱したのでその内容と、その解決の過程を備忘録として書き留めておこうと思います。

経緯

Webアプリを作ろうと思って、PythonのWebフレームワークである所のDjangoチュートリアルをやったはいいものの、

契約してるレンタルサーバー「ロリポップ」(スタンダードプラン)でDjangoが動かせるのかという問題にぶつかったので、

そもそも動くのか、俺は一体何をわかっていないのか、その辺の解決を試みます。

Djangoについては、ローカルでチュートリアルを一通りやりました。

Djangoのバージョンは1.11。「いってんいちいち」ではなく「いってんじゅういち」と読むほうが誤解がないです。1.9よりも新しい。

結論

読者の時間が無駄にならないように結論を先取りして書いておきますと

結局いろいろ調べたり試行錯誤した結果、レンタルサーバーでDjangoを動かすのはやめてVPSを契約することにしました。

レンタルサーバーでもCGI経由で動かすことはできるみたいだけど、そこまでするメリットがよくわからなかった。




ここから先は、僕の思考の時系列順に書いてます。


僕の経験値

5年前の2012年、PHPのWebフレームワークである所のCakePHPを使ってWebアプリを作ったことがあります。

解決したい疑問

CakePHPは普通に動かせたのにDjangoで困ってるのは何が違うからなの
CGIって何
ロリポップに「Pythonが使える」と書いてあるけど、どういう意味で「使える」の
・結局ロリポップDjangoは動くの



じゃあ一個ずつやっていきましょう

CakePHPは普通に動かせたのにDjangoで困ってるのは何が違うからなの

ロリポップPHP動かすのってめちゃくちゃ簡単なんですよ。

例えば、ロリポップFTPとかを使ってサーバー上に次のような hoge.php というファイルを上げる。

<?php
echo "Hellooooo Wooorrrrld";

で、上げたファイルのアドレスをそのままブラウザに打ち込んでアクセスすると、このPHPの実行結果が出力されます。

ファイルのパーミッションは644。全員Readができて、Writeは所有者だけ。eXecuteは誰も出来ない設定。

でも実行されてます。なんでだ。実行権限は誰にもないんじゃないのか。


まあとにかく。

PHPはファイルを上げるだけで実行できるんですよ。


対して、Pythonはどうか。


hoge.pyをアップします。

print("Goodafternoon world")

そしてこのファイルのアドレスをブラウザに打ち込んで直接アクセスすると…

500 Internal Server Error
※CGI もしくは SSI が正しく動作していません。


怒られました。

軽くググッた感じ、SSIの方は今日の記事とはあんまり関係なさそう。

CGIについてはあとで話題にしましょう。

ロリポップPHPについて

で、また調べを進めた所

僕のアカウントでのPHPの設定は「バージョン 7.1(モジュール版)」でした。

このモジュール版という所が多分、今日重要になってきそう。多分。


そこで、これを「バージョン 7.1(CGI版)」に変更してみました。



そして、先ほどのhoge.phpにアクセスして見た所…


…問題なく実行されますね。


(phpinfoを使って、Server APIの項目が Apache 2.0 Handler から CGI/FastCGI に変わったことを確認しました)


いや、その、仮説としてね


PHPはモジュール版だから実行できたのであって、pythonCGIを通して(?)実行する必要があって、だからPHPCGI版に変えたらさっきみたいに簡単に実行できなくなるんじゃないかって


思ったんですけどね。どうもそうじゃない。



CGIって何


ということで、やたらめったら出現する「CGI」というキーワードを調べてみます。

イメージ、なんかこう、15年くらい前にアクセスカウンターとか掲示板とかそういう周辺で見た言葉、っていうイメージ。


CGIとは、Common Gateway Interface の略。Wikipediaによると

ウェブサーバ上でユーザプログラムを動作させるための仕組み。

だそうです。

「…はぁ。え、CGIはそういうものの一種ってこと?それともそういうもの全般をCGIと総称するの???」などと思いましたが

前者でよさそうです。CGIはそういうものの一種。

ロリポップでは、.cgiファイルをアップロードしてブラウザでアクセスすれば実行されるっぽい。


んでまあ軽くググッた感じ、
Perlで書くことが多い
・拡張子は.cgi
・一行目には、使用したプログラミング言語へのパスを書く

最後の奴がわかりにくいですが、ロリポップのマニュアルにちゃんとパスが書いてありました。


ということで、とりあえず何もしないプログラム fuga.cgi を書いて、実行してみよう。

#!/usr/bin/perl

(パーミッションは700、ロリポップ推奨)

500 Internal Server Error
※CGI もしくは SSI が正しく動作していません。

なんでだよ!!


ということでいろいろ試行錯誤したり調べたりしながら、ようやく「動作するコード」に辿り着きました。

#!/usr/bin/perl
print "Content-type: text/plain\n\n";
print "fugafugafugafugaaaa";

これで、最終的にブラウザに「fugafugafugafugaaaa」が返ってきました。この2行目がないとサーバーエラーになる。

CGIの動き

つまりこういうことらしい。

基本的には.cgiファイルに好きな言語のコードを書くんですが、そのプログラミング言語さんに渡す前後にCGIさんを経由するので

CGIさん用の指示が必要になる。

全体の流れとしては、まず往路

.cgiファイル → CGI → プログラミング言語

この過程では、CGIさんは.cgiファイルの一行目に書いてある宛先(プログラミング言語のパス)を確認し、二行目以降を渡す。

今回の場合はPerlさんがそれを受け取って、実行。出力は次のようになる。

Content-type: text/plain

fugafugafugafugaaaa

次は復路

プログラミング言語 → CGI → ブラウザ

ここでCGIが一行目を見て「あ、これはただのテキストなのね。音声とか画像ではないのね。」と確認し、適切な形でブラウザに返す。

さっきエラーになった時は、この「これはテキストですよ」という一行目がなかったんですね。これを「ヘッダ」というらしいです。


なるほど。

よし!

ここまでわかればpythonも動かせるはずだ!

#!/usr/local/bin/python3.4

print("Content-type: text/plain\n")

for i in range(10):
	print(i)


これはちゃんと動いた!!!!(パーミッションで実行権限を付け忘れてエラー出て小一時間悩んだけど。)

ロリポップに「Pythonが使える」と書いてあるけど、どういう意味で「使える」の


とりあえず、CGI経由で動かせることはわかりましたね。


てもこれで、どうやってDjangoをインストールしたり動かしたりするのかはまだまだわかりません。


ここでSSHという機能を有効にしていろいろ試してみましょう。


SSHは、Secure Shell の略で、めちゃくちゃ簡単に言えば、コマンドプロンプトやターミナルからサーバーにアクセスする方法のことです。


コマンド入力でいろんなことができます。


ロリポップの管理画面からSSH設定を有効にして、

ssh -l ユーザー名 -p ポート番号 ホスト名

で接続成功。


"vim" やら "python" やら普通に使えるので、.pyファイルを作ってコマンドから実行とか簡単にできました。

なるほど、こういう意味でも、サーバー上でpythonを「使える」わけだ。



さて、こちらの参考文献によると

noppiki.hateblo.jp

curl や pip が無くて困ってる様子なんですが

今確認した所によると、既に入ってるようです。

pipが使えれば、python関係の好きなモジュールがインストールできるはずで、Djangoのインストールも瞬殺では??


ということでやってみよう。

python -m pip install Django

…。


だめ。Permission Error.


そうか〜〜〜



chmodも試したけど、弾かれました。まあそりゃそうだ。これで変えれたら意味がない。sudo は command not found. なるほど。



どうも調べると、こういう時は、--user というオプションを使えばいいっぽい?

やってみましょう。

python -m pip install Django --user


……うまくいきました!!


案外、SSHでこの調子でやっていけば、ロリポップDjangoちゃんと動くのでは?

結局ロリポップDjangoは動くの

では、ここからはこのマニュアルにそってやっていきましょう。

Django をデプロイする | Django documentation | Django


WSGI という仕組みを使って、サーバー上でDjangoを動かすことになりそうです。


CGI ではなく WSGI を使う」という理解でよさそう。多分。


ロリポップサーバーはApacheというソフトで動いているので、Apache上でWSGIを使うには mod_wsgi というモジュールを使うことになりそう。


新出単語が多くてアレですが、まあ、そういうことみたいです。


……



さて。そうして2時間くらい経ちましたけれども


ロリポップApacheに mod_wsgi をインストールして有効化する方法が全然わかりませんね。


Apacheまわりの設定が全部書いてある httpd.conf というファイルをいじる必要がありそうなんですが


ロリポップだろうとさくらレンタルサーバーだろうと、httpd.conf はいじるどころか中身見ることもできないみたいです。


あれ?じゃあデプロイできなくね????どうすんの?????無理なの???



……


どうも、下記のページたちによると

さくらのレンタルサーバでpyenvとDjangoを動かす « chibiegg日誌
さくらサーバのスタンダードでPython3.5 + Django1.9を動かす | しましまくろっく
qiita.com


結局、CGI経由で入れるしかないみたいです。WSGIではなく。


CGI経由だと、アクセス(リクエスト)がある度にpythonを起動して処理して、ってやるから反応が遅くなるみたいですね。

(WSGIのデーモンモードならpythonを起動しっぱなしにできる)


まあ、安いレンタルサーバーですから、それは仕方ないのでしょう。



ということで、長いことかかりましたが、

CGI経由でDjangoを動かす


やっていきましょう。



Djangoのプロジェクトの中から、「最初にこれを起動しさえすればいい」みたいな.pyファイルを見つけて、そいつをcgi経由で実行すれば済む話

…なら、簡単にいく気がするんだけど、そもそもDjangoってリクエストを受けた後どういう仕組みで動くんでしょうね。


URLディスパッチャがURLに合わせたビューを呼ぶ、ってのはわかってるんだけど


今話題にしてるのは、もっと前段階の話だよね。


もうちょっと悪あがき

いや、待って待って

Djangoってのは、WSGIを使って実装するように設計されているわけで、


CGIを経由してDjangoを動かすというのは

まあ言ってみれば邪道なわけですよ。

CGIで動かすと、パフォーマンスも下がるらしいし。

なんとかCGIを使わずに普通にWSGIで動かす方法はないものか。


ということで、httpd.conf の代わりに .htaccess をいじることでなんとかならないか調べてみました。

.htaccesshttpd.conf よりも下位にある設定ファイルで、.htaccess なら、レンタルサーバーでもいじることができる!


…ということで調べてみたんですが



.htaccess に書ける範囲の内容では、mod_wsgi を有効化することはできないみたいですね。


httpd.conf に LoadModule という行を書いてやる必要がある。



はい。ということで。ダメです。CGIを経由するしかなさそう。


レンタルサーバーや〜めた!VPSにしよう!!


はい。


突然ですが、完全に僕の知識不足であれだったんですが

いろいろ調べているうちに、そもそもレンタルサーバーではなく、VPSというサービスを使うと、httpd.conf をいじれることがわかりました。


VPSというのは、Virtual Private Server の略で、レンタルサーバーよりも自分で触れる範囲が広い(自分で触らなければならない、とも言える)


もらえる権限が大きい代わりに責任も伴うわけですね。


そもそもApacheのインストールから自分でやるみたいです。



そうか。


おとなしくこれ使えば、邪道な方法を取らずともDjangoアプリを作れるわけか。


しかも値段も安いとこを使えばレンタルサーバーと大して変わらないみたい。



ということで。


レンタルサーバーでDjangoを動かすのはやめて、VPSを契約することにしました。



追記(2018-04-25)

ちなみに、こうしてVPSを契約してDjangoを動かして作ったサービスがこちらです!

岡竜之介の大喜利道場

よかったら遊びに来て下さい!!


それから、この記事を書いた時には知らなかったのですが

Firebase や Heroku といったサービス上でDjangoを動かす手がありますね。

サーバーの管理をそこそこ自分でやらなきゃいけないVPSと違って、手軽でいいかもしれません。

一方で、その分カスタマイズ性が低く、かゆいところに手が届かないといったことは起こるかもしれませんね。

参考までに!

以上!!