お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。

nginxの設定ファイルを更新したのに読み込んでくれないときの対処法

  • 次のようにnginxのリロードや再起動をしても通じないとき
    • nginx -s reload
    • nginx -s stop -> nginx
  • 次のコマンドを流すとプロセスが綺麗に死んでくれて再読込できることがある
    • sudo kill -HUP $(cat /var/run/nginx.pid)

ReactでSPAを組んでいてブラウザバックしたときのフォームの入力内容が消し飛んで気になったので、ブラウザバックした時にどうなるのかというのを軽く調査した結果

確認したパターンとしては次の2つ

  1. フォームの入力値をDOMに保持させるステートレスな方式
  2. フォームの入力値をJSに保持させるステートフルな方式

LocalStorageに画面情報を保存して復元するとか、条件分岐を使ってDOMを隠して保持させるとか、そういう系は考慮しない

結果

DOM 保持 JS 保持
SPA 内ブラウザバック 消える 保持される
SPA 外ブラウザバック 保持される 消える
コード記述量 少ない 多い

1. フォームの入力値をDOMに保持させるステートレスな方式

この方式だとhistory.push()でDOMが消し飛ぶのでSPA内でのブラウザバックで入力したデータが保持されません
その代わりSPAの外、別のサイトに遷移してからブラウザバックしたときは、DOMが残っているので入力したデータが保持されます

2. フォームの入力値をJSに保持させるステートフルな方式

この方式だとJSでステート管理をしているため、history.push()で遷移してDOMが消し飛んでも、 defaultValueに持ってる値を突っ込んであげれば、取り敢えず入力したデータを保持することが出来ます
反対にSPAの外、別のサイトに遷移してからブラウザバックしたときは、メモリの中身が飛んでるので入力したデータが保持されません

各手法の実装方式

ちゃちゃっと書いたのでコードは超雑です

確認環境

Env Ver
react 17.0.2
react-dom 17.0.2
react-router-dom 5.2.0

1. フォームの入力値をDOMに保持させるステートレスな方式

大正義ステートレスです
Function Componentはステートレスなので、こうあってほしいですよね~
コードもシンプルで管理しやすいのが素敵なところです

export const StatelessPage = () => {
  const history = useHistory();
  return (
    <div>
      <form>
        <input type="text" />
        <button onClick={() => history.push(AppRoute.dom2.path)}>submit</button>
      </form>
    </div>
  );
};

2. フォームの入力値をJSに保持させるステートフルな方式

ギルティなステートフル方式です
Class Componentを捨てたはずなのにどうしてこうなった…
コードが煩雑で管理が大変です

export const StatefullPage = () => {
  const ctx = useContext(ExampleContext);
  const history = useHistory();
  const onChange = (ev: React.ChangeEvent<HTMLInputElement>) => {
    ctx.text = ev.target.value;
  };

  return (
    <div>
      <form>
        <input
          type="text"
          defaultValue={ctx.text}
          onChange={(ev) => onChange(ev)}
        />
        <button onClick={() => history.push(AppRoute.ctx2.path)}>submit</button>
      </form>
    </div>
  );
};

手順

  1. xrdpが入っていなければxrdpをインストール
    1. Desktop版なら最初から入ってた気もする
  2. 3389ポートを開ける
    1. sudo ufw allow 3389
  3. オートログインを殺す
    1. sudo sed -ie 's/AutomaticLoginEnable=true/AutomaticLoginEnable=false/' /etc/gdm3/custom.conf
  4. あとは再起動してWindowsのリモートデスクトップから繋げて画面が映ればOK
    1. sudo reboot

トラブルシューティング

接続したけど画面が真っ暗

pkill gnome-sessionでログインセッションを殺す

左にあるDockが表示されない・設定に外観がない・その他物理接続時とデスクトップの表示が異なる

sudo nano /etc/xrdp/startwm.shして以下の内容を追記する

export DESKTOP_SESSION=ubuntu
export GNOME_SHELL_SESSION_MODE=ubuntu
export XDG_CURRENT_DESKTOP=ubuntu:GNOME

GitHub Pagesにドメインを紐付ける

# ルートドメイン, cnameだとメールが届かなくなるのでaliasを使う
alias @ example-user.github.io.
# サブドメイン
cname sub example-user.github.io.

メールサーバーは分けたい

メールサーバーがさくらインターネットの場合はこんな感じで行ける

mx xxx.xxx.xxx.xxx. 10
txt xxx.xxx.xxx.xxx. v=spf1 a:wwwXXXX.sakura.ne.jp mx ~all
a mail xxx.xxx.xxx.xxx

Let’s EncryptのDNS-01チャレンジの設定方法

  • サブドメインのケースで書いてる
  • ワイルドカード証明書の設定も確かできたはずだが、今ん所使える環境がないので書いてない
  • @lycolia/value-domain-dns-cert-registerで自動更新できる
    a sub xxx.xxx.xxx.xxx
    txt _acme-challenge.sub XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    

WindowsからのRDP接続を前提として主にSSDブート、リモート環境構築、Let's Encrypt、LAMP、Nodeの環境構築を行う

🌏 環境

Windows側の環境は省略

環境 バージョン
Raspbian 2020-05-27-raspios-buster-arm64
acme.sh 2.8.7
PHP 7.3.19-1
MariaDB 10.3.23
phpMyAdmin 5.0.2
Node.js 10.21.0
npm 5.8.0
Yarn 1.22.4

📜 Raspberry Pi 4をUSB SSDからブートする

まずはここから

📞 リモート環境の構築

本体操作によるセットアップ

Headlessでできるならよしなにしてもいい気はする

  1. ラズパイにモニタ、キーボード、電源の通ったUSB-Cケーブルを接続
  2. 数分待つとセットアップウィザードが出てくるので適当に進める
    1. この途中でWiFiルーターに繋がるように設定しておく
  3. セットアップウィザードが終わったらWinKeyでメニューを出し設定> Raspberry Piの設定でSSHとVNCを有効
  4. シャットダウンする
  5. 電源USB以外を全部抜く

パッケージ情報の更新

  • sudo apt-get update

XRDPのインストール

Windows10からのRDP接続で現状操作不能だが一応書いておく

  1. sudo apt-get install xrdp
  2. Windows 10のリモートデスクトップ接続から接続確認

SSHD設定

待受ポートの変更と認証方式の変更

待受ポートの変更と外部接続
  1. sudo nano /etc/ssh/sshd_config
  2. Port 22を適当なポートに変更
認証方式の変更
  1. RLoginの機能で認証キーを生成
  2. sudo nano /etc/ssh/sshd_configで以下の設定に変更
   PubkeyAuthentication yes
   AuthorizedKeysFile      .ssh/authorized_keys
   PasswordAuthentication no
   PermitEmptyPasswords no
  1. ~/.ssh/authorized_keysを作る
mkdir ~/.ssh/
nano ~/.ssh/authorized_keys
  1. 公開鍵をコピーして~/.ssh/authorized_keysの一行目に貼り付ける
  2. sudo /etc/init.d/ssh restartでSSHDを再起動
  3. RLoginから再接続できたらOK
AndroidからSSH接続
  1. RLoginから秘密鍵を吐く
  2. JuiceSSHで秘密鍵を読む
  3. 終わり

Uncomplicated Firewallのインストールと設定

  1. sudo apt install ufw

  2. systemctl start ufw

  3. sudo ufw enableでFirewallを有効化

  4. SSHの穴をあける

    1. sudo ufw allow SSHのポート番号
  5. VNSの穴をあける

    1. WindowsRDPからラズパイに接続

    2. 蹴られるのでcat /var/log/ufw.logでログを見る

    3. 蹴られているDPT3389だったのでsudo ufw allow 3389

      1. help.ubuntu.comによるとSPTがSource Port、DPTがDestination Portということらしい
  6. sudo ufw status numberedで設定内容を確認

  7. SSHとRDPの接続確認

🔐 Let's Encrypt! DDNS Challenge

💡 LAMP環境構築

MariaDB, Apache, PHPのインストール

この環境でのApacheはphpMyAdminを動かすためだけに使用(外部公開しない)

  • sudo apt install -y mariadb-server apache2 php php-mysql libapache2-mod-php

MariaDBの設定

外部接続しないケース
  1. sudo mysql_secure_installation
  2. sudo mysql
  3. CREATE USER 'id'@'localhost' IDENTIFIED BY 'pw';
  4. GRANT ALL PRIVILEGES ON *.* TO 'id'@'localhost' WITH GRANT OPTION;
外部接続するケース
  1. sudo mysql_secure_installation

  2. sudo mysql

  3. CREATE USER 'id'@'%' IDENTIFIED BY 'pw';

  4. GRANT ALL PRIVILEGES ON *.* TO 'id'@'%' WITH GRANT OPTION;

  5. quit

  6. sudo nano /etc/mysql/my.cnfで最終行に以下を追加

[mysqld]
skip-networking=0
skip-bind-address

Apacheの設定

  1. sudo nano /etc/apache2/apache2.confで既存の設定をコメントアウトして適当にルートを追加
<Directory /home/pi/Public/>
  Options Indexes FollowSymLinks
  AllowOverride None
  Require all granted
</Directory>
  1. sudo nano /etc/apache2/sites-available/000-default.confも同様に変更
Apacheを動かすユーザーの変更
  1. sudo nano /etc/apache2/envvars
  2. export APACHE_RUN_USER=www-dataexport APACHE_RUN_USER=pi に変える
  3. sudo /etc/init.d/apache2 reloadでここまで反映

phpMyAdminのインストール

何故かaptでインストールできなくなってるので手動インストール。Windowsマシンからブラウザを利用して設定する

  1. https://www.phpmyadmin.net/ からphpMyAdminをダウンロード
  2. Apacheの公開ディレクトリに置く
  3. sudo ufw allow 80
  4. sudo ufw reload
  5. http://192.168.xxx.xxx/phpmyadmin/setupへアクセス
  6. 適当に設定し、ダウンロードボタンを押すと設定ファイルが落ちてくるのでphpmyadminのルートに置く
  7. http://192.168.xxx.xxx/phpmyadmin/setupへアクセスしエラーになることを確認
  8. http://192.168.xxx.xxx/phpmyadminへアクセスし、MariaDBのIDPWでログインできることを確認
    1. この環境では80番ポートは外部公開してないので問題ないが、外部公開する場合は.htaccessをおいてローカル以外のアクセスを蹴ると良い

📈 Node.jsのインストール

  1. sudo apt install -y nodejs npm
  2. sudo npm i -g n yarn

🎈 おまけ

  • Gitのインストール
    • sudo apt install -y gitで2.20.1が入ることを確認(微妙に古い)
  • composerのインストール
    • sudo apt install -y composerで1.8.4が入ることを確認(かなり古い)