Python
WordPress
teraterm
チュートリアル
lamp構築

LAMP+Wordpress+Python(Django)のセットアップメモ2018

はじめに

あーでもないこーでもない、さんざんOSいじりをしたあとで、なにをして今の状態になったかわからん:innocent:ということは往々にしてある。そこで何度もOSインストールからやりなおしてつっかえたところを一つ一つクリアーにしていったらいい経験になった。いままでの環境はなんだかんだで誰かの環境を借りたり(=もとの設定内容がわからない)してたから、今回は自分でVPS借りて、ドメインも買ったので、LAMP入門者用のチュートリアルにもなるぐらいには磨き上げたと思う。あんなに黒い画面が嫌いだった僕も、慣れてみればいいもんだね。ここはどこ?わたしは誰?みたいに覚えゲーの感じだけど、無駄がないもんね。

この記事を読む人はどんな人?

・Linux入門者(=僕)
・URLを打ち込むようなよくあるWebアプリが作りたい人
・しかもお名前.comで取得したドメインをたこ足配線してWebアプリやHPとか複数動かしたい人
・Web上にWordpress作りたい人
・Web上でPHP動かしたい人
・Web上でPython動かしたい人

私の環境

VPSとは Virtual Private Server の略だ。
つまり、Linuxを入れるといいながらその入れる先はインターネッツの先にある、契約済みのサーバーである。
つまり私は以下の環境でサーバーを遠隔構築している、ということ。
・Windows10
・TeraTerm

ここでやること

  1. LAMPのセットアップ
  2. ネームサーバーの設定
  3. WordPress環境構築
  4. Python環境の構築(Anaconda + Django)
  5. GitHubのセットアップ
  6. FTPのセットアップ
  7. PHPでダッシュボードを作る
  8. Pythonでダッシュボードを作る

VPSの契約は終わったという前提で始めるよ
あと、リンク張って省力化できるところはするよ

これからつくるLAMP環境について

先頭の文字を取って「LAMP」ね
・Linux(CentOS release 7.4)
・Apache 2.4.6
・MySQL 5.7
・PHP 7.1

SPECIAL THANKS

ココナラのcoreKeiさん
できるだけ自分で勉強・整理したうえで最後に人に頼ったら一気に点が繋がった!
どうしても理解したい!でも時間がない!そんなときは時間を買おう!

株式会社日本システム技研ディレクター 中澤 祐一さん
DjangoからMySQLにつなげられなくて(原因はMySQLドライバーとDjangoの相性)、もうどういう質問すればいいのかもわからんぐらいのエラーメッセージと戦ってたときに、そういえばDjangoに詳しそうな人がFBの友達でいたな?と思って相談した人。彼のおかげでDjango開発のスタート地点に立てました!みんな、友達は財産なんやで:relaxed:

Linux

インストール

image.png

image.png

image.png
yum-update は WindowsUpdate みたいなもん(と思ってる)

Teraterm

接続拒否されるようならまだコンソールが動いているかも。表示されているIPはさくらのVPSを契約してもらったIP。変にモザイクかかってわかんなくなる記事とかあるじゃん?めんどくさいからそういうのはしない。IPもポート番号もむき出しで行く。ハックされようが大したシステムは置かない実験室だしね:stuck_out_tongue_winking_eye:
せーぜんせつせーぜんせつ

ポート番号は最初22です。これは業界標準(?)の数字だから狙われるんだって。あとで変えようね。
image.png

OK押したらこれが出るので、続行ボタンを押す
(既存の鍵を、新しい鍵で上書きする、にチェック)
image.png

OSインストールのときに root のパスワードを打ち込んだはずだ。
image.png

ログインできた!

image.png

最初の設定

CentOS 7(さくらのVPS)サーバ作成直後に設定しておくべき初期セキュリティ設定
ここ見て一発でできた!

なお、Teratermでの公開鍵認証の設定のためのリンクに飛ぶと、リンク先の項目5番の設定有効化コマンド(/etc/rc.d/init.d/sshd reload)が打てない。原因はCentOS6用のページであることが原因なので、確認しないまま元のリンク先に戻ってステップを進めればCentOS7用の設定有効化コマンド(sudo systemctl restart sshd)がある。一応流れを下に書くね。
ちなみにLinux初心者は、コンソール上の「\$」とか「#」がよくわかんなかったりするんだけど、「\$」のときは一般ユーザで操作している、「#」のときはroot権限を持つユーザで操作している、ということです(これもわかんなくて沼にハマったなぁ)。root権限は最低限の使い方しかしないから、ユーザの切り替えをよくするんだよね。コピペの時はこれらの記号のうしろの文字からコピペしてね(記号はあくまでモードを表しているだけ)。

最初の設定
a. ユーザの追加 op
    # useradd op

b. op ユーザに対するパスワードの設定
    # passwd op

c. TeraTermでSSH鍵生成して公開鍵と秘密鍵を保存
    id_rsa.pub
    id_rsa

d. TeraTermを閉じてログインしなおし ユーザは op
    $ pwd
    /home/op ←ホームディレクトリ

e. ホームディレクトリに id_rsa.pub をドラッグして「~/」でSCPする
    $ ls
    id_rsa.pub ←転送された!

f. 公開鍵認証の設定(先頭にドットがつくのは隠しフォルダ)
    $ mkdir .ssh
    $ chmod 700 .ssh
    $ cat id_rsa.pub > .ssh/authorized_keys
    $ chmod 600 .ssh/authorized_keys
    $ rm -f id_rsa.pub

g. sshd_configの編集(ポート番号など)
    $ su -
    # vi /etc/ssh/sshd_config
        Port 61203
        PermitRootLogin no
        PasswordAuthentication no

h. wheel グループに対する sudo 設定の有効化
    # usermod -G wheel op

i. 設定の有効化とステータス確認
    # systemctl restart sshd
    # systemctl status sshd

j. ファイアウォールのポート番号を 項番g の61203と合わせて、設定の有効化
    # vi /usr/lib/firewalld/services/ssh.xml
        port="61203"
    # firewall-cmd --reload

k. TeraTermを開きなおして、opの61203の秘密鍵でログインできるか確認(rootでログインできないことも確認)
    $

l. 次の作業のために root になっておく
    $ su -

国や地域の設定

CentOS7のlocaleを日本にする

Tips:localeを日本に
# localectl set-locale LANG=ja_JP.UTF-8
# source /etc/locale.conf
# localectl
# date

文字化け

TeraTermで日本語が化ける件あれこれ(locale変えて曜日が化けたらこれ。原因はTeraTermのConsolasフォント)

PHP

インストール

CentOS7にPHP7.1をyumでインストール

Tips:PHP7.1
# yum install epel-release
# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
# yum remove php-*
# yum install --enablerepo=remi,remi-php71 php php-devel php-mbstring php-pdo php-gd php-xml php-mcrypt
# php --version
# vi /etc/php.ini
php.ini
date.timezone = "Asia/Tokyo"
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_input = UTF-8
mbstring.http_output = pass
mbstring.encoding_translation = On
mbstring.detect_order = auto
mbstring.substitute_charset = none

Apache(Webサーバ)

インストール

さくらVPS(CentOS7)をWebサーバ化してHelloWorldする

Tips
# yum -y install httpd
# systemctl start httpd.service
# systemctl enable httpd.service
# firewall-cmd --zone=public --add-service=http --permanent
# firewall-cmd --add-port=80/tcp --zone=public --permanent
# firewall-cmd --reload

タイムゾーンを日本時間に変更する

タイムゾーンを日本時間(JST)に変更する CentOS 7, 6

Tips
# timedatectl set-timezone Asia/Tokyo
# timedatectl status

Tree

インストール

ツリー表示ができるようになる。スーパー便利

image.png

↑こんなイメージで /home/op に基本的にすべて(webページとアプリケーション)を置いていく

Tips:treeのインストール
# yum install tree

バーチャルホスト

バーチャルホストの設定
最初このバーチャルホストってわけわかめだったんだけど、さくらとの契約で手に入れた「153.126.200.229」を、http://www.henojiya.net と、http://app01.henojiya.net で2通りの使い方にしたいときに使うんだ(この時点では両方にアクセスしても apache のハローワールドの同じページが出てくるはずだ)。難しくてもいちばん概念を理解しないといけない場所だよ。

「/home/op/」に「web(WordPress)」と「app01(Python)」のコンテンツを作る
a. こんな感じで欲しいサブドメインの分だけディレクトリを量産する
    1. *.henojiya.netでアクセスしてきたとき用のハコの作成と権限設定
        # mkdir -p /home/op/web/public_html
        # mkdir -p /home/op/app01/public_html
    2. サブドメインで見れるか確認するためのファイル(index.html)を作る。
        # vi /home/op/web/public_html/index.html
            <html>
                hello from www.henojiya.net
            </html>
        # vi /home/op/app01/public_html/index.html
            <html>
                hello from app01.henojiya.net
            </html>
    3. 権限をまとめて op 扱いに
        # chown -R op:op /home/op

b. VirtualHostの設定(追記!)私は Listen 80 の記述の後に追記
    # vim /etc/httpd/conf/httpd.conf
        <Directory /home/op>
          Require all granted
        </Directory>
        DirectoryIndex index.html index.php
        ErrorLog /home/op/_error_log
        CustomLog /home/op/_access_log combined
        AddDefaultCharset UTF-8
        <VirtualHost *:80>
          ServerName www.henojiya.net
          DocumentRoot "/home/op/web/public_html"
        </VirtualHost>
        <VirtualHost *:80>
          ServerName app01.henojiya.net
          DocumentRoot "/home/op/app01/public_html"
        </VirtualHost>
            ・
            ・
            こんな感じで欲しいサブドメインの分だけ <VirtualHost>ディレクティブを追記

c. VirtualHostの設定(User Group を編集!)
    # vim /etc/httpd/conf/httpd.conf
        User op
        Group op

d. サービスの再起動
    # systemctl restart httpd 

アドレスアクセステスト

ネームサーバーを設定していないので、まだ app01 は機能しない
http://www.henojiya.net
http://app01.henojiya.net

ネームサーバーを設定

バーチャルホストと対にして覚えないといけない概念、ネームサーバー。これで大ハマりしてたよ。
考え方自体は ここ の設定の概要がわかりやすい。要は、お名前.comと、さくらVPSコントロールパネル両方での設定が必要だということ(以下に勘所は書くけどあくまで作業手順はリンク先を見てね)。

・お名前.comでドメインを取得する(省略)

・お名前.com のコントロールパネルに入る。
image.png

・さくらのVPSのネームサーバー情報は
「ns1.dns.ne.jp」
「ns2.dns.ne.jp」
となっており、この情報を、お名前.com のネームサーバー情報に設定する。
これはドメインネーム(=会社名)とIP(=電話帳)の台帳のようなモンで、お名前.comの台帳をつかってもいいし、さくらのVPSの台帳を使ってもいい。どっちで設定しても同じ効果。逆に言うと片方に書くようにしないとあとあと混乱を招く。
image.png

・取得したドメインを登録する(wwwとかはつけんくてよろしい)
image.png

・台帳たる、さくらの「ゾーン情報」のAレコードには、henojiya.netのIPアドレスが記帳されている。
Aレコードの設定とは?:ドメイン名がこのIPアドレスだよと指定すること。そしてここの「エントリの追加と変更」のとこに、欲しいサブドメインを登録するわけだ。
image.png

・「app01」が増えてるでしょ?いやー、このへんがドハマりしてげんなりしてた。相当勉強になった。
image.png

アドレスアクセステスト

それぞれ違うページが出てくるはず
http://www.henojiya.net
http://app01.henojiya.net

MySQL

インストール

MySQL 5.7 をインストールしたら最初に行うセットアップ

Tips
# rpm -qa | grep maria
mariadb-libs-5.5.50-1.el7_2.x86_64
# yum remove mariadb-libs
# rm -rf /var/lib/mysql/
# yum localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
# yum install mysql mysql-devel mysql-server mysql-utilities
# rpm -qa | grep mysql
# mysqld --version
# mysqld --user=mysql --initialize
# systemctl enable mysqld.service
# systemctl start mysqld.service
# systemctl stop mysqld.service
# systemctl restart mysqld.service
# grep password /var/log/mysqld.log
# mysql_secure_installation
初期パスワードを入力する(直前のgrepで出てきたランダムパスワード)
新しいパスワードを入力する
再度同じ新しいパスワードを入力する
y
0
y
ポリシーに沿った新しいパスワードを入力(さっきと同じでいい)
再度新しいパスワードを入力する
y
y
y
y
y
All done!

UTF-8

これな。MySQL のテーブルの文字コードを utf8 に変更する
「Server characterset」と「Db characterset」のところがlatin1でしょ?これに対処しておかないと、あとあとMySQLにInsertするときとかにハマる。

MySQL
mysql> status
  Connection id:          57459
  Current database:
  Current user:           root@localhost
  SSL:                    Not in use
  Current pager:          stdout
  Using outfile:          ''
  Using delimiter:        ;
  Server version:         5.7.21 MySQL Community Server (GPL)
  Protocol version:       10
  Connection:             Localhost via UNIX socket
  Server characterset:    latin1
  Db     characterset:    latin1
  Client characterset:    utf8
  Conn.  characterset:    utf8
  UNIX socket:            /var/lib/mysql/mysql.sock
  Uptime:                 106 days 4 hours 6 min 50 sec
CentOS
# vi /etc/my.cnf
my.cnf(一番下の行に追記)
character-set-server=utf8(結果的に[mysqld]セクションに書くことになる)
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqldump]
default-character-set=utf8
CentOS(MySQL再起動)
# systemctl restart mysqld.service
MySQL
mysql> status
  Connection id:          6
  Current database:
  Current user:           root@localhost
  SSL:                    Not in use
  Current pager:          stdout
  Using outfile:          ''
  Using delimiter:        ;
  Server version:         5.7.21 MySQL Community Server (GPL)
  Protocol version:       10
  Connection:             Localhost via UNIX socket
  Server characterset:    utf8
  Db     characterset:    utf8
  Client characterset:    utf8
  Conn.  characterset:    utf8
  UNIX socket:            /var/lib/mysql/mysql.sock
  Uptime:                 13 min 6 sec

MySQLWorkbench

GUI環境で接続することで取り回しがよくなる。
さくらVPS Ubuntu MySQLWorkbench でMysqlサーバーにssh 接続

接続の新規追加

image.png

image.png

SSH Hostname: 153.126.200.229:61203
SSH Username: op
SSH Password: (op ユーザーのパスワード)
SSH Key File: VPSでのログイン時に指定する rsa(秘密鍵)
MySQL Hostname: localhost
MySQL Server Port: 3306
Username:python
Password:(MySQLのpythonユーザーのパスワード)

image.png

ん? まぁいいか(笑)

WordPress

インストール

さぁ、ここからいよいよウワモノを作っていこう!
基本は ここ を見てもらって、いちおう下にもメモるね
・{MYSQLROOTPASSWORD} は、さっきMySQLのroot設定のときに決めたパスワード入れて
・SET GLOBAL validate_password_policy=LOW は非推奨
{MYSQLROOTPASSWORD} のパスワードが、MySQLの基準を通らなかっただけ(ォィ

Tips
・MySQLでデータベース「wordpress」を作成して権限変更
    # mysql -u root -p
    mysql> create database wordpress;
    mysql> show databases;
    mysql> SET GLOBAL validate_password_policy=LOW;
    mysql> grant all on wordpress.* to root@localhost identified by '{MYSQLROOTPASSWORD}';
    mysql> exit;

・Wordpressのダウンロード、解凍、権限変更
    # cd /home/op/web/public_html
    # wget https://ja.wordpress.org/wordpress-4.9-ja.tar.gz
    # tar xvzf wordpress-4.9-ja.tar.gz
    # rm -f wordpress-4.9-ja.tar.gz
    # mv wordpress/* .
    # rmdir wordpress
    # chown -R apache:op *
    # chmod -R g+w *

ここでドメインにアクセスしてみよう
http://www.henojiya.net/wp-admin

※こんなん出てくるねん

image.png
CentOS7 PHP7.1.2 お使いのサーバーの PHP では WordPress に必要な MySQL 拡張を利用できないようです。

Tips
# php -m | grep mysql

何も出力されない場合はphp-mysqlndをインストールします。
# yum install yum-utils
# yum-config-manager --enable remi-php71
# yum install php-mysqlnd

# php -m | grep mysql
mysqli
mysqlnd
pdo_mysql

pacheを再起動します。
# service httpd restart

ここでドメインにアクセスしてみよう
http://www.henojiya.net/wp-admin

Wordpress表示された!

ようやっとここまできたわ...
ちなみにデータベースの設定画面で送信すると wp-config ができる。
image.png

「ユーザー名」と「パスワード」は、MySQLの「root」とさっき決めたrootのパスワードです。
image.png

Tips(wp-config.phpが出来上がったタイミングで最後の行に追記)
# echo "define('FS_METHOD','direct');" >> wp-config.php

image.png

子テーマをつくる

子テーマを作ってWordPressの既存テーマをカスタマイズする
このリンク先はわかりやすいよ。
とりあえずテーマは Orfeo を選んで外観を Orfeo にして、有効化する。

Tips
WordPressテーマを入れた場所
# cd /home/op/web/public_html/wp-content/themes

「-child」というフォルダを作成:これは Orfeo というテーマを使う場合
# mkdir orfeo-child

フォルダを作成した場所
# cd ./orfeo-child

Viで開く
# vi functions.php
    <?php
    add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
    function theme_enqueue_styles() {
        wp_enqueue_style( 'parent-style',   get_template_directory_uri() . '/style.css' );
        wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array('parent-style')
    );
    }
    ?>
# vi style.css
    /*
     Theme Name:   orfeo child
     Template:     hestia
    */
Tips:テストで作ったindex.htmlは消しましょう
# rm -f /home/op/web/public_html/index.html

このタイミングで、子テーマ(orfeo-child)の有効化ができるはず

Python(Anaconda一択)

インストール

AnacondaのインストールはここのLinuxのパートを見よ!
データサイエンティストを目指す人のpython環境構築2016(Linux)

Tips
# cd /home/op/
# wget https://repo.continuum.io/archive/Anaconda3-4.3.1-Linux-x86_64.sh
# bash Anaconda3-4.3.1-Linux-x86_64.sh
利用規約がずらずら出るのでEnterおしっぱで yes or no と聞かれたら yes
どこにインストールすんの?って聞かれる(初期値 /root/anaconda3)ので「/home/op/anaconda3」でEnter
OSのPATH変数にAnacondaを追加するかどうか尋ねられるので yes
でもなぜか追加されないのでこれ
# export PATH=/home/op/anaconda3/bin:$PATH
念のためconda自体をアップデート
# conda update conda

バージョン確認コマンドが実行できた!
# python -V
Python 3.6.0 :: Anaconda 4.3.1 (64-bit)

# rm -f Anaconda3-4.3.1-Linux-x86_64.sh
# chown -R op:op /home/op

Tips:PATHを通す

PATHを通そう
「PATH=/home/op/anaconda3/bin:$PATH」を追記

CentOS
$ sudo vi .bash_profile
CentOS-vi
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin
PATH=/home/op/anaconda3/bin:$PATH

export PATH
CentOS
$ python -V
   Python 3.6.0 :: Anaconda custom (64-bit)

Django

なんでこんなにややこしいんや...クッソハマったわ...:poop:

インストール

インストールしたら pip list で Django が入っているか確認

Tips
# cd /home/op/
# pip install django
# pip list

Apacheの設定

Apacheのmod_wsgiを導入してPythonを実行する

Tips(Anacondaがどこにインストールされたか知る)
# python -c "import sys; print(sys.path)"
Tips
# cd /home/op
# yum -y install httpd-devel
# yum -y install gcc
# yum -y install make
# yum -y install python-devel
# pip install mod_wsgi
# pip install mod-wsgi-httpd ←※インストールにかなり時間が掛かる。5分~10分くらい掛かるのでじっくり待つ

バーチャルホストを設定 をしたけど、あれを改造する

Tips
# vi /etc/httpd/conf/httpd.conf
httpd.conf(修正前)
<Directory /home/op>
  Require all granted
</Directory>
DirectoryIndex index.html index.php
ErrorLog /home/op/_error_log
CustomLog /home/op/_access_log combined
AddDefaultCharset UTF-8
<VirtualHost *:80>
  ServerName www.henojiya.net
  DocumentRoot "/home/op/web/public_html"
</VirtualHost>
<VirtualHost *:80>
  ServerName app01.henojiya.net
  DocumentRoot "/home/op/app01/public_html"
</VirtualHost>
httpd.conf(修正後)
LoadModule wsgi_module /home/op/anaconda3/lib/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so
WSGIPythonHome /home/op/anaconda3/
ErrorLog /home/op/_error_log
CustomLog /home/op/_access_log combined
AddDefaultCharset UTF-8
<VirtualHost *:80>
  ServerName www.henojiya.net
  DocumentRoot "/home/op/web/public_html"
  <Directory /home/op/web/public_html>
    Require all granted
  </Directory>
</VirtualHost>
<VirtualHost *:80>
  ServerName app01.henojiya.net
  DocumentRoot "/home/op/app01/public_html"
  WSGIScriptAlias / /home/op/app01/public_html/mysite/mysite/wsgi.py
  <Directory /home/op/app01/public_html/mysite>
    <Files wsgi.py>
      Require all granted
    </Files>
  </Directory>
</VirtualHost>

こんなふうに変えたやで。
VirtualHost ディレクティブに含めたり外したり移動したりして確かめたのでこの配置でいいはず。
例えば、WSGIPythonHomeをVirtualHost ディレクティブに含めると動かなくなるね
逆に、WSGIScriptAlias をVirtualHost ディレクティブの外に出すと、WordpressがDjangoに乗っ取られる
image.png

LoadModule_wsgi_moduleについて
# python -c "import sys; print(sys.path)"
  /home/op/anaconda3/lib/python3.6/site-packages

(編集注:site-packagesまでのパスがわかるので、以下のパス情報とくっつけて)
/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so

(編集注:このパスをLoadModule_wsgi_moduleとする)
LoadModule wsgi_module /home/op/anaconda3/lib/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so

WSGIPythonHomeについて
(編集注:Anacondaのディレクトリを指定する)
/home/op/anaconda3/
WSGIScriptAliasについて
第1引数は、アプリケーションを提供したいベースとなるURLパス( / ルートURLを示している)
第2引数は、 wsgi.py の場所 
大抵はプロジェクトパッケージ (本例では mysite ) の内部です。
これは、そのファイルで定義された WSGI アプリケーションを使用して、
指定された URL 以下のすべての要求にサービスを提供するように Apache に指示します。

WSGIScriptAlias / /home/op/app01/public_html/mysite/mysite/wsgi.py
Filesディレクティブについて
webアプリの窓口となる wsgi.py しか開放しない。という意味

    <Files wsgi.py>
      Require all granted
    </Files>
Tips:再起動
# systemctl restart httpd

プロジェクト作成

プロジェクト名はとりあえず「mysite」とする。

公式からメモ)外側の mysite/ ルートディレクトリは、このプロジェクトのただの入れ物です。 この名前は Django に関係しませんので、好きな名前に変更できます。内側の mysite/ ディレクトリは、このプロジェクトの実際の Python パッケージです。この名前が Python パッケージの名前であり、 import の際に 使用する名前です (例えば import mysite.urls) 。

Tips
# cd /home/op/app01/public_html
# django-admin startproject mysite
# cd mysite/mysite

image.png

wsgi.py(ウィズギー)

公式からメモ)mysite/wsgi.py: プロジェクトをサーブするためのWSGI互換Webサーバーとのエントリーポイントです。

/home/op/app01/public_html/mysite/mysite/wsgi.py
# vi wsgi.py
wsgi.py
"""
WSGI config for mysite project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
"""

import os
import sys

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
sys.path.append('/home/op/app01/public_html/mysite')

application = get_wsgi_application()

settings.py

ALLOWED_HOSTS(許可するドメイン)を編集する

/home/op/app01/public_html/mysite/mysite/settings.py
# vi settings.py

ALLOWED_HOSTS = ['.henojiya.net']
Tips:再起動
# systemctl restart httpd

アドレスアクセステスト

http://www.henojiya.net/
http://app01.henojiya.net/

Django's HelloWorld!

image.png

Wordpress HelloWorld!

image.png

Tips:エラーを見つめてなおして再起動しての繰り返し!根気!
# tail -f /var/log/httpd/error_log
# systemctl restart httpd.service

Django's HelloWorld2!

あぁ^~ なんか飽きて放っといてしばらくぶりにやったらできた...熟成してアタマの整理ができたのかなぁ...不思議
一回 mysite は消して仕切り直し
参考:Python3.4 + Djangoで作るWebアプリケーション(Part.2 アプリ開発編)

CentOS(/home/op/app01/public_html)
# sudo rm -rf mysite
# django-admin startproject pj1
# cd pj1
# python manage.py startapp app1

image.png

※pj1/pj1ディレクトリ配下のファイル群が、全アプリケーションに共通する設定ファイル

httpd.conf

mysite を探して pj1 に置換

Tips
# vi /etc/httpd/conf/httpd.conf

WSGIScriptAlias と Directory ディレクティブ を変更

httpd.conf(修正後)
<VirtualHost *:80>
  ServerName app01.henojiya.net
  WSGIScriptAlias / /home/op/app01/public_html/pj1/pj1/wsgi.py
  <Directory /home/op/app01/public_html/pj1>
  </Directory>
</VirtualHost>

pj1/pj1/settings.py

AllowsHostを設定した(※ファイルが大きいので変えたとこだけ)
Django 1.5以降ではALLOWED_HOSTSの設定が必要
image.png

CentOS(/home/op/app01/public_html)
# cd /home/op/app01/public_html
# vi pj1/pj1/settings.py
pj1/pj1/settings.py
ALLOWED_HOSTS = ['.henojiya.net']

pj1/pj1/wsgi.py

WSGIはDjangoがApacheに指示を出すためにあいだに入る交通整理役。
プロジェクト(=pj1)のパスを追加した

CentOS(/home/op/app01/public_html)
# cd /home/op/app01/public_html
# vi pj1/pj1/wsgi.py
wsgi.py
import os
import sys #add

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pj1.settings")
sys.path.append('/home/op/app01/public_html/pj1') #add

application = get_wsgi_application()

pj1/pj1/urls.py

子のURL設定台帳を見てくれ、と設定した

CentOS(/home/op/app01/public_html)
# cd /home/op/app01/public_html
# vi pj1/pj1/urls.py
urls.py
from django.urls import include, path

urlpatterns = [
    path(r'', include('app1.urls')),
]

pj1/app1/urls.py(新規ファイル)

URL設定台帳はわたしです。views.py の index 関数を呼ぶ

CentOS(/home/op/app01/public_html)
# cd /home/op/app01/public_html
# vi pj1/app1/urls.py
pj1/app1/urls.py
from django.urls import path
from app1 import views

urlpatterns = [
    path(r'', views.index, name='index'),
]

現時点での絵理解

こんな感じかなぁ
image.png

BootStrap

Bootstrapを利用すると、最低限のhtml記述だけで見栄えが整ったWebページを作成することができます。便利セット。Bootstrap自体は、CDNといういわゆる直リンで使う(つまりこのセクションでは実質Bootstrapのインストールなどは行わない)
まず最初に作った「index.html」はいい加減消すか(笑)

index.html
<html>
  hello from app01.henojiya.net
</html>
CentOS(/home/op/app01/public_html)
# rm index.html

httpd.conf

static(静的ファイル)ディレクトリを作って認識させる

CentOS(/home/op/app01/public_html)
# mkdir pj1/app1/static
# sudo vi /etc/httpd/conf/httpd.conf
httpd.conf(追記後)
<VirtualHost *:80>
  ServerName app01.henojiya.net
  DocumentRoot "/home/op/app01/public_html"
  WSGIScriptAlias / /home/op/app01/public_html/pj1/pj1/wsgi.py
  <Directory /home/op/app01/public_html/pj1>
    <Files wsgi.py>
      Require all granted
    </Files>
  </Directory>

  ##add
  Alias /static/ /home/op/app01/public_html/pj1/app1/static/
  <Directory /home/op/app01/public_html/pj1/app1/static>
    Require all granted
  </Directory>
  ##add

</VirtualHost>

この時点ではこうなっている

CentOS
# tree pj1
pj1
┣ app1
┃ ┣ __init__.py
┃ ┣ admin.py
┃ ┣ apps.py
┃ ┣ migrations
┃ ┃ ┗ __init__.py
┃ ┣ models.py
┃ ┣ static
┃ ┣ tests.py
┃ ┣ urls.py
┃ ┗ views.py
┣ manage.py
┗ pj1
    ┣ __init__.py
    ┣ __pycache__
    ┃ ┣ __init__.cpython-36.pyc
    ┃ ┗ settings.cpython-36.pyc
    ┣ settings.py
    ┣ urls.py
    ┗ wsgi.py

settings.py

CentOS
# vi pj1/pj1/settings.py
pj1/pj1/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'app1',       #add
]

LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'

MySQL

ユーザ作成

「pythondb」に対してFULL権限をもつ「python」ユーザを作成。
最初はSELECT権限だけ、とかにしてたんだけど、のちの "マイグレーション" という工程でCREATEが必要になる
同じにしたかったけどパスワードポリシーが面倒だな...
usr:python
psw:python123

CentOS
# mysql -u root -p
MySQLユーザー追加(ALLがFULL権限を表す)
mysql> GRANT ALL ON pythondb.* TO 'python'@'localhost' IDENTIFIED BY 'python123';
   Query OK, 0 rows affected (0.01 sec)

データベースを作成

データベースを作成
mysql> CREATE DATABASE pythondb;
   Query OK, 1 row affected (0.01 sec)
mysql> show databases;

image.png

MySQLクライアント

DjangoがMySQLを操作するのには2つのアプローチがある
ひとつめが、MySQL公式の「ナマSQLで攻めるタイプ」のもの
ふたつめが、Django公式がオススメする「メソッドチェーンで操作できるタイプ」のもの。最初はmodels.pyがうまく作れなくて(なぜかテーブルを作ると項目がA-Zでならんでしまう事象が発生)ひとつめでSQLゴリゴリ書いてたんだけどいまは二つ目でできたので、ふたつめを推奨する

1.mysql-connector-python

ナマSQLで行くならこっち

インストール
CentOS
# sudo /home/op/anaconda3/bin/pip install mysql-connector-python
CentOS(/home/op/app01/public_html)
# vi pj1/app1/views.py
pj1/app1/views.py
from django.shortcuts import render
import mysql.connector

def index(request):
  conn = mysql.connector.connect(user='python', password='python123', database='pythondb')
  cur = conn.cursor()
  cur.execute("SELECT * FROM W_CSV;")
  data = cur.fetchall()
  colname = cur.column_names
  cur.close
  conn.close

  return render(
    request=request,
    template_name='index.html',
    context={'recordset': data,'colname': colname})

2.mysqlclient(推奨)

modelシステムを使うならこっち

インストール
CentOS
# sudo /home/op/anaconda3/bin/pip uninstall mysql-connector-python
# sudo /home/op/anaconda3/bin/pip install mysqlclient
# vi pj1/pj1/settings.py
settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'pythondb',
        'USER': 'python',
        'PASSWORD': 'python123',
    }
}
pj1/app1/models.py(いわゆるテーブル定義)
from django.db import models

class evaluation(models.Model):
     ym = models.TextField(max_length=6)
     homogeneity = models.FloatField(null=True)
     plowing = models.FloatField(null=True)
     biological = models.FloatField(null=True)
     chemical = models.FloatField(null=True)
     hardness = models.FloatField(null=True)
pj1/app1/views.py
from django.shortcuts import render
from .models import evaluation

def index(request):
    #SELECT
    qry = evaluation.objects.order_by('-ym')[:1].values('ym','homogeneity','plowing','biological','chemical','hardness')
    return render(request, 'index.html', {'rs': qry, 'cs':qry[0].keys()})
pj1/app1/views.py(ちなみにこの流れを仕込むとdbへ書き込みができる)
from .models import evaluation
#UPSERT
tbl = evaluation()
tbl.ym = '2017-01-01'
tbl.homogeneity = '100'
tbl.plowing = '100'
tbl.biological = '100'
tbl.chemical = '100'
tbl.hardness = '100'
tbl.save()
CentOS(テーブル定義をもとにMySQLを操作して自動的にテーブルを作成)
# python pj1/manage.py makemigrations app1
# python pj1/manage.py migrate

データを仕込む

migrateでテーブルが作られた後に

index.html

MySQL公式ドキュメント:fetchall()はタプルを返す
MySQL公式ドキュメント:column_namesは項目名をタプルで返す
Djangoのテンプレートでタプルの展開

CentOS(/home/op/app01/public_html)
# mkdir /home/op/app01/public_html/pj1/app1/templates
# vi pj1/app1/templates/index.html
pj1/app1/templates/index.html
<!DOCTYPE html>
<html lang="ja">

  <head>
    <!-- Stylesheet and meta necessary for Bootstrap -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">

    <title>Anaconda!</title>

  </head>

  <body>

    <h1>Hello, Bootstrap world!</h1>
    <table class="table table-dark table-hover">
      <thead>
        <tr>
          {% for c in cs %}<td>{{ c }}</td>{% endfor %}
        </tr>
      </thead>
      <tbody>
        <tr>
        {% for r in rs %}
          <td>{{ r.ym }}</td>
          <td>{{ r.homogeneity }}</td>
          <td>{{ r.plowing }}</td>
          <td>{{ r.biological }}</td>
          <td>{{ r.chemical }}</td>
          <td>{{ r.hardness }}</td>
        {% endfor %}
        </tr>
      </tbody>
    </table>

    <!-- jQuery necessary for Bootstrap -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
  </body>
</html>
CentOS(追記:デプロイごとにapache再起動!)
# systemctl restart httpd 

アドレスアクセステスト

( ^ω^)おっ!「h1」エフェクトかかったじゃん!!MySQLのデータも!!
(`・ω・´ )ンンン~~!!!ここに来るまでに長かったなぁ~
http://app01.henojiya.net/
image.png

※Djangoがキャッシュオバケを持ってくる

新規データが追加されたタイミングでキャッシュをクリアするようにしたほうがいいらしい。なんだか昔のデータが表示されたりする。

Apacheで、キャッシュをさせない設定

CentOS
# sudo vi /etc/httpd/conf/httpd.conf
httpd.conf
(取り消し。詳しくは下の ※デプロイごとにapache再起動! を見ること)
CentOS
# systemctl restart httpd 

※デプロイごとにapache再起動!

いろんな人に話を聞いてわかったんだけど、デプロイごとにapacheを再起動することが重要であり、基本らしい。djangoのソースいじると変更が反映されるから再起動しなくていいかな?って思いこんでたみたい。すぐ上の httpd.conf は忘れてください。

CentOS
# systemctl restart httpd 

UnitTest

Djangoのテストの書き方について勉強したのでまとめる
app1フォルダにはtests.pyがあらかじめ置かれている。これをtestsフォルダを作ってそのなかにしまう

CentOS(/home/op/app01/public_html/pj1/app1)
# tree
.
┣ __init__.py
┣ __pycache__
┣ admin.py
┣ apps.py
┣ migrations
┣ models.py
┣ static
┣ templates
┃ ┗ index.html
┣ tests.py
┣ urls.py
┗ views.py
CentOS(/home/op/app01/public_html/pj1/app1)
# mkdir tests
# mv tests.py tests/tests.py
# vi tests/__init__.py
vi
(カラファイルを作成)
(Pythonにパッケージだということを伝えるためには「__init__.py」というファイルを作らなければなりません)
CentOS(/home/op/app01/public_html/pj1/app1)
# tree
.
┣ __init__.py
┣ __pycache__
┣ admin.py
┣ apps.py
┣ migrations
┣ models.py
┣ static
┣ templates
┃ ┗ index.html
┠ tests
┃ ┠ __init__.py
┃ ┗ tests.py
┣ urls.py
┗ views.py

# vi tests/tests.py
CentOS(/home/op/app01/public_html/pj1/app1)
from django.test import TestCase

class SmokeTest(TestCase):
    def test_bad_maths(self):
        self.assertEqual(1+1, 3)  # 失敗
CentOS(/home/op/app01/public_html/pj1/app1)
# python ../manage.py test
System check identified no issues (0 silenced).
FE
======================================================================
ERROR: test_bad_maths (app1.tests.tests.SmokeTest)
----------------------------------------------------------------------
Tracebac....(省略)
======================================================================
FAIL: test_bad_maths (app1.tests.tests.SmokeTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/op/app01/public_html/pj1/app1/tests/tests.py", line 6, in test_bad_maths
    self.assertEqual(1+1, 3)  # 失敗
AssertionError: 2 != 3

----------------------------------------------------------------------
Ran 1 test in 0.023s

FAILED (failures=1, errors=1)

権限

さんざんrootのままディレクトリとか作りまくってると access denied というか permission error になる可能性があるので op 配下をまとめて権限変更(これ時々やらかすとまじで混乱するなぁ)

CentOS
権限をまとめて op 扱いに
# chown -R op:op /home/op

Git

[Git] CentOS7に最新版のgitをインストール

インストール

Tips
# cd /home/op/
# git --version
git version 1.8.3.1
# yum remove git
# yum -y install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker autoconf
# wget https://www.kernel.org/pub/software/scm/git/git-2.9.5.tar.gz
# tar vfx git-2.9.5.tar.gz
# cd git-2.9.5
# make configure
# ./configure --prefix=/usr
# make all
# make install
# git --version
git version 2.9.5
# rm -f git-2.9.5.tar.gz

鍵の作成と設定

アプリとかHPの設置場所が基本的に /Home/op 配下なので、GitHubとの接続は op でのプロンプト(=$)じゃないとダメみたい。ヘンにrootで操作してここでもハマった。
gitHubでssh接続する手順~公開鍵・秘密鍵の生成から~

Tips(opになってからの操作)
# exit
$ git config --global user.name "yoshitaka-CentOS"
$ git config --global user.email "yoshitakaOkada0214@gmail.com"
$ cd ~/.ssh

なにか聞かれたらEnter3回でカレントディレクトリに鍵が作られる
$ ssh-keygen -t rsa

公開鍵をgitHubにアップ

image.png

Tips
$ ssh -T git@github.com
Hi duri0214! You've successfully authenticated, but GitHub does not provide shell access.

実行すべきgitコマンドは書かれている

image.png

Tips:Wordpressのディレクトリを
$ cd /home/op/web
$ git init
Initialized empty Git repository in /home/op/web/.git/
$ git add .
$ git commit -m "first commit"
$ git remote add origin git@github.com:duri0214/CentOS-Wordpress.git
$ git push -u origin master
Tips:Pythonのディレクトリを
$ cd /home/op/app01
$ git init
Initialized empty Git repository in /home/op/app01/.git/
$ git add .
$ git commit -m "first commit"
$ git remote add origin git@github.com:duri0214/CentOS-Python.git
$ git push -u origin master

VisualStudioで編集したい!

これやろ!これ。いままでずーっとTeratermからのコンソール編集してたけどやっぱりVisualStudioでしょう。
image.png

1.VisualStudioを立ち上げてチームエクスプローラを選ぶ
2.複製を選ぶ
3.複製するGitリポジトリのURLを入力してくださいのところにはGithubのURLを仕込むためにGithubの自分のページを開く
image.png

3.Githubの CLONE を選択して https の URL をコピー
image.png

4.アカマルの場所にURLをペーストすると、その下に勝手に文字が入るけど、任意のカラフォルダを指定する(カラフォルダじゃないと怒られるだよ)
image.png

5.複製(C)を押すとクローンされる
image.png
image.png

6.ソリューションエクスプローラー開いたらあらまぁ!
image.png

7.編集が終わったらコミットするとコミットメッセージを書くように言われるので書いて
8.すべてをコミットを押す
image.png
image.png

同期(pushのことだね)をしてくださいといわれるので
image.png

「プッシュ」を押すとプッシュされる
image.png
image.png
image.png

Githubを見ても更新されている!
image.png

.vsを同期対象外にする

このフォルダはvisualstudioが勝手に作るファイルで、うっかりCentOSで同期取るとサーバーエラー起こすかも。
image.png

.gitignore の書き方
VisualStudio .gitignore

Commit

git add -A 新規作成/変更/削除されたファイル全てを追加(AllのA)
最後にまた git diff をして差分がでなくなったことを確認している。
コミットがローカルへのセーブ、プッシュがサーバーへのセーブ

CentOS
$ git add -A
$ git commit -m "コミットコメントをここに書く"
 15 files changed, 10 insertions(+), 16 deletions(-)
$ git push -u origin master
 Counting objects: 25, done.
 Compressing objects: 100% (23/23), done.
 Writing objects: 100% (25/25), 4.10 KiB | 0 bytes/s, done.
 Total 25 (delta 11), reused 0 (delta 0)
 remote: Resolving deltas: 100% (11/11), completed with 11 local objects.
 To github.com:duri0214/CentOS-Python.git
   b137e37..7af5695  master -> master
 Branch master set up to track remote branch master from origin.

Fetch

Masterの同期を取る

CentOS
$ git fetch
$ git merge origin/master

VisualStudioでローカル実行可能にする

上記でGithubとVisualStudioをくっつけたのは、あくまでエディターとしてであって、VisualStudioからの「実行」はできない。したがって、なんとかGithubから同期を取った後、ローカルのAnaconda・MySQL・Djangoと連携できれば、VPSを直接Teratermで覗いてコードヒントも出ない状態で手探りで編集するなんてこともなくなって大きな安心感を得られるはずなんだが...

こっちにまとめなおした
Djangoで VisualStudio2017 ➡ Github の環境を作るメモ

FTP

インストール

昔は NextFTP とかそういうのでやってたんだけどいまは FileZilla ってのがよく出てくるのでこれにした。

鍵の登録

  1. メニューバーから 編集 -> 設定 -> SFTP で "鍵ファイルの追加(A)" ボタンをクリック。
  2. 秘密鍵を選択する
  3. filezilla用に作り替えてもいいか聞いてくるので OK として、リネームする(id_rsa -> id_rsa_filezilla.ppk) image.png

接続

image.png

つながったつながった!これでバックアップもできるね!:relaxed:
image.png

バックアップ

WordPressでバックアップを取る4つの方法(初心者向け)

ダッシュボードを作る

要件

・CoinCheckの相場をグラフで見ることができる
・Slackのとあるチャンネル(なんでもいい)を見ることができる
・GoogleMapを使ったなにか
・天気予報を表示
・QGISを使ったなにか
・PHPとPython両方でつくる(同じものを視点を変えて作る)

どんなダッシュボードにするか

無料で使えるBootstrap製のダッシュボードのテンプレート10選
Blur Admin がよさそう

  • Django
  • 権限
  • Git
  • VisualStudioでローカル実行可能にする
  • FTP
  • ダッシュボードを作る