プラグインを入れて Markdown で投稿できるようになった!!(これも後々記事にする)
今回は、このブログを立てるにあたってやったことをまとめるよ。
今回は CentOS7 を使っています。
Amazon Linux2 を使ったら extra でのインストール苦しんだので諦めました。
つまづくポイントが多いので、段階を踏んで確認していきます。
ここまで問題なければ、次回の記事で Python 製 CMS の Mezzanine を入れて再度 0 からプロジェクトを作成し直します。
$ vi /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1
$ yum install nginx
$ nginx -v
nginx version: nginx/1.15.5
$ sudo systemctl enable nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
実は Postgres をちゃんと使うのは初めて。せっかくだから新しい 11 を入れる。 参考: https://soudai.hatenablog.com/entry/2018/10/08/023918
$ sudo yum update
$ sudo yum localinstall https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-7-x86_64/pgdg-centos11-11-2.noarch.rpm
$ sudo su postgres
bash-4.2$ /usr/pgsql-11/bin/initdb -E UTF-8 --no-locale -D /var/lib/pgsql/11/data
bash-4.2$ exit
$ sudo systemctl start postgresql-11.service
$ sudo systemctl enable postgresql-11.service
Created symlink from /etc/systemd/system/multi-user.target.wants/postgresql-11.service to /usr/lib/systemd/system/postgresql-11.service.
$ psql -V
psql (PostgreSQL) 11.0
$ sudo passwd postgres
$ su postgres
パスワード:
bash-4.2$ cd
bash-4.2$ pwd
/var/lib/pgsql
bash-4.2$ psql
注意: DB 名を大文字にしたけど、小文字で登録されたみたい。( ポスグレは大文字小文字が区別される??)
postgres=# CREATE DATABASE [DB名] LC_COLLATE 'C' LC_CTYPE 'C' ENCODING 'UTF8' TEMPLATE template0;
CREATE DATABASE
postgres=# CREATE USER [ユーザ名] WITH PASSWORD '******';
CREATE ROLE
postgres=# ALTER ROLE [ユーザ名] SET client_encoding TO 'utf8';
ALTER ROLE
postgres=# ALTER ROLE [ユーザ名] SET default_transaction_isolation TO 'read committed';
ALTER ROLE
postgres=# ALTER ROLE [ユーザ名] SET timezone TO 'UTC+9';
ALTER ROLE
postgres=# GRANT ALL PRIVILEGES ON DATABASE BLOG TO [ユーザ名];
GRANT
postgres=# \q
bash-4.2$
参考: https://qiita.com/tinaba/items/01bc72c100f97438a36e
$ sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
$ sudo yum install -y python36u python36u-libs python36u-devel python36u-pip psycopg2-binary
$ python3.6 -V
Python 3.6.5
$ pip3.6 -V
pip 9.0.1 from /usr/lib/python3.6/site-packages (python 3.6)
今回、ブログ関係のファイルは/opt/blog/に配置します。
また、CentOS7 自体には python2 系のパスが通ってしまっているため、
venv で Python3 系の仮想環境を作って、その上で Django のプロジェクトを動かします。
[tenn25@ip-10-0-0-51 blog]$ pwd
/opt/blog
[tenn25@ip-10-0-0-51 blog]$ sudo python3.6 -m venv py36
[tenn25@ip-10-0-0-51 blog]$ ll
合計 0
drwxr-xr-x. 5 root root 74 10月 21 21:01 py36
[tenn25@ip-10-0-0-51 ~]$ source py36/bin/activate
(py36) [tenn25@ip-10-0-0-51 ~]$
(py36) [tenn25@ip-10-0-0-51 ~]$ sudo chown tenn25:tenn25 py36 -R
(py36) [tenn25@ip-10-0-0-51 ~]$ ll
合計 0
drwxr-xr-x. 5 tenn25 tenn25 74 10月 21 01:51 py36
(py36) [tenn25@ip-10-0-0-51 ~]$ pip install django gunicorn psycopg2 Pillow
Installing collected packages: pytz, django, gunicorn, psycopg2, Pillow
Successfully installed Pillow-5.3.0 django-2.1.2 gunicorn-19.9.0 psycopg2-2.7.5 pytz-2018.5
インストールができたので、Django のプロジェクトを作成します。
コンソールの左に(仮想環境名)が表示されてる状態で行います。
仮想環境の起動は source [インストールパス]/py36/bin/activate
仮想環境の停止は deactivate です。
(py36) [tenn25@ip-10-0-0-51 ~]$ django-admin startproject blog
(py36) [tenn25@ip-10-0-0-51 ~]$ ll
合計 0
drwxrwxr-x. 3 tenn25 tenn25 35 10月 21 02:03 blog
drwxr-xr-x. 5 tenn25 tenn25 100 10月 21 01:55 py36
プロジェクトルートの名前も blog にしてしまったせいで
階層が非常にわかりづらくなってしまった。。
/opt/blog は自分で作成した作業ディレクトリです。
その下に Django プロジェクト[blog]を作成しました。
(py36) [tenn25@ip-10-0-0-51 blog]$ pwd
/opt/blog
(py36) [tenn25@ip-10-0-0-51 blog]$ sudo vi blog/blog/settings.py
今回は Postgresql を使うので ENGINE は以下のように記載する。
ALLOWED_HOSTS = ['tenn25.com']
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
DATABASES = {
'default': {
#'ENGINE': 'django.db.backends.sqlite3',
'ENGINE': 'django.db.backends.postgresql_psycopg2',
#'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'NAME': 'blog',
'USER': 'tenn25',
'PASSWORD': '**********',
'HOST': 'localhost',
'PORT': '',
}
}
アプリケーションで使うデータベースの定義を自動的に作成して DB に反映する機能を migration と言うらしい。
makemigration→migrate の順に行う。
(py36) [tenn25@ip-10-0-0-51 blog]$ pwd
/opt/blog/blog
(py36) [tenn25@ip-10-0-0-51 blog]$ ls
blog manage.py
(py36) [tenn25@ip-10-0-0-51 blog]$ python manage.py makemigrations
/opt/blog/py36/lib64/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
""")
No changes detected
(py36) [tenn25@ip-10-0-0-51 blog]$ pip install psycopg2-binary
(py36) [tenn25@ip-10-0-0-51 blog]$ python manage.py makemigrations
No changes detected
(py36) [tenn25@ip-10-0-0-51 blog]$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying sessions.0001_initial... OK
アプリケーションサーバをいれなくても、
Python 自体にその機能がある。一旦それで起動。
(py36) [tenn25@ip-10-0-0-36 blog]$ python manage.py runserver 0.0.0.0:8000
Performing system checks...
System check identified no issues (0 silenced).
October 21, 2018 - 02:33:54
Django version 2.1.2, using settings 'blog.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
Django には元から Web ページの管理者用ページが用意されている。
その管理者ユーザを作成する。
Django は manage.py からいろんな作業を行う。
manage.py がある階層で以下のコマンドを実行。
(py36) [tenn25@ip-10-0-0-51 blog]$ python manage.py createsuperuser
ユーザー名 (leave blank to use '*****'): **********
メールアドレス: **********@*****.***
Password:
Password (again):
Superuser created successfully.
次はアプリケーションサーバの gunicorn つかう。
フォルダ内の wsgi.py を使うという指定をする
(py36) [tenn25@ip-10-0-0-51 blog]$ which gunicorn
opt/blog/py36/bin/gunicorn
(py36) [tenn25@ip-10-0-0-51 blog]$ gunicorn --version
gunicorn (version 19.9.0)
(py36) [tenn25@ip-10-0-0-51 blog]$ pwd
/opt/blog/blog/blog
(py36) [tenn25@ip-10-0-0-51 blog]$ gunicorn --bind 0.0.0.0:8000 blog.wsgi
[2018-10-21 21:15:36 +0900] [1484] [INFO] Starting gunicorn 19.9.0
[2018-10-21 21:15:36 +0900] [1484] [INFO] Listening at: http://0.0.0.0:8000 (1484)
[2018-10-21 21:15:36 +0900] [1484] [INFO] Using worker: sync
[2018-10-21 21:15:36 +0900] [1487] [INFO] Booting worker with pid: 1487
.service ファイルを作ってサービスとして登録しよう
(py36) [tenn25@ip-10-0-0-51 ~]$ sudo vi /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=tenn25
Group=tenn25
WorkingDirectory=/opt/blog/blog
ExecStart=/opt/blog/py36/bin/gunicorn --access-logfile - --workers 3 --bind 0.0.0.0:8000 blog.wsgi:application
[Install]
WantedBy=multi-user.target
いったん上記の設定をして確認しよう。
注意点として、blog.wsgi というのは[blog/wsgi.py]を意味している
wsgi.py へのパスが通るように /opt/blog/blog/blog/wsgi.py となるように WorkingDirectory にも注意すること。
[tenn25@ip-10-0-0-36 system]$ sudo systemctl daemon-reload
[tenn25@ip-10-0-0-36 system]$ sudo systemctl restart gunicorn
[tenn25@ip-10-0-0-36 system]$ sudo systemctl enable gunicorn
[tenn25@ip-10-0-0-36 system]$ sudo systemctl status gunicorn
● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; enabled; vendor preset: disabled)
Active: active (running) since 日 2018-10-21 12:36:40 JST; 9s ago
問題なければ、bind をソケットファイルに変更しよう。
Web サーバとアプリケーションサーバは同じサーバを想定してるので、http ではなく、
Unix ドメインソケットを使ったサーバ内部のソケット通信にすることで、通信速度が早くなる。
(gunicorn はこれに対応している。)
そのために、上記の bind 設定を以下のように変更する。
# ExecStart=/opt/blog/py36/bin/gunicorn --access-logfile - --workers 3 --bind 0.0.0.0:8000 blog.wsgi:application
ExecStart=/opt/blog/py36/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/tenn25/blog/blog.sock blog.wsgi:application
こうすることで、8000 番ポートは使わずに 80 番 →Nginx→Unix ドメインソケット →gunicorn という流れになる。 サービスファイルを変更したら、改めて systemctl で再読み込み/再起動をしよう。
cd /etc/nginx/conf.d/
sudo mv default.conf default.conf.org
sudo cp default.conf.org blog.conf
upstream app_server {
server unix:/opt/blog/blog/blog.sock;
}
server {
listen 80;
server_name www.tenn25.com;
location = /favicon.ico {access_log off; log_not_found off;}
location / {
include proxy_params;
proxy_pass http://app_server;
# proxy_pass http://localhost:8000; ←8000番でgunicornが受ける場合はこう
}
}
$vi /etc/nginx/proxy_params
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
https://webcurtaincall.com/articles/1
(py36) [tenn25@ip-10-0-0-51 nginx]$ sudo cat /var/log/audit/audit.log | grep nginx | grep denied
type=AVC msg=audit(1540124576.312:226): avc: denied { name_connect } for pid=1618 comm="nginx" dest=8000 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:soundd_port_t:s0 tclass=tcp_socket
type=AVC msg=audit(1540124576.312:227): avc: denied { name_connect } for pid=1618 comm="nginx" dest=8000 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:soundd_port_t:s0 tclass=tcp_socket
type=AVC msg=audit(1540124719.818:241): avc: denied { name_connect } for pid=1618 comm="nginx" dest=8000 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:soundd_port_t:s0 tclass=tcp_socket
type=AVC msg=audit(1540124719.818:242): avc: denied { name_connect } for pid=1618 comm="nginx" dest=8000 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:soundd_port_t:s0 tclass=tcp_socket
どこのパスを示してるのかは、常に注意すること。
ここまでで、各サービス再起動してあげればブラウザの 80 番ポートからアクセスできるはず。
お疲れ様でした。