nginx+Django+CodeRedCMSを立てた件 備忘録

# PythonでCMS...の続き
この前試してみた Django+Wagtailは使いやすく、結構気に入りました。
[UbuntuでDjango+Wagtail+PuputのCMSでBlogを作る件 備忘録](https://qiita.com/sekirei/items/a611ec4a5e8227e6ddd0)

さらに調べてみたところ **CodeRedCMS**というWagtailをカスタマイズする形でさらに表現力を高めたCMSスタックがあることを知りこれも試してみることにしました。
本家⇨[Build a Better Website with CodeRed CMS](https://www.coderedcorp.com/cms/)
Bootstrap4を使っていたり、完全にOpenSourceである事を謳っていたりします。
~~（そんなことより物騒な名前を変えろよ、とは思います。笑）~~

今回は、nginxに繋いでサンプル運用もしてみようかと思います。
apacheでも良いと思いますが、単にwsgiの設定がnginxの方が馴染みがあったというのが理由。


## サマリー
1.ConoHaでUbuntuサーバを借りて、pythonの環境を作る
2.Django、Wagtail、puputをインストール
3.CodeRedCMSをインストール
4.お試しサイトの作成
5.お試しサイトの実行とページの作成／編集
6.uWSGIをインストール
7.nginxをインストール
8.devからprodに変更してnginxにつなぐ
9.staticの扱いをなんとかする

## 1.ConoHaでUbuntuサーバを借りて、pythonの環境を作る
- 前回同様、ConohaのVPSです。ConoHaのUbuntu 64/512イメージを選択しましたが、18.04が用意されていたので折角なのでこれを使います。
- 作業用にユーザ "workuser" を作りましたが、wheelがなく、sudoというgroupに入れました。

```
# gpasswd -a workuser wheel
gpasswd: group 'wheel' does not exist in /etc/group
# gpasswd -a workuser sudo
Adding user workuser to group sudo
```
- サンプル運用したいため各種設定。これは省略。
- Pythonの環境をどうしようかと思いましたが、今回はここに手間をかけることをやめてみます。Python3.6は入っていたのでそのまま使うことにしました。サーバ内でPython環境を複雑にしてしまうよりも別環境用にサーバを借り直した方が時間コストがかからないと思ったためです。というわけで... 

```
# apt install python3-pip 
```
- 以降ここでの説明は python3とpip3を使っての作業になります。ご自分の環境でお試しの際は適宜読み替えてください。



## 2.Django、Wagtail、puputをインストール
この辺りのものをインストールするのは引っかかりどころはほぼないと言ってよさそうです。

```
# pip3 install django
# pip3 install wagtail
# pip3 install --upgrade pip3
# pip3 install wheel
# pip3 install wagtail django-colorful django-el-pagination django-social-share
# pip3 install --no-deps puput 
```

## 3.CodeRedCMSをインストール

```
# pip3 install coderedcms
```
以上

## 4.お試しサイトの作成
ここからは作業ユーザでやりました。crcsiteという名前にしました。[c]ode [r]ed [c]msという頭文字から取りました。ここはどんな名前でもよい。

```
# su workuser
$ coderedcms start crcsite --sitename "YourSite" 
$ cd crcsite
```
ディレクトリが作成され必要なファイルが配置されるのですが、やはり Django初心者を迷子にさせる二重のディレクトリ構造は健在です。
crcsiteのプロジェクトディレクトリの中にcrcsiteという同じ名前のディレクトリが作られました。

ここでblogアプリのpuputの設定もしたのですが、説明の流れがわかりにくくなるので記述を閉じておきます。<details><summary>puputのための設定</summary><div>

```
$ cd crcsite/settings/
$ vi base.py ※１
$ cd ..
$ vi urls.py ※２
$ cd ..
```
※１

```base.pyの編集箇所
INSTALLED_APPSに追加
--------
'wagtail.contrib.sitemaps',
'wagtail.contrib.routable_page',
'django_social_share',
'puput',
'colorful',
--------

末尾に追加
--------
PUPUT_AS_PLUGIN = True
--------
```
※２

```urls.pyに追加
from django.conf.urls import include, url

from wagtail.core import urls as wagtail_urls
from puput import urls as puput_urls　　★普通はこれだけのようだけれども上の二つがないとエラーになる

---
urlpatterns = [
    # Admin
    path('django-admin/', admin.site.urls),
    path('admin/', include(coderedadmin_urls)),

    url(r'',include(puput_urls)),   　★これと
    url(r'', include(wagtail_urls)),　★これをいれておいた。
```
</div></details>

## ５.お試しサイトの実行とページの作成／編集
あとはWagtailそのままの操作になります。
xxx.xxx.xxx.xxxはVPSのアドレス。ポートは8080にしましたがなんでも可。

```
$ python3 manage.py migrate
$ python3 manage.py createsuperuser
$ python3 manage.py runserver xxx.xxx.xxx.xxx:8080
```
ブラウザで http://xxx.xxx.xxx.xxx:8080/admin で管理画面に入ります。
管理画面で作成できるページはWagtailのデフォルトの状態に比べてかなり作成できるページの表現力が高く楽しいものが作れます。そもそもWagtailでも（というか素のDjangoでも）テンプレートを作って拡張していく仕組みなので自分で書いていけば良いわけですが、CodeRedCMSではここまでやれば、次はページの作成に入れるというところが嬉しい。
管理・編集画面はこんな感じ。アップロードした画像ををページの中で使用しているところ。
Settingsのペインを開けてあります。
デザインはWagtailそのものですが設定できる機能が大幅に増えています。
![crc-admin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358557/8571ebd9-91cf-653c-1766-9362f2650c39.png)


試しに作ってみたページはこんな風なもの。
多分30分くらいでできたと思います。素材を加工してる時間の方が長い。
![crc-testsite.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358557/8f27a236-ba54-674a-b72d-d8aac17f5fb7.png)


## 6.uWSGIをインストール
nginxとの接続は WSGIで行います。
WSGIというのがWebサーバとアプリケーションのインターフェースの仕様で、その仕様に沿ってDjangoアプリケーションをnginxに橋渡ししてくれるuWSGIというモジュールを使います。
uWSGIのインストールは以下のように。

```
# pip3 install uwsgi
```
このモジュールの口になる設定が必要で、サイトのアプリのディレクトリにあります。
今回なら ```crcsite/crcsite/wsgi.py```です。

```wsgi.py
import os
from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "crcsite.settings.dev")
```
最後の行の```crcsite.settings.dev``` というところを見ると、開発用の設定ということになります。
**ここは後でprodにします。**

```manage.py runserver```の代わりに以下のようにするとブラウザでも出力が確認できます。

```
$ cd crcsite/crcsite
$ sudo uwsgi --http :8080 --module crcsite.wsgi
```


## 7.nginxをインストール
以下のようにしてnginxをインストールして起動。

```
# apt update
# apt show nginx
# apt install nginx
# nginx -v
nginx version: nginx/1.16.0
# nginx
```
うまく動作していれば、ポート８０でブラウザからアクセスすると```Welcome to nginx! ...ほにゃらら```と表示されます。

ここまででuWSGIとnginxが動作してることが確認できたので、次はprodにしてつなぎます。


## 8.devからprodに変更してnginxにつなぐ
先ほどの```crcsite/crcsite/wsgi.py```をprodに修正します。

```wsgi.py
import os
from django.core.wsgi import get_wsgi_application

#os.environ.setdefault("DJANGO_SETTINGS_MODULE", "crcsite.settings.dev")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "crcsite.settings.prod")
```

nginxの方は```/etc/nginx/conf.d/default.conf```のlistenポート、サーバ名、ルートパス（”/”）を変更しました。

```default.conf
server {
    listen       8080;
    server_name  xxx.xxx.xxx.xxx;

    #charset koi8-r;
    access_log  /var/log/nginx/host.access.log  main;

    location / {
        uwsgi_pass  127.0.0.1:8081;
        include     /home/workuser/crcsite/uwsgi_params;        
    }

　　...
```

```include     /home/workuser/crcsite/uwsgi_params``このuwsgi_paramsという拡張子もないファイルの中身は以下のようになってます。検索してみるとこの内容で決定版らしくこのまま使いました。

```uwsgi_params
uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;
```

```uwsgi_pass  127.0.0.1:8081```はサーバ内localのポートを指定ということになります。

127.0.0.1:8081をnginxで指定しているので、これを--socketで指定してuwsgiを起動します。
(先ほどの動作確認の時は --http で指定していたので注意)
ざっくり言ってDjangoのつなぎ先は127.0.0.1:8081ですよ、という指示です。

```
$ cd crcsite
$ sudo uwsgi --socket 127.0.0.1:8081 --module crcsite.wsgi --chmod-socket=666 &
```


nginxを再起動

```
$ sudo pkill nginx
$ sudo nginx
```

ブラウザからはnginxのserverの記述に書いた8080ポートでアクセスします。

```
http://xxx.xxx.xxx.xxx:8080/admin
```

アクセスできた！...けれどレイアウトがおかしい、絵も出ない...



## 9.staticの扱いをなんとかする
staticのパスの下にあるcssやjsにアクセスできないと、使い物になりません。
devからprodにするときには/static/のパスを修正することになります。

```/etc/nginx/conf.d/default.conf``` には以下のようにstaticとmediaを追記しました。


```default.conf
server {
    listen       8080;
    server_name  118.27.0.30;

    #charset koi8-r;
    access_log  /var/log/nginx/host.access.log  main;

    location / {
        uwsgi_pass  127.0.0.1:8081;
        include     /home/workuser/crcsite/uwsgi_params;        
    }

    location /static/ {
        root /home/workuser/crcsite;
    }

    location /media/ {
        root /home/workuser/crcsite;
    }
　　...
```

上記のようにnginx側が見るところを指定しておいて、アプリ側ではstaticな物をまとめてコピーしてくれるというcommandを試してみることに。
アプリのディレクトリで投入。

```
$ cd crcsite
$ python3 manage.py collectstatic
```


uwsgiとnginxを再起動

```
$ sudo pkill uwsgi
$ sudo uwsgi --socket 127.0.0.1:8081 --module crcsite.wsgi --chmod-socket=666 &
$ sudo pkill nginx
$ sudo nginx
```

以上でnginx経由でCodeRedCMSを使えるようになりました。