サーバーのOSをアップデート
ubuntuのLTS 18.04が出たので、OS入れ替えたのが約1ヶ月前。
blog動かして、データも復元したのがつい最近。
本当にやる事が遅くて、このペースだと死ぬまであっという間な気がする。
死ぬる時には、何かをやりきった気になりたい。
This site’s main contens. mainly programming.
ubuntuのLTS 18.04が出たので、OS入れ替えたのが約1ヶ月前。
blog動かして、データも復元したのがつい最近。
本当にやる事が遅くて、このペースだと死ぬまであっという間な気がする。
死ぬる時には、何かをやりきった気になりたい。
El Capitanにアップデートした。
前のYosemiteの時はbrewが動かないとかあったけど、今回はすんなりできた。他になんかあんのかな?と思ってxcodeを動かしてみたけど、一応動いた。何も作ってないので、あまり確認のしようがなかった。
Eclipseはjavaのバージョンがどうこう言われて動かなかった。たぶん大分前からそうだったんだろうな…
ユーザ認証して、認証後のユーザ利用まで動作できたのでまとめる。
できたけど、フレームワークが提供してくれてるがいろいろ面倒くさい。
djangoって結構自前で作る部分が多いかと思うので、フレームワークがやってくれるのか、そこは自前なの?!、とかが分からなくてしんどかった。
とはいえユーザ認証する部分は上記サイトをまるまる参考にさせていただきました。
せいぜいurls.pyの書き方が違うくらい。
<br /> urlpatterns = [<br /> url(r'^admin/', include(admin.site.urls)),<br /> url(r'^login/$', 'django.contrib.auth.views.login',<br /> {'template_name': 'account/login.html'}),<br /> url(r'^logout/$', 'django.contrib.auth.views.logout',<br /> {'template_name': 'account/logout.html'}),<br /> url(r'^account/', include('account.urls', namespace='account')),<br /> ]<br />
ユーザ認証を別のアプリケーションから利用するところが今回の記事のメインなんだけど、モデルを起こすところも、c-bata webさんの記事を参考にさせてもらいました。しかし、差分だけ書くと作業の流れがわかりにくいので丸々書く。
アプリケーションをこさえる。todoを残すだけのアプリ。
$ python manage.py startapp todo
setting.pyのINSTALLED_APPSにtodoを追加。
+++ b/django_auth/settings.py @@ -38,6 +38,7 @@ INSTALLED_APPS = ( 'django.contrib.messages', 'django.contrib.staticfiles', 'account', + 'todo', )
urls.pyにルーティングを追加。
+++ b/django_auth/urls.py @@ -23,5 +23,6 @@ urlpatterns = [ url(r'^logout/$', 'django.contrib.auth.views.logout', {'template_name': 'account/logout.html'}), url(r'^account/', include('account.urls', namespace='account')), + url(r'^todo/', include('todo.urls')), ]
モデルを定義。外部キーとしてdjangoのUserモデルを指定。
<br /> from django.db import models<br /> from django.contrib.auth.models import User</p> <p># Create your models here.</p> <p>class Todo(models.Model):<br /> user = models.ForeignKey(User, related_name='todo')<br /> memo = models.CharField('Memo', max_length=128)</p> <p>
admin.py。
<br /> from django.contrib import admin<br /> from todo.models import Todo</p> <p># Register your models here.</p> <p>admin.site.register(Todo)<br />
todo/urls.pyはフレームワーク生成ではなく、自分で作成。表示のみ。更新はadminからやる。
<br /> from django.conf.urls import url<br /> from django.contrib.auth.decorators import login_required<br /> from django.views.generic import TemplateView<br /> from . import views</p> <p>urlpatterns = [<br /> url(r'^$', login_required(views.IndexView.as_view(<br /> template_name='todo/index.html')), name="index"),<br /> ]<br />
views.py。何をこんなにimportしなきゃいかんのか分かってないけど、やる。しょうがない。まだdjangoはチュートリアルと、これしか作ってないし。
<br /> from django.shortcuts import render<br /> from django.core.urlresolvers import reverse<br /> from django.views import generic<br /> from django.http import HttpResponseRedirect, HttpResponse, Http404<br /> from django.template import RequestContext, loader<br /> from django.contrib.auth.decorators import login_required<br /> from django.contrib.auth.models import User<br /> from .models import Todo</p> <p># Create your views here.<br /> class IndexView(generic.ListView):<br /> template_name = 'todo/index.html'<br /> context_object_name = 'todo_list'</p> <p> def get_queryset(self):<br /> # reffer django-document.<br /> # Built-in class-based generic views > Dynamic.filtering<br /> # print(self.request.user)<br /> return Todo.objects.filter(user_id = self.request.user.id)<br />
テンプレートの追加。ディレクトリ構成が気持ち悪いけど、他の書き方がよく分からない。
% mkdir -p todo/templates/todo/ % touch todo/templates/todo/index.html
<br /> ▽<br /> <p>{{ user.username }}</p></p> <p>{% if todo_list %}<br /> <ul><br /> {% for todo in todo_list %}<br /> <li>{{ todo.memo }}</li><br /> {% endfor %}<br /> </ul><br /> {% else %}<br /> <p>No item are available.</p><br /> {% endif %}<br />
あとはDBを更新すれば出来上がり。
% python manage.py makemigrations % python manage.py migrate
出来上がったのはこれ。ログイン後にhttp://127.0.0.1:8080/todoとかでアクセスすれば、adminで追加したメモがUser毎に表示されるハズ。
https://github.com/vottie/django_auth
苦労したのはtodoのviews.pyでどうやればUserを利用できるか、だった。
結果Userモデルをimportしてあげることで解決できた。
もう1点はListViewでどうやればログインしたUserがGETできるかだったが、ドキュメントをしらみつぶしに読んでいったらUserはRequestオブジェクトに入っていることが分かって、ListViewのselfはrequestオブジェクトを含むことが分かって解決した。
最後に今回の環境は以下。
vagrant
ubuntu14.04
python 3.4.3(pyevn)
django 1.8
djangoをvagrantにインストールしたのだけれど、runserverしてもホスト(この場合はmac)側のブラウザで管理画面が見えない。ポートフォワードの設定がおかしくなってる。
具体的にはguest:8000, host:28000で定義しているにもかかわらず、ホスト側からはlocalhost:18000でアクセスできてしまう。
ポートフォワードせずにvm上でw3mでアクセスするとguestのポートは8000であることは確実。
なぜにポートフォワードがトチ狂うのか?と思ってたが、vagrantのgunicornの設定で8000番を使ってて、かつ18000番にポートフォワードしてた。。。
vagrantでは28000番を使って、ホスト側は28001番のフォワード設定で解決した。と思いきや、ぜんぜんつながらない。
tcpdumpまでひっぱりだして3,4晩ウンウン唸ってたけど、”django vagrant”でググったら一発で解決した。
5分でできるVagrantでDjangoの環境構築 | qiita
そういえばrailsか何かでハマったような気もする…
djangoで何か作って運用するための準備としてgunicornを使ってみた。
トップページには簡単に動きまっせみたいなことを書いているが、3晩はかかった。仕事だとしたらば1日潰れたぐらい時間がかかった。
まずはvagrantで動いてるubuntu 14.04にインストール
</p> <p>$ pyenv shell 3.4.3</p> <p>$ pip install gunicorn</p> <p>
つづいてサンプルアプリの写経
~/src/gunicorn/myapp/myapp.py
</p> <p>def app(environ, start_response):<br /> data = "Hello World!\n"<br /> start_response("200 OK", [<br /> ("Content-Type", "text/plain"),<br /> ("Content-Length", str(len(data)))<br /> ])<br /> return iter([data])</p> <p>
動かしてみると、おー動く。
</p> <p>unicorn -w 4 myapp:app</p> <p>[INFO] Listening at: http://127.0.0.1:8000 (13232)</p> <p>
でもブラウザからは動作はしない。vagrantのポートフォワードの設定をしてもダメ。webサーバ、うちの場合はnginxの設定も必要らしい。
なんとなく真似てgunicornのグループを作成して、vagrantユーザを所属させてみたが、結局confの設定は正しく読めなかった。
nginxの設定もunixドメインソケットのupstreamの設定がキモっぽいがsite-available/defaultに書いてると、/var/log/nginx/error.logに以下のエラーが出てnginxが起動しない。
"upstream" directive is not allowed here
ググってみるとどうもバーチャルホストの設定が必要らしくconf.d/になんか書く必要があるとのこと。参考にさせてもらったサイトでもよくみるとそうなってたので、そのようにした。でもconf./dの設定とsites-availableの設定の関係性が分からなくなった。
confの設定がどうも効かないので、CLIから直接起動。アプリを書いたディレクトリで、以下を叩く。
</p> <p>unicorn -b "unix:/tmp/gunicorn.sock" myapp:app</p> <p>
今度はListeningのlogが変わった。
</p> <p>[INFO] Listening at: unix:/tmp/gunicorn.sock (13277)</p> <p>
がしかし、http://127.0.0.1:18000/にアクセスすると、gunicornのアプリがエラーする。(18000はvagrantへのhttpアクセスのport forwardの設定port)
</p> <p>[ERROR] Error handling request&nbsp;Traceback (most recent call last):<br /> File "/opt/pyenv/versions/3.4.3/lib/python3.4/site-packages/gunicorn/workers/sync.py", line 177, in handle_request<br /> resp.write(item)<br /> File "/opt/pyenv/versions/3.4.3/lib/python3.4/site-packages/gunicorn/http/wsgi.py", line 326, in write<br /> raise TypeError('%r is not a byte' % arg)</p> <p>
“gunicorn type error not a byte”でググって、stackoverflowで解決。
gunicorn (Python3.4 and 3.3) sends in response only headers without data | stackoverflow
元のアプリがpython 3系だとダメらしい。以下のresponseとおぼしき1行を修正してブラウザからの動作は確認できた。
– return iter([data])
+ return [bytes(data, ‘utf-8’)]
残すは設定ファイルからのgunicorn起動。
2015/10/05追記
設定ファイル書けた。たぶんファイルのパーミッションの問題で、daemon化ができていなかった。以下は動作が確認できたファイルで、logファイルは先に作成して、chmod 666した。
</p> <p>import multiprocessing</p> <p>bind = 'unix:/tmp/gunicorn.sock'</p> <p>workers = 2<br /> worker_class = 'sync'<br /> worker_connections = 1000<br /> max_requests = 1000<br /> timeout = 30<br /> keepalive = 2</p> <p>debug = False<br /> spew = False</p> <p>prelood_app = True<br /> daemon = True<br /> pidfile = '/tmp/gunicorn.pid'<br /> umask = 0<br /> #user = 'vagrant'<br /> #group = 'gunicorn'</p> <p>accesslog = '/usr/local/gunicorn/logs/access.log'<br /> errorlog = '/usr/local/gunicorn/logs/error.log'<br /> loglevel = 'info'</p> <p>proc_name = 'gunicorn'</p> <p>
なお確認したソフトのバージョンは、以下。
python 3.4.3
nginx 1.4.6
gunicorn 19.3.0
ちゃんとした証明書になったので、iphoneからの投稿もできるようになりました。
nginxのログ見てもパスワードは見えてまへん。
でも写真はそのままアップすると位置情報が入ってるから一工夫しないと、です。
ようやっとhttpsでアクセスできるようになりました。
http://www.sakura.ad.jp/campaign/rapid_ssl/
申し込んでほぼ3週間。自分の申請に謝りがあったのが、良くなかったのですが、サポートの方とやりとりして、ようやくSSLでアクセスできるようになりました。
オレオレ証明書の赤いのが出ないし、信頼できないサイトかもよーの手間が省けるので、すごく快適です。
以前やろうとしたc++製markdownパーサのgithubでの公開、ようやくできた。前回はvagrantの環境作成で止まったが、結局ubuntu 12.04を無理やり使うのはやめて14.04のvmを新たに作った。
公開するのにサイト名とかいろいろハードコーティングだったのを設定ファイルに追い出す修正をするだけで、すごい時間がかかってしまった。まだ他にも気になる点はいろいろあるけど、直してると2015年終わっちゃうので、とりあえず公開した。
以前作ったc++製のmarkdownパーサ。githubで公開しようと思ったら自分のドメインベタ書きでとても無理だった。なので、真っ当にテスト環境で直して本番で試してみようと考えた。vagrantの環境はubuntu 12.04があるので、そこにコードを持っていく。
vagrantでは鍵を作ってなかったので、作成して、.ssh/id_rsa.pubの内容をこのドメインのユーザの.ssh/authorized_keysにコピペして追加。
ssh ユーザ名@boltech21.net -p sshのポート番号
sshでつながることを確認したら、コードをがっさーと持ってくる。
git clone ssh://ユーザ名@boltech21.net:ポート番号/.gitのあるパス vagrantのディレクトリ名
コードは持ってこれたので、とりあえずmakeしようと思ったら、gccのバージョンが古いそうで-std=c++11がなんだかわからん。と怒られた。
C++11のためにGCCの最新版をインストールする | 金星☆ちゃんねる
先人の知恵を拝借し、gcc 4.8をインストール。
boostも必要だったので、インストール。これもvpsとバージョンが違う…
やっぱりコンパイルエラーが出た。boostのエラー大量過ぎて読む気にならない。素直に環境を合わせようか。