自作ソシャゲ用テスト環境作成ログ その2

前=> https://qiita.com/Rwf-9DH3/items/4e1d1d189810c9d8b847

今回設定するのは
・Djangoプロジェクト作成
・ポート設定と確認
・NginxとUwsgiのsocket使った連携設定

#とりあえずSUDO設定
Root権限で下記コマンドを実行すると、
sudoコマンドの許可設定が編集できるようなので末尾に1行追加します。

```
# visudo 
```
```/etc/sudoers.tmp
(一般ユーザー名) ALL=(ALL) ALL
```
ここまでやったら、以降の作業は全て、一般ユーザー権限で実行します。
#Djangoのプロジェクト初期化
とりあえずの確認を済ませたいので、セキュリティ周りを一度切ります。

```
$ sudo systemctl stop firewalld
$ sudo systemctl stop nginx
```
次に、Djangoのプロジェクトを作成します。
前回記事で作った、manage.py ファイルがあるディレクトリで下記を実行。

```
$ cd /home/(ユーザー名)/
$ django-admin startproject app
$ cd app/
```
こうすると、下記のようなファイル構造が出来るのでsettings.pyを一部編集します。

```
/home/(一般ユーザー名)/app
　　/app
　　　　__init__.py
　　　　settings.py
　　　　urls.py
　　　　wsgi.py
　　manage.py
```

```settings.py
(前略)
ALLOWED_HOSTS = [
    '(IP or ドメイン)',
]
(中略)
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'appdb',
        'USER': '(MariaDBの一般ユーザー名)',
        'PASSWORD': '(MariaDbの↑用パスワード)',
        'HOST': 'localhost',
        'PORT': '3306',
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
        },
    },
    'master' : {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
(中略)
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
```
次に、下記コマンドを実行してから、Webブラウザで「http://(IPかドメイン)」を実行すると
正常に設定完了していれば、日本語で説明の書いてあるページが出ます。

```
$ sudo python manage.py runserver 0.0.0.0:80
```
次に、下記コマンドを実行した後、「http://(IPかドメイン)/admin」を実行すると
IDとパスワードを要求される画面が表示されます。

```
$ python manage.py migrate
$ python manage.py createsuperuser
$ sudo python manage.py runserver 0.0.0.0:80
```
2行目で登録したID/パスワードでログインして、エラー等でなければとりあえずの初期化は完了になります。

# ポート設定と確認
下記コマンドを流してください。

```
$ sudo systemctl start firewalld
```
この後、先程開いたWebページにブラウザで再アクセスしようとするとエラーが出ます。
何故かと言うと、Webブラウザの外部接続に対応するポートが存在しないから。
というわけで、開けます。

```
$ firewall-cmd --get-active-zones
$ firewall-cmd --get-services
$ sudo firewall-cmd --permanent --zone public --add-service http
$ sudo firewall-cmd --reload
$ sudo python manage.py runserver 0.0.0.0:80
```
「http://(ドメイン)/admin」に再アクセスしてページ開けられれば設定完了しました。
このコマンド群が何をやっているのかというと、80番ポートを外部アクセス可能な設定にしています。
http という名前で80番ポートがファイアーウォールには元々設定されていまして、
これをpublic 設定に加えることで、初めてWebブラウザなど外部からアクセス可能になっているわけです。
ちなみに、runserver の最後の 80 はこの80番ポートを使う、という宣言である模様。

#NginxとUwsgiのsocket通信
まずUwsgi単体の動作試験を行います。

```
$ cd /home/(一般ユーザー名)/app/
$ sudo uwsgi --http :80 --module app.wsgi
```
これで今までに開いたページが何かしら開ければ動いてます。

#nginxとuwsgi設定
NginxとUwsgiは、socketファイルで関連付けを行います。
このためにフォルダを作成します。なお、権限は一般ユーザーアカウントを使えるように調整。

```
$ sudo mkdir -p /var/run/uwsgi
$ sudo chown -R (一般ユーザー名).(一般ユーザー名) /var/run/uwsgi/
```
次に、Nginxの設定を書き換えます。

```
$ sudo mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
$ sudo vi /etc/nginx/nginx.conf
```
```/etc/nginx/nginx.conf
user (一般ユーザー名);
worker_processes 1;

error_log /var/log/nginx/error.log warn;

events {
    worker_connections  1024;
    use epoll;
}

http {
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_host" "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;
    tcp_nopush      on;
    keepalive_timeout  120;

    server {
        listen       80;
        server_name  (サーバーのドメイン名);

        set $deny_f 0;

        if ( $deny_f = 1) {
            return 403;
        }

        location /project/ {
            include /etc/nginx/uwsgi_params;
            uwsgi_pass unix://var/run/uwsgi/uwsgi.sock;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
```
Q.これの具体的な設定内容って何？
A.すみません、拾い物を幾つか比較して継ぎ接ぎしたのでよくわかんないです！

ただ、特に重要なところは server{} 内です。
server_nameでドメイン等指定していますが、location /project/ {} というものを追加しています。
要するに、このアプリのURLは全て「http://(ドメイン名)/project/～～」にする、という設定にしてます。
location / {} でも多分大丈夫、というより大丈夫だったんですが、今回はこれで行こうと思います。

保存し終えた後に、設定ファイルの構文チェックとNginx再起動を行います。

```
sudo nginx -t
sudo systemctl restart nginx
```
http://(ドメイン)/ にアクセスしてNginx表記の出ている英語ページが出れば、とりあえず動いてます。
これが終わり次第、下記コマンドを実行してみてください。

```
$ uwsgi --socket /var/run/uwsgi/uwsgi.sock --wsgi-file /home/(一般ユーザー名)/app/app/wsgi.py --chdir /home/(一般ユーザー名)/app --thunder-lock --master --enable-threads --uid (一般ユーザー名)
```
多分初回はこれ動かないと思います。
nginxの設定ファイルでエラーログを生成しているので /var/log/nginx/error.log を確認するとわかりますが、
Socketをpermission denied(権限がない)という理由で使えない、と表記されています。
で、なぜ権限がないか、というとソケット使用がSELinuxというもので使用を制御されているからです。
というわけで、とりあえずSELinuxの状態を変更しましょう。

本当は対象Socketファイルをホワイトリスト登録するのが正しいらしいのですが、
今回は面倒くさいし本番環境ではないので、ガチ制御モードから、エラーログ出力モードに切り替えます。

```
$ getenforce
  -> Enforcing になってたら下記2行を流します
$ sudo setenforce 0
$ getenforce
  -> Permissive になってたら成功
```

もう一回先程の uwsgi コマンドを実行すれば、Webブラウザのアクセスが成功すると思います。
成功したら、次はuwsgiをデーモン化して、バックグラウンド処理されるようにします。
下記のようなフォルダ階層、およびファイルを作ってください。
uwsgi.log はファイルだけ作って中身自体は空で大丈夫です。

```
/home/(一般ユーザー名)/app
　　/app
　　/etc
　　　　uwsgi.ini
　　/log
　　　　uwsgi.log
　　manage.py
```
```uwsgi.ini
[uwsgi]
chdir=/home/(一般ユーザー名)/app
wsgi-file=/home/(一般ユーザー名)/app/app/wsgi.py
socket=/var/run/uwsgi/uwsgi.sock
master=True
thunder-lock=True
enable-threads=True
pidfile=/home/(一般ユーザー名)/app/etc/uwsgi.pid
daemonize=/home/(一般ユーザー名)/app/logs/uwsgi.log
```
完了後、下記を流して、コマンドラインがログ表示にならず、
Webページが今までと違う表示になっていればnginxとuwsgiの設定は完了しました！

```
$ uwsgi --ini /home/(一般ユーザー名)/app/etc/uwsgi.ini
```
#Django側のURL修正
多分今の設定だと下記ページにアクセスした時404エラーとか出ると思います。
http://(ドメイン)/project/admin/

```/home/(一般ユーザー名)/app/settings.py
urlpatterns = [
#    url(r'^admin/', admin.site.urls),
    url(r'^project/admin/', admin.site.urls),
]
```

uwsgiコマンドをもう一度叩くと更新が反映されるので、
その後に再度ページアクセスすれば、こちら修正されるはずです。