AB型技術系 主に備忘録

ほぼプログラム関連の備忘録

DSM上のApacheでPHPを動かす

DSM上のApachePythonを動かすためにこれまでいろいろ試してきました。
freelancer.hatenablog.jp
仕事関連でPHPで作成されたCMS等の検証を行うことになったのでPHPも動かせるように設定してみました。

Web Stationの設定を確認

Web Stationの設定

PHPは7.0と7.4がインストールされていました。
※インストールされていなければパッケージセンターの画面で簡単にインストールできます。

ユーザー定義のポータルの作成

Webサービス ポータル

作成ボタンをクリック。

ポータル作成ウィザード1

仮想ホストを選択。

ポータル作成ウィザード2

ホスト名を入力。
その他はデフォルトのまま。
次へボタンをクリック。

ポータル作成ウィザード3

ドキュメントルートを入力。
今回はwebディレクトリにphpディレクトリを作成し指定しました。
HTTP バックエンドサーバーはApacheを選択。
スクリプト言語の設定はPHP7.4を選択。
次へボタンをクリック。

ポータル作成ウィザード4

変更不要なら何も変更せずに次へボタンをクリック。

ポータル作成ウィザード5

設定の確認をして問題なければ作成ボタンをクリック。

確認ダイアログ

OKボタンをクリック。

Webサービスポータル

ユーザー定義のポータルが作成できました。

動作確認用のPHPをアップロード

下記のファイルをweb/phpにアップロードし 実行権限(755)を付与。

sample.php

<?php
echo "PHPサンプルページ"
?>

動作確認

https://php/sample.php

PHP動作確認

無事phpの動作が確認できました。


DSM上でPython + MariaDBを使ってWebアプリを稼働させるためにやったこと

5年ほど使用しているDS216jのDSMを7.1に更新したことをきっかけにDSM上でWebアプリを稼働させようと思って試したことの記録です。
必要なパッケージをパッケージセンターで検索してインストールしました。
pythonのライブラリについてはSSHサービスを有効にしてTera Termで接続してインストールしました。

DS216jのDSMを7.1に更新

DSM バージョン

まずDSMを7.1に更新しました。

Web Stationをインストール

Web Station インストール
Web Station インストール完了

Webサーバーの機能を追加したいのでWeb Stationをインストールしました。

MariaDBをインストール

MariaDB インストール

MariaDBをインストール。

パスワードとポートを入力

パスワードとポートを入力。
ポートはデフォルトで3306です。

インストール完了

インストール完了後にMariaDBの設定画面を開く。

MariaDBの設定画面を開く
MariaDBの設定画面

TCP/IP接続を有効にする」を選択して適用ボタンをクリック。
これでTCP/IP接続でDSM上のMariaDBに接続できるようになりました。
MariaDBMySQLの派生として開発されているのでMySQL感覚で使えるかと。

phpMyAdminをインストール

phpMyAdminをインストール
インストール完了

ブラウザ上でMariaDBを管理するためphpMyAdminをインストールしました。

ユーザーアカウントを作成

phpMyAdminを開く

phpMyAdminを開いて

phpMyAdminのログインページ

ユーザー名に「root」を入力、パスワードにMariaDBインストール時に設定したパスワードを入力、サーバーの選択は「MariaDB 10」を選択して「実行」をクリック。

データベースを作成

phpMyAdmin TOP画面

「ユーザーアカウント」をクリック。

ユーザーアカウント画面

「ユーザーアカウントを追加する」をクリック。

ユーザーアカウントを追加画面

ユーザー名とパスワードを入力、認証プラグインは「ネイティブMySQL認証」を選択、
グローバル特権を全てチェックして「実行」をクリック。

ユーザーアカウント作成完了

新しいユーザーが追加されました。
「データベース」をクリック。

テーブルを作成

データベース画面 TOP

データベース名を入力して「作成ボタン」をクリック。
作成したデータベースを選択。

データベース設定画面

テーブル名を入力して「実行」をクリック。

カラム追加画面

追加するカラムの情報を入力して「保存する」をクリック。

テーブル構造画面

テーブルが作成できました。

DBeaverから接続できるか確認

DBeaver 接続設定

SQLクライアントはDBeaverを使用することにしました。

接続結果

DBeaverでMariaDBに接続することができました。

Python実行環境の設定

Web StationでPythonの実行環境を設定できるようなので設定方法を調べてみました。

スクリプト言語の設定

スクリプト言語の設定

Web Station→スクリプト言語の設定→Pythonで設定画面を開いてみました。
Python3をインストールする必要があるみたいですね。

パッケージセンターを確認

パッケージセンターでpythonを検索

パッケージセンターでPythonのインストール状況を調べてみるとPython2がインストールされていることが確認できました。
Python3はインストールできないのか?

SSHサービスを有効化

SSHサービスを有効化

DSMにTera Termを使って接続するためSSHサービスを有効化しました。

Pyhonのバージョンを調べる

Tera Termで接続

Tera Termで接続してPythonのバージョンを調べてみました。
※ 接続時のユーザーはDSM上で追加

testuser@DS216J:~$ python --version					
Python 3.8.12					
testuser@DS216J:~$					

Python2系がインストールされていると思ったらPython 3.8がインストールされていました。
ということはPythonのパスを調べてApacheをインストールすればPythonCGIとして動作させることができるのでは?
という仮説を立てる。

Apacheをインストール

バックエンドパッケージ

Web Stationのあ管理ページで関連するパッケージのインストール状況を確認。
Apacheは2.2と2.4がインストールできます。

Apache2.4をインストール

Apache2.4をインストールします。

Apache2.4がインストールされたことを確認

Apache2.4をインストールしました。

webサービスポータルを追加

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>					

http://test

仮想ホストの稼働確認

仮想ホストが稼働していることが確認できました。

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で実行されてることが分かりました。

pythoncgiとして動作させる

.htaccessとテスト用のpyファイルを準備します。

.htaccess

DirectoryIndex index.php index.html index.py
AddHandler cgi-script .py	

test.py

#!/bin/python
print('Content-Type: text/plain; charset=UTF-8\n')
print("Pythonで文字列出力")

.htaccessとtest.pyを/volume1/web/rootに置きます。

http://test/test.py

PythonCGIとして動作

PythonCGIとして動作させることができました。

PythonMariaDBにアクセスできるか確認

PythonMariaDBにアクセスするためにPyMySQLを使います。
pypi.org

pipをインストール

PyMySQLをインストールするためにpipをインストールします。

testuser@DS216J:~$ sudo curl -k https://bootstrap.pypa.io/get-pip.py | sudo python3
pipをインストール

インストールできましたが、警告が発生。
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がインストールできました。

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に置きます。

http://test/testMySql.py

PyMySQLが動作しない

コネクションの作成時にエラーが発生しました。

インストールしたPyMySQLについて調べる

PyMySQLに問題がないか調べてみます。

root@DS216J:$ pip show PyMySQL
インストールした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

/usr/lib/python3.8/site-packagesにあるファイル一覧

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
/usr/lib/python3.8/site-packages/pymysqlにあるファイル一覧

ファイルも存在するし問題なさそう。

rootユーザーで直接実行

権限周りが怪しそうなのでrootユーザーで直接実行してみました。

root@DS216J:~# python /volume1/web/root/testMySql.py
rootユーザーで実行

MariaDBに接続してデータが取得できました。

rootユーザー以外で実行

testuser@DS216J:~$ python /volume1/web/root/testMySql.py
rootユーザー以外で実行

ブラウザで確認した時と同じエラーが発生しました。
やはり権限の問題でした。

パッケージの実行権限を調べる

/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ユーザー以外で実行

rootユーザー以外でMariaDBに接続してデータが取得できました。

PyMySQLを使ってMariaDBに接続(成功)

http://test/testMySql.py

接続成功

ブラウザ上でも取得したデータを表示することができました。

スクリプト言語の設定でpythonが設定できない、
rootユーザー以外でPyMySQLが動かない、等いろいろはまりましたが何とかDSM上でPythonを使って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>

http://localhost:3000/sample_page

components配下のコンポーネントでデーターを取得して表示することができました。


Nuxt.js ヘッダ部やフッタ部をコンポーネント化

ヘッダ部やフッタ部をコンポーネント

前回レイアウトディレクトリにレイアウト用のファイルを追加しレイアウトを切り替えられるようにしました。

freelancer.hatenablog.jp

ヘッダ部やフッタ部は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ディレクト

/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

http://localhost:3000/layout_default

レイアウトに関する記述がないのでデフォルトのレイアウトが適用される。

layoutsディレクトリにsample.vueを作成

layoutsディレクト

/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

http://localhost:3000/layout_sample

ページコンポーネントで指定したレイアウト(layout: 'sample')が適用される。

ヘッダ部やフッタ部は部品としてcomponents直下に作成した方がいいかも。
次回はこのあたりを試そうかと。