XserverにNextcloudを導入

WEBサイトを運用するためにXserverレンタルサーバーを利用している。

月額1,000円ほどのスタンダード契約なんだけれど300GBのNVMeが割り当てられている。 メインの俳句サイトや個人ブログ、息子や娘のWordpressサイトなど複数ドメインで利用しているが、せいぜい30GBほどの消費で、将来的な増加を配慮したとしてもなお200GB超の余裕がある。

せっかくなので勉強を兼ねてNextcloudを導入してみた。 Dropboxも無料で16GBのスペースを確保できているので実用上は困っていないのだけれど、他に活用できるかもと思って導入してみた。 手順は、下記サイトのTipsを参考にした。

1. 導入手順

参考サイトに詳しく説明があるが、要はWordpressをインストールするのと同じだと考えれば良い。

1.1 インストールする場所を決める

サブドメインでも構わない。 自分は、サーバーを契約したときに自動的に割り当てられる独自ドメイン minorugh.xsrv.jp が使わずに残っていたのでそれを使いました。

  • Nextcloud本体をhome/minorugh/minorugh.xsrv.jp/public_html/nextcloud へインストールします。
  • データー保存用には、非公開ディレクトリhome/minorugh/data/nextcloudを作成しておきます。
📁 home/minorugh
|--📁 minorugh.xsrve.jp
|   |--📁 ...
|   └--📁 public_html
|       └--📁 nextcloud
└--📁 data
    └--📁 nextcloud

1.2 データーベースの準備

Nextcloud用にあたらしくデータベースを作成し、ユーザーを追加します。

エックスサーバーのサーバーパネル(MySQL設定)にて

  • 新規データベースの作成
  • 必要があれば新規ユーザー作成
  • アクセス権所有の設定

2. インストーラーのダウンロード

Nextcloud Install へアクセス、 DOWNLOAD Server > Community projects > Web installer をクリック、 setup-nextcloud.phpをダウンロードします。今回はサーバーへの転送を省くために直接サーバーにダウンロードします。

エックスサーバーにSSH接続して以下のコマンドを実行します

$ cd ~/minorugh.xsrv.jp/public_html/nextcloud

$ wget https://download.nextcloud.com/server/installer/setup-nextcloud.php
......
...... `setup-nextcloud.php' へ保存完了

3. インストール

minorug.xsrv.jp/nextcloud/setup-nextcloud.php へアクセスしてインストールします。

インストールディレクトリの指定に「.」を入力してカレントディレクトリに展開します。以上でインストールが完了してセットアップに移るのですが、エックスサーバーではこの記事公開時点で 500 Internal Server Errorが出ます。

minorugh.xsrv.jp/nextcloud/.htaccessの該当箇所を下記のように修正します。

<IfModule pagespeed_module>
#  ModPagespeed Off コメントアウト
</IfModule>

4. セットアップ

.htaccess の修正が終わったら再度minorugh.xsrver.jp/nextcloud へアクセスしてセットアップを終了させます。

Debian 11 bullseye 〜Wifiを使ったネットインストール

Debian10をインストールしてから最近11にアップデートしたのだけれど、いろいろ試行錯誤して触りまくっていたのでなんとなく安定しないので、思い切ってクリーンインストールすることにした。

Dotfilesのお陰でさほど苦労もなくdebian11をクリーンインストールして動作も安定し心なしかフットワークもかるくなった気がする。一年に一度くらいはメンテナンスを兼ねてクリーンインストールするのもいいかなと思った。基本的に下記のTipsの通りの作業であるが、何箇所か躓いているので備忘録を記す。

non-free-firmwareを含んだdebianインストールメディア

というのも見つけたので試したが、自分のThinkpadではだめだった。結局上記Tipsのとおりに、下記のfirmwareセットをダウンロードして上手く行った。

デスクトップ環境のリストア

パネル関係を再構築するのに結構手間取った。

どうバックしておいたら簡単にリストアできるのかわからなくて対策していなかったのだけれど、${HOME}/.config/xfce4フォルダーをバックしておくといい感じであった。次回は、これで試せるようにmakefileを修正しておいた。

Live版のインストールメディア

こちらも試して見た。インストールは簡単に出来てデスクトップ表示まではOKだったが、そこからインストールを選ぶとWiFiで躓く。 Live版にfirmwareを反映させる方法がわからないので諦めた。

Git と Dropbox の連携

重要なファイル群をDropboxに配置し複数端末で共有している。Dropbox だけでも多少の履歴は辿れるけれど、さらに保険をかける意味でGitHubにもリポジトリを作ってみようと思った。

Dropbox内にgitツリーを置くとややこしくなろそうなのでDropbox外の別デレクトリにtreeをおくというTipsを見つけて真似してみた。

$ cd ~/Dropbox/project

$ git init --separate-git-dir /path/to/project.git
Initialized empty Git repository in /path/to/project.git/

上記を実行すると、Dropboxデレクトリにあった .git デレクトリは、/path/to/project.git に移動し、もとのデレクトリには、以下の内容の .git というファイルが生成される。内容はリンク先を書いただけのテキストファイルなのだが、Dropboxデレクトリでは普通に magit-statusできる。

gitdir: /path/to/project.git

リストアするとき

もし、将来ローカルリポジトリのPCをクリーン再インスールするケースを想定してテスト用のリポジトリで試してみた。

mkdir /path/to && cd /path/to してgit clone priject.gitする。 データリポジトリは、Dropboxをインストールして同期すれば、自動的にリストアできるので、.gitデレクトリのみ残してデータは削除して良い。

競合コピーが生じないようにemacs-mozc辞書を共有する方法

mozc辞書をDropboxに置いて、そのシンボリックをそれぞれの各端末に貼って辞書共有をしている人は多いと思います。

リアルタイムで同時使用はしない…という使い方であれば何も問題ないのですが、 自分の場合は、基本メイン機のEmacsは起動しっぱなし(蓋閉じでSleep)なので、その状態でサブ機のEmacsを立ち上げると、mozcのON/OFFとは関係なく~/Dropbox/mozc/.mozc/ に競合コピーが量産されます。

そこで、簡単な回避方法を考えてみました。大げさなタイトルですが、Tipsといえるほどのものではありません。

ファイル体系

くどくど説明するより下図を見ていただければ、“な〜んだ” と理解いただけると思います。

メイン機の .mozc/ は、Dropboxに保存してシンボリックリンクで使い、サブ機で使うときはEmacsを起動するたびにDropboxにある最新の .mozc/ をコピーして使うという仕組みです。

※ maine-machine
~/.mozc <-- symbolic link -- ~/Dropbox/mozc/.mozc
                                | Copy latest every time
※ sub-mchine                    |
~/.mozc <-- symbolic link -- ~/Dropbox/backup/mozc/.mozc

Emacsの設定

emacsの設定ファイルはメイン機とサブ機で共有しているので、uname -n を条件子としてメイン機(自分の場合はe590)でない場合(サブ機のとき)は、emacsを起動したときにmozc辞書をコピーしています。シンボリックリンクは、一度貼っておけばコピーのたびに貼り直さなくても大丈夫です。

;; Clone the mozc dictionary placed in Dropbox to Nextcloud.
(defun mozc-copy ()
 "Copy mozc for submachine."
 (interactive)
 (unless (string-match "e590" (shell-command-to-string "uname -n"))
	 (compile "cp -rf ~/Dropbox/mozc/.mozc ~/Dropbox/backup/mozc")))
(add-hook 'emacs-startup-hook 'mozc-copy)

使い方

Dropboxに配置したmozc辞書は、メイン機での単語登録や入力履歴を記憶し常に最新の状態でバックアップされます。 サブマシーンの場合は、emacsを起動するたびに最新の辞書をコピーしてそれを使うという簡単な割り切りです。

サブマシーンで単語登録したら、元辞書へ書き戻すという仕組みも考えれますが、結局は、競合コピーをどう回避するかという課題になると思うので割り切ることにしました。良い方法があれば教えてください。

メイン機、サブ機の定義は特にありません。使用頻度の高い方をメイン機として構成すればいいかなと思います。

Windows11 非対応 CPU+TPM+セキュアブート回避最強編

Windows11を導入するためには3つの条件が必須になっています。

1. CPU
     ※ Intelの Coreシリーズは第8世代以降(Core i3/i5/i7の8000以降)
     ※ AMDの Ryzenシリーズは第2世代以降(Ryzen 5 2600以降)
2. TPM1.2/2.0
3. UEFI/セキュアブート(boot)

我が家で家族が使っているマシン5台について、Windows11へのアップグレードを試みましたがいづれもシステムチェックで引っかかりアウトでした。

まず最初に見つけた Tipsでレジストリを編集して3台は成功しました。

しかし残りの2台(Thinkpad X220、L540)は、セキュアブートでひっかかって駄目。

こちらもレジストリ編集でいけたという Tipsもあったので試しましたがアウトでした。

諦めるのは癪なので、ググって「最強編」なる Tipsを見つけました。

インスール用の ISOファイルを USBにコピーして、sourcesフォルダ内にある appraiserres.dllを削除してインストールするというものでした。 ただし、その手順にやや注意事項があるようなので転載しておきます。

1. appraiserres.dllを削除

ダウンロードした ISOファイルを直接編集して appraiserres.dllを削除しよとしてもできませんでしたので、一度 USBにコピーして作業しました。 削除でもリネームでも構わないようで、念の為に Windows10の appraiserres.dllと差し替えるという方もいましたが、私の場合は削除で問題なくインストールできました。

2. ISOファイルから起動

ISOファイルをダブルクリックすると下記の通りマウントされるので setup.exeを実行すます。

Alt Text

3. セットアップ画面

ISOファイル中の setup.exeを実行すると、何度か画面が変遷して下記の画面で入力まちになります。

Alt Text

ここでのポイントは、必ず

「セットアップでの更新プログラムのダウンロード方法の変更」

をクリックしてインストールしなければいけません。

そのまま次へを押してしまいますとすステムチェックされてインストール出来ません。

4. 更新プログラムの入手は「今は実行しない」を選ぶ

続いて次の画面に代わります。

Alt Text

ここでも大事なポイントがあり、

今は実行しない

にチェックを入れて「次へ」を押します。

この方法で残り2台も無事 Windows11へアップグレードできました。

5. この手法の問題点

先人の Tipsによるとこの最強編でインストールしたら日々のアップデートを自動でしてくれないとのことでした。

けれども私の場合は、今のところ2台共その心配はなく機嫌よく動いて、自動アップデートにも対応しているようです。

2台共 Windows10 Proだったのでそのへんが関係しているのかもされえません。

まだ、完全に安心はできないですが暫く様子を見てみましょう。

でも Micro Softが、どうな目算があってこんな意地悪な制限をするのか不可解、単なるパソコンメーカー販促への義理だてとしか思えない。

SlackAppを最小化状態で自動起動する for Linux

元ネタ SlackAppを最小化状態で自動起動する

SlackAppを自動起動にしている場合は ~/.config/autostart/slack.desktop と言うファイルがあります。 私の環境では、slack.desktop/usr/share/applications/slack.desktop に存在していました。 なので、編集するには `sudo`` が必要です。

[Desktop Entry]
Name=Slack
StartupWMClass=Slack
Comment=Slack Desktop
GenericName=Slack Client for Linux
Exec=/usr/bin/slack %U
Icon=/usr/share/pixmaps/slack.png
Type=Application
StartupNotify=true
Categories=GNOME;GTK;Network;InstantMessaging;
MimeType=x-scheme-handler/slack;

Exec が実際に実行するコマンドを指定しています。/usr/bin/slack が本体なので、この直後に --startup を挿入すれば最小化状態で自動起動するようになります。

Exec=/usr/bin/slack --startup %U

おそらく、SlackAppをアップデートすると /usr/share/applications/slack.desktop は上書きされて --startup が消えるので、~/.config/autostart/ にはシンボリックリンクではなく、コピーを置くなどのしたほうがいいです。

SylpheedやEmacsをログイン時に最小化起動させる

元ネタは下記

Devil’s Pieのインストール

 sudo apt install devilspie

設定ファイルの作成

~/.devilspie/に設定ファイル devils_startup.dsを以下の内容で作成する。 ファイル名は拡張子が.dsならアプリケーション名でなくてもいいようだ。

(if (is (application_name) "sylpheed")
	(begin (minimize))
  (if (is (application_name) "emacs")
	  (begin (minimize))
	))

Devil’s Pie起動&終了スクリプトの作成

/usr/local/bin/あたりにシェルスクリプト devils_startup.shを以下の内容で作成する。ファイル名は任意、実行権限を忘れずに付与しておくこと。

#!/bin/bash
devilspie &
devils_startup & # Specify ** of **.ds
sleep 5s
killall -9 devilspie

devilspieは常駐監視するタイプのツールなので、お役目が済んだら5秒で強制終了させている。 EmacsやSylpheedが最小化しないときは時間を延ばしてみて調整する。

シェルスクリプトを自動開始アプリケーションに登録する

devilspie活用Tipsの多くは、あまり触れていないが、今回のような目的に使う場合は、当然ながら devils_startup.sh を自動開始アプリケーションに登録する必要がある。

Debian場合は「設定マネージャー」→「セッションと起動」→「自動開始アプリケーション」

Sylpheedの設定「新着メールを自動チェックする(○分ごと)」「起動時に新着メールをチェックする」を利用するとバックグラウンドでメールチェックしてくれて便利。

GUIの起動時にパスフレーズを自動入力して ssh-add を実行させる

Emacsを作業テーブルとして常用的に SSHを使うので、ログイン時にパスフレーズを自動入力させて ssh-addを実行させるように環境構築したので備忘録を残しておく。

Debian Linux環境であるので他の環境の場合は、それぞれに応じた工夫がいるかと思う。

  1. autologin.sh の設定(shell script)
  2. autostart.desktop の設定(Linuxの自動起動)

autologin.sh

expectを利用した標準的なスクリプトです。

#!/usr/bin/expect
# Run ssh-add with passphrase auto input at GUI startup
# Look ${PWD}/.config/autostart/autologin.desktop

# Include Password
source ~/Dropbox/backup/zsh/env.sh

spawn ssh-add /home/minoru/.ssh/id_rsa
expect "Enter passphrase for /home/minoru/.ssh/id_rsa:"
send "${PW}\n";
interact

autologin.sh はどこに配置してもよいのですが、私の場合は、ホームデレクトリに置きました。

作成後、動作権限の付与を忘れないように。

$ chmod 600 autologin.sh

スクリプトは GitHubで公開しているので passphraseは直接書かないで別ファイルとしてインクルードしている。

include するファイルは下記のような内容である。

## Password file to include in ~/.autologin.sh
set PW "<your passphrase>"

your passphrase には、秘密鍵 id_rsa の作成時に設定したパスワードを書きます。パスワードは長いほど解読されにくくて安全なのですが、長すぎると暗号化や復号処理に過大な負荷がかかります。私の場合は安全を考えて40桁にしましたが今の所無理なく機能しているようです。

autostart.desktop

GUIログイン時に autologin.shが自動起動されるように設定します。

debian Linuxの GUI「セッションと起動」に直接設定してもいいのですが、下記のような autostart.desktopファイル作成したほうが簡単です。

[Desktop Entry]
 Version=1.0
 Name=AutoLogin
 Comment=Run ssh-add with passphrase auto input at GUI startup
 Exec=gnome-terminal -- zsh -c "expect $HOME/.autologin.sh"
 Icon=utilities-terminal
 Terminal=false
 Type=Application
 Categories=Application;

これを、~/.config/autostart フォルダーに保存します。上記の設定の場合、gnome-terminal は、コマンド実行後すぐに閉じます。

UpFtpを改造して UpSFTPを作った

ホームページを更新するのに結城浩さん作の upftp.plを FTPSモードで使っていたが SFTPで使えるようにしたいと思い試してみました。

Net::SFTPを入れようとトライしたのですがうまくいかず、Perlでは Net::SFTP::Foreignを使うという情報を見つけたので cpamで入れてみたらあっさり認識してくれました。IO::Ptyも入れるようにメッセージがでたのでこれも installしました。

私の利用している xserverの場合、SFTPの標準ポート22では使えなかったのでオプションで指定しました。

#!/usr/bin/perl
#
# This is UpSFTP, Version 1.0
# Copyright (C) 2022, by Minoru Yamada.
# This program is a modification of Hiroshi Yuki's upftp.pl for use with SFTP.
# https://minorugh.xsrv.jp/post/2022/0119-upsftp/
# https://github.com/minorugh/upsftp
#
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
use strict;
use warnings;
use Net::SFTP::Foreign;

########################################
# Configuration
########################################
# Show debug info: 0 (nodebug), 1 (terse), 2 (verbose)
my $debug = 0;
# Show update info.
my $show_update = 1;
# Your SFTP host name.
my $hostname = 'yoursftp.doain';
# Your SFTP port.
my $portnumber = 'portnumber';
# Your SFTP user name.
my $username = 'yourname';
# Optional settings
my $moreoptions = [ -o => 'StrictHostKeyChecking no' ];
# Remote root directory (in fullpath)
my $remoterootdir = '/home/youraccount/public_html';
# Local root directory (in fullpath)
my $localrootdir = "/usr/home/myname";
# File list (in fullpath)
my $filelist = "/usr/home/myname/filelist.txt";

########################################
# End of configuration.
########################################
my $sftp;
my @newfilelist;

&upsftp;
exit(0);

sub upsftp {
    if ($debug) {
		print "Simulation only, I do not transfer any file.\n";
    }
    unless ($hostname) {
        print "\$hostname is empty, abort.\n";
        return;
    }
    unless ($username) {
        print "\$username is empty, abort.\n";
        return;
    }
    unless ($portnumber) {
        print "\$hostport is empty, abort.\n";
        return;
    }
    unless ($remoterootdir) {
        print "\$remoterootdir is empty, abort.\n";
        return;
    }
    unless ($localrootdir) {
        print "\$localrootdir is empty, abort.\n";
        return;
    }
    unless ($filelist) {
        print "\$filelist is empty, abort.\n";
        return;
    }
    print "filelist is $filelist\n" if ($debug);
    if (!open(FILELIST, $filelist)) {
        print "$filelist is not found.\n";
        return;
    }
    while (<FILELIST>) {
        chomp;
        next if (/^#/);
        my ($filename, $updatetime) = split(/,/);
        $updatetime = 0 if (not defined($updatetime) or $updatetime eq "");
        print "$filename = $updatetime\n" if ($debug > 1);
        my $mtime = (stat("$localrootdir/$filename"))[9];
        $mtime = 0 if (not defined($mtime) or $mtime eq "");
        print "mtime = $mtime\n" if ($debug > 1);
        if (defined($mtime) and $mtime > $updatetime) {
            print "Update $filename\n" if ($debug or $show_update);
			&sftp_put("$localrootdir/$filename", "$remoterootdir/$filename");
        } else {
            print "Skip $filename\n" if ($debug);
        }
        my $curtime = time;
        push(@newfilelist, "$filename,$curtime\n");
    }
    close(FILELIST);
	&sftp_close;
    if (!open(FILELIST, "> $filelist")) {
        print "$filelist: Cannot create.\n";
        exit(-1);
    }
    print FILELIST @newfilelist;
    close(FILELIST);
}

# Put $localfile to $remotefile.
sub sftp_put {
    my ($localfile, $remotefile) = @_;
    $sftp = Net::SFTP::Foreign->new($hostname,
									port=> $portnumber,
									user=> $username,
									more=> $moreoptions);
    $sftp->put($localfile, $remotefile);
}

# Closing the connection to the remorte server
sub sftp_clode {
	undef $sftp;
	print "Disconnecting from remote server\n";
}
1;

iframeの高さを取得し自動調整する

レスポンシブ Webデザインでは、iframeの高さが PCとスマホ・タブレットで結構変わってしまうことも多くて事前に高さを決め打ちで指定できません。

そこで、JavaScript(jQuery)を使って iframeの高さを自動的に設定してくれるスクリプトを探しました。

親ページと子ページのそれぞれで設定の必要な Tipsが多い中、 親ページの設定のみで動作するものを見つけて試したところ実に快適だったのでこのスクリプトを採用することにした。

HTMLで準備すること

高さを自動調整したい iframeの classに「autoHeight」を付けるだけです。

<iframe src="http://www.example.com/" class="autoHeight"></iframe>

iframeの高さを自動的に調整してくれるスクリプト

jQueryを読み込んだ状態で以下のスクリプトを実行します。

(function(window, $){
	$(window).on("load",function(){
		$('iframe.autoHeight').each(function(){
			var D = $(this).get(0).contentWindow.document;
			var innerHeight = Math.max(
				D.body.scrollHeight, D.documentElement.scrollHeight,
				D.body.offsetHeight, D.documentElement.offsetHeight,
				D.body.clientHeight, D.documentElement.clientHeight
				);
			$(this).removeAttr("height").css('height', innerHeight + 'px');
		});
	});
})(window, jQuery);

ページに配置された画像などの読み込みが完了した時点で iframeの高さを調整します。

同じページ内に複数の iframeがあっても、正常に高さを設定できます。

class="autoHeight" と書くだけで scrolling="no" frameborder="no" とかを書く必要なくとてもシンプルな優れものでした。

参考サイト