DSM上のApacheでPHPを動かす
DSM上のApacheでPythonを動かすためにこれまでいろいろ試してきました。
freelancer.hatenablog.jp
仕事関連でPHPで作成されたCMS等の検証を行うことになったのでPHPも動かせるように設定してみました。
Web Stationの設定を確認
PHPは7.0と7.4がインストールされていました。
※インストールされていなければパッケージセンターの画面で簡単にインストールできます。
DSM上でPython + MariaDBを使ってWebアプリを稼働させるためにやったこと
5年ほど使用しているDS216jのDSMを7.1に更新したことをきっかけにDSM上でWebアプリを稼働させようと思って試したことの記録です。
必要なパッケージをパッケージセンターで検索してインストールしました。
pythonのライブラリについてはSSHサービスを有効にしてTera Termで接続してインストールしました。
Web Stationをインストール
Webサーバーの機能を追加したいのでWeb Stationをインストールしました。
MariaDBをインストール
MariaDBをインストール。
パスワードとポートを入力。
ポートはデフォルトで3306です。
インストール完了後にMariaDBの設定画面を開く。
「TCP/IP接続を有効にする」を選択して適用ボタンをクリック。
これでTCP/IP接続でDSM上のMariaDBに接続できるようになりました。
MariaDBはMySQLの派生として開発されているのでMySQL感覚で使えるかと。
phpMyAdminをインストール
ブラウザ上でMariaDBを管理するためphpMyAdminをインストールしました。
ユーザーアカウントを作成
phpMyAdminを開いて
ユーザー名に「root」を入力、パスワードにMariaDBインストール時に設定したパスワードを入力、サーバーの選択は「MariaDB 10」を選択して「実行」をクリック。
データベースを作成
「ユーザーアカウント」をクリック。
「ユーザーアカウントを追加する」をクリック。
ユーザー名とパスワードを入力、認証プラグインは「ネイティブMySQL認証」を選択、
グローバル特権を全てチェックして「実行」をクリック。
新しいユーザーが追加されました。
「データベース」をクリック。
テーブルを作成
データベース名を入力して「作成ボタン」をクリック。
作成したデータベースを選択。
テーブル名を入力して「実行」をクリック。
追加するカラムの情報を入力して「保存する」をクリック。
テーブルが作成できました。
Python実行環境の設定
Web StationでPythonの実行環境を設定できるようなので設定方法を調べてみました。
パッケージセンターを確認
パッケージセンターでPythonのインストール状況を調べてみるとPython2がインストールされていることが確認できました。
Python3はインストールできないのか?
Pyhonのバージョンを調べる
Tera Termで接続してPythonのバージョンを調べてみました。
※ 接続時のユーザーはDSM上で追加
testuser@DS216J:~$ python --version Python 3.8.12 testuser@DS216J:~$
Python2系がインストールされていると思ったらPython 3.8がインストールされていました。
ということはPythonのパスを調べてApacheをインストールすればPythonをCGIとして動作させることができるのでは?
という仮説を立てる。
Apacheをインストール
Web Stationのあ管理ページで関連するパッケージのインストール状況を確認。
Apacheは2.2と2.4がインストールできます。
Apache2.4をインストールします。
Apache2.4をインストールしました。
webサービスポータルを追加
Web Station→webサービスポータル→で設定画面を開いて作成ボタンをクリック。
「仮想ホスト」をクリック。
ポータルタイプは「名前ベース」を選択、ホスト名を入力、80/443をチェックして「次へ」ボタンをクリック。
ドキュメントルートを入力、HTTPバックエンドサーバーはApache2.4を選択。
他はデフォルトのままで「次へ」ボタンをクリック。
変更せず「次へ」ボタンをクリック。
設定を確認して「作成」ボタンをクリック。
ユーザー定義のポータルが追加されました。
仮想ホストの稼働確認
web/rootに下記のindex.htmlを追加
<!DOCTYPE html> <html lang="jp"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>サンプルページ</title> </head> <body> <b>サンプルページ</b> </body> </html>
仮想ホストが稼働していることが確認できました。
Pythonのパスを確認
pythonコマンドが実行できるので実行されているpythonのパスを調べます。
installdir.py
import os import sys print(os.path.dirname(sys.executable))
installdir.pyファイルを/volume1/webに置いてTera Termで接続して実行します。
testuser@DS216J:~$ cd /volume1/web
testuser@DS216J:/volume1/web$ python installdir.py
/bin
testuser@DS216J:/volume1/web$
/binにあるpythonで実行されてることが分かりました。
PythonでMariaDBにアクセスできるか確認
PythonでMariaDBにアクセスするためにPyMySQLを使います。
pypi.org
pipをインストール
PyMySQLをインストールするためにpipをインストールします。
testuser@DS216J:~$ sudo curl -k https://bootstrap.pypa.io/get-pip.py | sudo python3
インストールできましたが、警告が発生。
pipを使うにはrootユーザーでないとだめってことかな?
PyMySQLをインストール
pipコマンドを使ってPyMySQLをインストールします。
testuser@DS216J:~$ pip install PyMySQL raceback (most recent call last): File "/bin/pip", line 5, in <module> from pip._internal.cli.main import main ModuleNotFoundError: No module named 'pip._internal'
pipインストール時に表示された警告メッセージの通りrootユーザー以外では権限の問題で失敗するようです。
rootユーザーに変更してインストール
testuser@DS216J:~$ sudo -i
Password:パスワードを入力
root@DS216J:~#pip install PyMySQL
PyMySQLがインストールできました。
PyMySQLを使ってMariaDBに接続(失敗)
testMyql.py
#!/bin/python print('Content-Type: text/plain; charset=UTF-8\n') conn = None cursor = None try: import pymysql import pymysql.cursors # コネクションの作成 conn = pymysql.connect(host='DS216J', user='testuser', port=3306, password='xxxxxxxx', db='test_db', charset='utf8', cursorclass=pymysql.cursors.DictCursor) cursor = conn.cursor() # SQL実行 cursor.execute("select * from test_table") row = cursor.fetchone() if row is not None: print(row["column1"]) print("\n") print(row["column2"]) except Exception as e: print(e.args) finally: print("完了") cursor.close() conn.close()
test_tableに登録したデータ
testMyql.pyを/volume1/web/rootに置きます。
コネクションの作成時にエラーが発生しました。
インストールしたPyMySQLについて調べる
PyMySQLに問題がないか調べてみます。
root@DS216J:$ pip show PyMySQL
/usr/lib/python3.8/site-packagesにPyMySQLがインストールされているようです。
root@DS216J:~$ cd /usr/lib/python3.8/site-packages
/usr/lib/python3.8/site-packagesに移動して
root@DS216J:/usr/lib/python3.8/site-packages>$ ls
PyMySQLが存在することが確認できました。
pymysqlディレクトリの中身を確認してみます。
root@DS216J:/usr/lib/python3.8/site-packages~$ cd ./pymysql
/usr/lib/python3.8/site-packages/pymysqlに移動して
root@DS216J:/usr/lib/python3.8/site-packages/pymysql$ ls
ファイルも存在するし問題なさそう。
rootユーザーで直接実行
権限周りが怪しそうなのでrootユーザーで直接実行してみました。
root@DS216J:~# python /volume1/web/root/testMySql.py
MariaDBに接続してデータが取得できました。
rootユーザー以外で実行
testuser@DS216J:~$ python /volume1/web/root/testMySql.py
ブラウザで確認した時と同じエラーが発生しました。
やはり権限の問題でした。
パッケージの実行権限を調べる
/usr/lib/python3.8/site-packagesにあるディレクトリの権限を調べてみます。
testuser@DS216J:~$ cd /usr/lib/python3.8/site-packages
/usr/lib/python3.8/site-packagesに移動して
testuser@DS216J:/usr/lib/python3.8/site-packages$ ls -l
所有者以外の権限がないです。
権限を設定
rootユーザーに変更してpymysqlディレクトリの権限を設定します。
root@DS216J:/usr/lib/python3.8/site-packages$ chmod -R 755 ./pymysql root@DS216J:/usr/lib/python3.8/site-packages$ ls -l
所有者以外に読取と実行権限が追加されました。
rootユーザー以外で実行
testuser@DS216J:~$ python /volume1/web/root/testMySql.py
rootユーザー以外でMariaDBに接続してデータが取得できました。
Nuxt.js components配下のコンポーネントでデーターを取得
共通コンポーネントでデータを取得して表示したい
共通コンポーネントでデータを取得したいので下記のように実装
/pages/sample_page.vue
<template> <Sample/> </template>
/components/sample.vue
<template> <div> <b>{{data.data1}}</b><br> <b>{{data.data2}}</b> </div> </template> <script> export default { async asyncData(context) { const data = await context.$axios.$get('http://localhost:3000/nuxt_test.json') return { data } } } </script>
/static/nuxt_test.json
{ "data1":"データ1", "data2":"データ2" }
http://localhost:3000/sample_page
エラーが発生しました。
原因はasyncDataがpages配下以外のコンポーネントが使えないから。
公式だと↓のページで詳しく説明されてました。
nuxtjs.org
このページには解決方法も記載されれていて、fetchフックを使えば解決できると記載されていました。
fetchフックの使い方を公式ページで調べると↓のページのサンプルがドンピシャでした。
nuxtjs.org
このページを参考にコンポーネントを修正しました。
/components/sample.vue
<template> <div> <b>{{data.data1}}</b><br> <b>{{data.data2}}</b> </div> </template> <script> export default {data() { return { data: {} } }, async fetch() { this.data = await fetch( 'http://localhost:3000/nuxt_test.json' ).then(res => res.json()) } } </script>
Nuxt.js ヘッダ部やフッタ部をコンポーネント化
ヘッダ部やフッタ部をコンポーネント化
前回レイアウトディレクトリにレイアウト用のファイルを追加しレイアウトを切り替えられるようにしました。
ヘッダ部やフッタ部はcomponents直下に配置してコンポーネント化したほうがよさそうなのでためしてみました。
header.vueとfooter.vueを追加
componentsディレクトリにheader.vueとfooter.vueを追加する。
/components/header.vue
<template> <header style="border-bottom:solid 1px #CCC;padding:10px">ヘッダ部(共通)</header> </template>
/components/footer.vue
<template> <footer style="padding:10px">フッタ部(共通)</footer> </template>
defaultvueを修正
/layouts/default.vue 修正前
<template> <div> <header style="border-bottom:solid 1px #CCC;padding:10px">ヘッダ部(デフォルト)</header> <div style="border-bottom:solid 1px #CCC"> <nuxt/> </div> <footer style="padding:10px">フッタ部(デフォルト)</footer> </div> </template>
/layouts/default.vue 修正後
<template> <div> <Header/> <div style="border-bottom:solid 1px #CCC"> <nuxt/> </div> <Footer/> </div> </template>
<コンポーネント名 />でコンポーネントの内容が表示されるようになります。
古いバージョンのNuxt.jsだとimport宣言が必要になりますが、新しいバージョンだとcomponents配下にあるコンポーネントは自動でインポートされます。
/layouts/default.vue inport宣言する場合
<template> <div> <Header/> <div style="border-bottom:solid 1px #CCC"> <nuxt/> </div> <Footer/> </div> </template> <script> import Header from '~/components/header.vue' import Footer from '~/components/footer.vue' export default { components: { Header, Footer } } </script>
/lnuxt.config.js 自動インポートの設定個所
// Auto import components: https://go.nuxtjs.dev/config-components components: true,
http://localhost:3000/layout_default
部品化したヘッダーとフッターが表示されるようになりました。
データ取得やレイアウトに関する機能はある程度ためせたので次回はコンポーネント間のデータのやりとりについて試してみます。
Nuxt.js レイアウトディレクトリを試してみる。
レイアウトディレクトリ
ページコンポーネントに各ページで共通になる部分(ヘッダ部、フッタ部)を記述するのが面倒。
Nuxtにはレイアウト作成の機能があり各ページに共通のレイアウト適用することが可能。
layoutsディレクトリにdefault.vueを作成
/layouts/default.vue
<template> <div> <header style="border-bottom:solid 1px #CCC;padding:10px">ヘッダ部(デフォルト)</header> <div style="border-bottom:solid 1px #CCC"> <nuxt/> </div> <footer style="padding:10px">フッタ部(デフォルト)</footer> </div> </template>
レイアウトを指定しなかった時に適用されるデフォルトのレイアウト。
<nuxt/>がページコンポーネントが表示される部分。
/pages/layout_default.vue
<template> <div style="padding:10px">ボディ部</div> </template> <script> export default { name: 'LayoutDefault' } </script>
http://localhost:3000/layout_default
レイアウトに関する記述がないのでデフォルトのレイアウトが適用される。
layoutsディレクトリにsample.vueを作成
/layouts/sample.vue
<template> <div> <header style="border-bottom:solid 1px #CCC;padding:10px">ヘッダ部(個別)</header> <div style="border-bottom:solid 1px #CCC"> <nuxt/> </div> <footer style="padding:10px">フッタ部(個別)</footer> </div> </template>
ページコンポーネントで指定することによって適用されるレイアウト。
/pages/layout_sample.vue
<template> <div style="padding:10px">ボディ部</div> </template> <script> export default { name: 'LayoutSample', layout: 'sample' } </script>
http://localhost:3000/layout_sample
ページコンポーネントで指定したレイアウト(layout: 'sample')が適用される。
ヘッダ部やフッタ部は部品としてcomponents直下に作成した方がいいかも。
次回はこのあたりを試そうかと。