この記事には曖昧な表現や作業内容が含まれます。学習やデプロイに参考される場合はご注意ください。なお、筆者自身もネット上の記事を参考にデプロイを行いましたが、XserverにDjangoのアプリをデプロイするのはインフラ初心者にはハードルが高い印象です。
皆さんこんにちは。環境構築だけで何十時間も消費してしまっている小幡です。インフラエンジニアという職業が存在する理由をPythonで仕事させて貰うまであまり理解できていなかったのですが、”sudo”コマンドをはじめ、”brew”,”rpm”,”curl(最新)”が使えないXserverの環境でDjangoをインストールしようとしたら、さらに何十時間も消費するはめになってしまい、インフラを整えてくれる人がいたらいいのになぁと痛感しました。(curlは使えますが、古いバージョンでlinuxbrewがインストールできない。とかそういう状況だったと思います。)
そんなインフラ構築初心者には辛い環境で、10数年前くらいの方法で(?)環境構築したお話をします。具体的には”wget”を使って必要なもの(C言語のソース?)ダウンロードして、ダウンロードしてきたソースを”./configure”でビルドして(?)バイナリファイルを作成して使える様にする(?)という、頭に?がたくさん湧いてしまう状況でした。
以下リンクを参考にしています。ただ、1つのサイトで全てうまくいくということにはならず、少しだけ上手く行かないので、そのつど検索をたくさんすることになると思います。
パスなどを自分好みに変える事なく、忠実に記事を再現する方法で作業した方がうまくいくと思います。
できればC言語の初歩的な学習からやり直したいですが、今回はDjangoのアプリをデプロイしたいので、また今度。
以下、備忘録的なもので、筆者がハマったところなどを書いているだけです。上のリンクから問題解決策を探す事をお薦めします。
sudoコマンドが使えない状況とは?
sudoコマンドは管理者の実行権限を使い、どんな事でも出来てしまう魔法のコマンドな訳で、これを使うことによってサーバに行いたいことをなんでも行える訳です。
つまりサーバを借りているだけの私は管理者ではないので、sudoコマンドは使えない仕様になっているということだと認識しています。
Xserverではなく他のサーバだと使えたりするらしいのですが、他社のサーバを借りようかと悩んだ結果、借りなかったので詳しいことはわかりません。
それとsudoで何かインストールしたりする状況だと、サーバ全体に影響を与えるためsudoコマンドが使えないだけで、自分が借りているサーバの領域に対して、何かをインストールすることは可能の様でしたので、結果的にはsudoを使用せずにDjangoのインストールを終える事ができました。
このsudoコマンドが使えない状況、つまり与えられた領域の中だけでやりたいことをやるというのは結構不自由なもので、与えられた領域には、Djangoをデプロイするだけの環境は容易されていません。
そもそもなぜXserverなのか?
私がポートフォリオで使用しているサーバがXserverだったためです。
AWSや、さくらのVPS、Herokuの使用も検討しました。
まずAWSはEC2の費用がかかり、インフラの整備に間違いがあると費用がかさむ恐れがあります。DynamoDBやLambdaを使ってAPIを作成する場合などは、常時かかる費用がゼロで、もしそのAPIが使われる頻度が高くなった場合に支払いが始まるというお財布に優しい設計になっていますが、EC2はインスタンスが起動している時間で費用が発生してしまいます。
つまり一番安いEC2を選択したとしても、アプリを常時公開状態にしておくと、アクセスがゼロでも費用がかかる訳です。(1年間は無料で使える枠があったかと思いますが、結局常時公開したいのでパスします。)
さくらのVPSはXserverと同じ定額制なので、決まった金額を振り込めば期間内で更に費用がかかるということはありません。アプリがバズってアクセス数が増大し、増強しなければならない場合は大変かもしれませんが。
こちらも比較的リーズナブルで良いかなぁと心が揺れましたが、なぜ既に支払い済みのXserverでやらないのか?!という、内なる声が私を踏みとどまらせたのでした。そうして、この数十時間をつぎ込んでしまう日々が始まったのです。
お金で解決できることだったので、他のサーバを借りてしまえばよかったのかもしれませんが、このおかげでDjangoの知識や、CGIやシバン、.htaccessの知識が深まり、ちょっとしたインフラ構築ならできるようになった気持ちになれたので、よしとします。(本当はPythonだけをガシガシ書きたい)
ということで、もしもお金に余裕があり、時間がまったくないという方に「XserverでDjangoのアプリのデプロイ方法を教えてください」と聞かれたら「他のサーバを借りた方が良いよ」と返答すると思います。
Linuxbrewをインストールするまで
このlinuxbrewをインストールするだけでも、数十時間を費やしたのではないか?というほど大変でした。
たぶん一番最初に「さぁ頑張って環境構築するかー」と始めた頃は、「XserverでPATHを通す」ということの意味さえしっかりと理解できていなかったと思います。
この「PATHを通す」はどんな環境構築でも難関の1つだと思いますが、Xserverの場合だと例えばcurlをwgetでソースをダウンロードする場合、そのダウンロード場所はどうするのか?その後のインストール場所はどうするのか?インストールしたらパスはちゃんと通っているのか?という3ステップも越えなければなりません。
もっと具体的に言うと、まず何かをインストールする前に、現状の環境でどのバージョンのcurlが使われているのかを確認しておくことが重要です。その時にはwhichコマンドを使います。これは後に続くコマンドが実行される場所を表示してくれます。以下のように書きます。
which curl
するとパスが表示されると思いますが、確か以下の様な場所が表示されます。
/usr/bin/curl
これは「ルート(管理者権限下)のusr(ユーザ)のbin(バイナリ)のcurl(コピーURL)」を指していると考えます。ルートにあるというのは自分の与えられた範囲の中ではないことを意味します。
自分の与えられた範囲はcdコマンド単体でEnterを押した時に入るディレクトリの事です。そこでpwdコマンド(現在のディレクトリを表示するコマンド)を実行すると現在いる位置がわかるとおもいますが、そこは/usr/ではないはずです。おそらく/home/から始まる場所だと思います。
つまり、最初にcurlをwhichでどこにあるか探しに行きましたが、与えられた範囲の外のcurlを使う設定になっているということがわかりました。
そしてこのcurlを-Vオプションを付けて実行するとバージョンが確認できます。
curl -V
すると、最新のバージョンではないことがわかるかと思います。
どこで必要だったのか正確な事は忘れてしまいましたが、curlとgitのバージョンが古く、Djangoインストールまでのどこかで沼にハマる(つまずく、上手くいかなくなる)ことになると思います。
opensslとの連携が上手くいかず、wolfsslなどを調べ始める
curlとgitだけでもものすごく大変です。しかし、ほとんどの場合は、上であげた記事を参考に作業すればインストールできると思います。それでも私の場合は、この作業だけでも相当苦労してしまいました。
特にcurlをインストールするときにopensslを使用してhttpsのソースもダウンロードできるようにする設定が必要なのですが、opensslとcurlの連携が上手く行かず、httpsが対応されないものがビルドされてしまうというトラブルがありました。
「あーもう何をやってもopensslじゃだめなんじゃないかー?」と頭を抱え始めて時間が経ち、こんなところで悩んでいても仕方ないから、他に出来る方法はないか探し始めてしまいました。そこで”with-openssl”以外にも使えるssl(?)があることに目が止まり、最下段にあった(?)wolfsslを調べ始めてしまいました。
というのも”openssl”をネットで調べてみると「opensslに脆弱性」という記事が最初にあがっていたからというのもありました。あまりいい評判じゃないものより、他のものがあるならそっちを使うのもありだと思ってしまったのです。wolfsslはおそらく、今回の場合は不適切な採用となると思いましたが、とりあえず公式ページからダウンロードしてきて、FTPでXserverに送信してcurlのビルド時に”with-wolfssl”としたところ、本当にhttpsが使えるようになって驚いた様な気がします。(曖昧)
しかし、すぐに別の作業でまたトラブルになって「こっちでもopensslが必要なのかー、面倒だからもとに戻そう」ということで、よく覚えていませんが、全てやり直したと思います。
gcc, g++も頑張ってインストールする
curl,git,linuxbrewがインストール終わるとgcc@5問題にぶつかると思います。これもXserverに入っているgccがバージョン5未満なので起こるエラーだと思います。ここまで自力でgccをwgetしてきてビルドすることをしてしまうわけですが、これもlibとの連携が上手くいかず、インストールはできるものの結局不具合が生じてしまう結果になるだけでした。
恐らくビルドを正確に行うことができればgcc@5問題は解決できるのだと思いますが、ここは諦めて最初からやり直すことにしました。
結局色々なもののソースをダウンロードしてきてはビルドからインストールを繰り返してきたわけですが、./configureの基本的な知識が足りず、かなり苦労しました。
欠けているライブラリを設定する
どこの段階で発生したか忘れましたが、色々とインストールしていくと、参照しているライブラリが欠如している箇所ができて、エラーが発生するという事がありました。
恐らくビルド設定でミスがあったのだと思いますが、うまくlibと連携が取れていな状態でインストールすると怒るものだと思います。lddコマンド(?)で欠如部分を見つけて、その穴にライブラリを設定する的な作業をした記憶がありますが、詳細は忘れてしましました。
問題部分を検索して、あっさり解決してしまったのだと思います。困ったことにすぐに解決してしまったことほど記憶に定着しませんねぇ。
C言語のソースをビルドする際に、使っているライブラリのパスの様なものを指定することによって、そのライブラリが使えるようになり、ビルドしたバイナリも実行可能になるという様な認識なのですが、そのライブラリのパスが欠けている状態が発生したということです。
そしてそのlibraryのパスを確認するコマンドがlddコマンドという認識です。さらにそのlibraryを追加するためになんやかんやしたはずです。
PATH地獄問題、index.cgi, .htaccess問題
linuxbrewをインストール出来てからDjangoインストールまでは比較的簡単なはずです。というのも、pipenvで仮想環境が出来てからはその環境にいつも通りのやりたいことを比較的自由に操作可能だからです。
linuxbrewをインストールしてPipenvもインストールして、DjangoとPythonが無事にXserverに入りました。
さて、なんやかんやあって、アプリもXserverに送って、後はindex.cgiと.htaccessだけになりました。ちなみにアプリをXserverに送るためにSyberDackを使いました。FFFFTPやFileZilaなども選択肢としてあげられるかもしれません。
ここからゴールはもうすぐなのに「Hellow, World」が圧倒的に遠い存在に思えたのは今回が初めてでした。XAMPやらVagrantやらDockerなども触ってきましたが、1日あれば「Hellow, World」くらい出来ていたように思うので、本当にここは辛い戦いでした。
まず、先ほども書いた通り、curlやgitを使うために自分の環境にインストールしPATHを通す必要がありました。これだけなら2つを足すだけなので、まだ混乱は起きませんが、これからlinuxbrewとpipenvの仮想環境の考慮が始まります。
linuxbrewのbrewでインストールしたものがどこに入っていくのか問題です。そしてlinuxbrewでインストールしたpipenvですが、これを使って作成した仮想環境はどこにあるのか?さらに仮想環境にインストールしたpythonとDjangoはどこにあるのか?
もうパニックですね。
この調べた環境パスなどをデスクトップにメモしたりしました。というのも最初にpipenv installした時に、作成した仮想環境を削除するpipenv –rmというオプションを知らず、作成した仮想環境がいくつもできてしまったのです。仮想環境のパスは呼び出した元のフォルダ名にランダムな(?)英数文字が足されたものなので、見分けが付けずらいということもありました。
そしてこのパスをCGIと.htaccessで使う事になります。
ここら辺は、whichやらpipenv –vevnやら、pythonの対話型シェルに入ってindex.cgiで使うモジュールを実際に動かしてみたり、Xserverのエラーログを見てみたり、とにかくやれることをやるだけです。
どんな時でもエラーログを見ることは重要です。ある種エラーのログは1つの結果ですので、どういう結果が返されているかの確認は一番重要です。エラーを見る事で明確に次に取るべき行動がわかりますので、しっかりとエラーを確認しましょう。
エラーログの確認は、Xserverの公式ドキュメントがすぐに見つかるはずです。ダウンロードできたらwindowsの場合であればダウンロードフォルダに入ると思いますのでPowershellなどを開けばcdコマンドでホームに移動した後、downと書いてTABでダウンロードフォルダが選択されるので簡単に移動できますし、catコマンドを使い、ドメイン名を入れた後にまたTABを押せば長いファイル名を一気に入れてもらったファイル名を選択すれば中身を確認できます。
私の場合はログファイルだけで(30)個ほども出来てしまいましたが。30回も同じ作業をしていると、数秒でログを確認できるようになりました。SSHで接続した状態でログを確認できれば良いのでしょうが、公式ドキュメントを探してもログの保存場所はわかりませんでした。
さて最終的には.htaccessと.cgiについてはほとんどわからず、CGIのシバンやらsys.path.insertで使う環境変数だったり、最終的にはWSGIとASGIの違いだったりDjangoと非同期処理だったり、結局は1からわからないことをわかるようにしたら出来るようになったという感じです。
わからない事をわかるようにする
今回この苦行を終えて、改めてわからない事をわかるようにすることが重要だと感じました。
まあまだC言語の事やソースからのビルドだったり、PATHの通り方だったりpipenvの作りなど、完璧に理解できていない事があるので、学ばなければならない事が多々あります。
しかし、何がわからないか、どこの処理が悪いのでやりたいことができていないなど、まったくの盲目の世界から脱出はできたのかなと感じています。
結果的にXserverでDjangoを使い「Hello, World」までたどり着きました。
これでやっと次に進めます(涙