さくらのレンタルサーバーでAVIFを作れるようにする

さくらのレンタルサーバーでもAVIFが作れたらいいよねというのでやってみた。

前提

  • シェルにzshを使っている。さくらのレンタルサーバーのデフォルトシェルはcshなので注意されたし。
  • ~/binにパスが通っている

やり方

  1. アセンブラのビルド

    cd ~
    wget https://www.nasm.us/pub/nasm/releasebuilds/2.16.03/nasm-2.16.03.tar.xz
    tar xf nasm-2.16.03.tar.xz
    cd nasm-2.16.03
    ./configure --prefix=$HOME
    gmake -j4 && gmake install
    
    nasm -v
    
  2. libavifのビルドとゴミ掃除

    cd ~
    git clone -b v1.2.1 https://github.com/AOMediaCodec/libavif.git
    sed -i '' 's|^static_assert(sizeof(off_t) == sizeof(int64_t), "");|/* & */|' libavif/src/io.c
    cmake -S libavif -B libavif/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF \
    -DAVIF_CODEC_AOM=LOCAL -DAVIF_LIBYUV=LOCAL -DAVIF_LIBSHARPYUV=LOCAL \
    -DAVIF_JPEG=LOCAL -DAVIF_ZLIBPNG=LOCAL -DAVIF_BUILD_APPS=ON
    cmake --build libavif/build --parallel 1
    cp ~/libavif/build/avifenc bin/
    rm -Rf libavif nasm-2.16.03 nasm-2.16.03.tar.xz
    
  3. avifを作る
    avifenc -q 65 -y 420 -s 6 --ignore-xmp src.jpeg out.avif
    

あとがき

これを活用すればさくらのレンタルサーバーでもavifを作れるようになるので、任意のCMSから蹴ればサムネイルの軽量化とかができるかもしれない。注意点としてコマンドライン呼び出しになるため任意コマンドが実行されないように注意する必要はある。

ビルドはnice不要で、avifの生成についても4000x3000のJPEGをAVIFにするのはniceなしで行けた。

レンタルサーバーにないバイナリをソースコードからビルドして使うという意味で、本記事はさくらのレンタルサーバーにNode.jsをインストールするの親戚記事である。

さくらのレンタルサーバーにSerene Bach v4を設置してみた

さくらのレンタルサーバーにSerene Bach v4.0.0-beta.25を設置してみたので、その時のメモ。運用する気がないため画面が出ることと記事が書けること以外何も見ていない。

公式のドキュメントが日英混在で解りづらく、なんか書いてるのを適当に試しても上手く行かなかったので手順を残す。

前提条件

/home/<ユーザーID>/www/blogに設置し、このパスにblog.example.comを割り振り、https://blog.example.comでアクセスするものとする。

設置手順

  1. 必要なファイルをダウンロードし設置する

    # 展開先のパスをここに書く
    DIST="blog"
    
    mkdir -p "${DIST}"
    wget 'https://github.com/serendipitynz/serenebach/releases/download/v4.0.0-beta.25/serenebach-v4.0.0-beta.25-freebsd-amd64.tar.gz'
    tar xzvf serenebach-v4.0.0-beta.25-freebsd-amd64.tar.gz -C "${DIST}" --strip-components=1
    rm serenebach-v4.0.0-beta.25-freebsd-amd64.tar.gz
    cd "${DIST}"
    chmod 755 serenebach
    mv serenebach serenebach.cgi
    
    cat <<'EOF' > .htaccess
    RewriteEngine On
    # ブログをサブパス(例 /blog/)に置く場合は、実際のパスに合わせる:
    RewriteBase /
    
    # ① データベースなど内部ファイルを外部から遮断する(最優先・必須)
    RewriteRule ^data/ - [F]
    
    # ② すでにサーバにある「古い画像ファイル」だけ直接配信する。
    #    実在チェック(-f)で絞るのがポイント。存在しない画像リクエストは③で
    #    Serene Bach に渡り、アップロード画像・OG カードなどが配信される。
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^img/ - [L]
    
    # ③ それ以外はすべて CGI へ渡す(ブログ本体・旧 sb.cgi・旧 *.html・
    #    カテゴリーディレクトリも Serene Bach に届き、旧 URL 転送が働く)
    RewriteRule ^serenebach\.cgi/ - [L]
    RewriteRule ^(.*)$ serenebach\.cgi/$1 [L]
    EOF
    
  2. https://blog.example.comにアクセスしセットアップを流す

  3. 最初のセットアップ画面。管理者ユーザー名、パスワードさえ入れれば通る。
    最初のセットアップ画面。管理者ユーザー名、パスワードさえ入れれば通る
  4. ログイン画面。さっき設定した内容でログイン
    設定するとログイン画面に遷移するのでさっき設定した内容でログインする
  5. 管理画面。新規記事で記事が書ける
    ログインすると管理画面に遷移するのでここで記事が書ける
  6. 執筆画面。HTML、Markdown、sbtextを選べる
    新規記事作成画面ではHTML、Markdown、sbtextを選べた
  7. 公開画面トップ
    https://blog.example.comにもう一度アクセスすると公開ページのトップが出るようになっていた

Serene Bach v4とLyndbaum、GitHubでMarkdownの解釈を比較してみた

GitHubを正とした場合、次の違いが見られた。パーサーごとにこういう違うが出るのは面白い。

  • Lyndbaum
    • 斜体構文が下線付きで太字、斜体にならない(HTML上は<em>で出しているため仕様上は正しい。CSSでわざとやってる)
  • Serene Bach v4
    • 引用のネストで色が変わる、斜体になる
    • 単なる改行は未反映
    • 脚注構文未対応
      • リンクは出るが文字列に飛ぶ
Serene Bach v4 Lyndbaum v4.21 GitHub
上記で利用した構文
# 見出し1

## 見出し2

### 見出し3

#### 見出し4

##### 見出し5

###### 見出し6

####### 見出し7

# ほげ

段落1寿限無、寿限無、五劫ごこうのすりきれ、海砂利水魚、水行末・雲来末・風来末、食う寝るところに住むところ、やぶらこうじのぶらこうじ、パイポ・パイポ・パイポのシューリンガン、シューリンガンのグーリンダイ、グーリンダイのポンポコピーのポンポコナの、長久命ちょうきゅうめいの長助!

段落2日本語のMarkdownを
快適に書ける
そんなパーサーがあるといいな

## ふが

1. 番号付きリスト
2. ほげほげ

ここは段落

- ふつーのリスト
- ふがふが

ここも段落

- ふつーのリスト
  - ネストされたふつーのリスト
- ぴよぴよ
  1. ネストされた数字のリスト
  2. にこめ
     - ネストされた普通のリスト

1. 番号付きリスト
   - ネストされたふつーのリスト
     - 更にネストされたふつーのリスト
2. ほげほげ
3. 一行空きリスト開始

   ```bash
   #!/bin/sh
   # デバイスが存在しなければ終了
   [ -n "$DEVICE" ] || exit 0
   ```

4. 一行空きリスト終了(Prettierのフォーマットで生まれる)

リストとリストの間に別のブロックが入ると切れる

1. uniuni
   ```bash
   #!/bin/sh
   # デバイスが存在しなければ終了
   [ -n "$DEVICE" ] || exit 0
   ```
2. aa

## ぴよ

[リンク](https://example.com)

_斜体_
**太字**
~~取り消し線~~

> スペース空き引用
>
> > スペース空き引用の中の引用
> >
> > > スペース空き引用の中の引用の中の引用
>
> コードフェンス引用
>
> ```php
> <?php
> echo "aaa";
> ?>
> ```

<!--prettier-ignore-->
>スペースなし引用
>
>>スペースなし引用の中の引用
>>
>>>スペースなし引用の中の引用の中の引用
>
>コードフェンス引用
>
>```php
><?php
>echo "aaa";
>?>
>```

# 季節の食べ物について

## そうめん

今年もそうめん[^1]の季節になってきた。

[^1]: 関西地方でよく食べられる細い麺である。

## うどん

うどん[^udon]もいいだろう。

[^udon]: 讃岐うどんがうどんのすべてのような顔をしているが稲庭うどんなどもある

<http://example.com>

a ->
<-b
<-hoge->

| th1 | th2 |
| --- | --- |
| aaa | bbb |
| ccc | ddd |

---

# 番号リストテスト

1. あ
2. い
3. う
4. え
5. お
6. か
7. き
8. く
9. け
   - 桁が変わると
10. こ
    - 桁が変わるとインデントが深くなる



ほげほげ[^11]

[^11]: ほげほげの脚注

# ああああ

ふがふが

ぴよ[^12]ぴよ

[^12]: ぴよぴよの脚注

## いいいい

foobarbaz1[^124]
foobarbaz2[^124]
foobarbaz3[^124]

# C#

[^124]: foobarbazの脚注

あとがき

Lyndbaumの斜体問題についてだが、これは仕様としている。

まず個人的に_underscore_は下線だと考えており、斜体は*italic*だと考えているの。しかしMarkdown的にはどちらも同じで、Prettierは文脈に応じてアンダースコアをアスタリスクに変換するため、文中にこの二つが混在することがしばしばある。

つまり下線付きか斜体かを区別することが難しい。そこで私は下線付き太字として本来のMarkdownと異なる解釈をすることにした。斜体って読みづらいし。HTML的には<em>で出ているので見た目だけの問題である。

さくらのレンタルサーバーにCachetを設置したログ

ステータス管理画面のCachetをさくらのレンタルサーバーに設置したときのログ。

開発版の3.xを利用しているが、軽く叩いた感じはとりあえず使える気がする。

確認環境

確認時点でのさくらのレンタルサーバーではSQLiteでの動作は出来なかった。これはPHP拡張がJSONをサポートしていないからと思われる。

Env Ver
Cachet 3.x 2b0fc68988309647bdc0ba8e0b40862a3b8ddef4
cachethq/core 87be2387c06264c672dad94c87d00408bf34536d
PHP 8.3.31
MySQL 8.0

Cachetには正確なバージョン番号がなさそうなのでコミットハッシュを書いている。最新のハッシュのコードが入っていることを確認済。

またCachet 3.xの中身は事実上からっぽで、vendor/配下にあるcachethq/coreが本体なので、そちらのバージョンも併記している。

手順

以下のコマンドはすべてzshで実行しているため、さくら標準のcshでは動かない箇所があるかもしれない。

  1. composerがなかったのでcomposerを入れた。ここから先は~/bin/にPATHが通っていることを前提で進める

    php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
    php -r "if (hash_file('sha384', 'composer-setup.php') === 'c8b085408188070d5f52bcfe4ecfbee5f727afa458b2573b8eaaf77b3419b0bf2768dc67c86944da1544f06fa544fd47') { echo 'Installer verified'.PHP_EOL; } else { echo 'Installer corrupt'.PHP_EOL; unlink('composer-setup.php'); exit(1); }"
    php composer-setup.php
    php -r "unlink('composer-setup.php');"
    
    mkdir ~/bin
    mv composer.phar ~/bin/composer
    
  2. Cacheの取得と設置

    git clone -b 3.x https://github.com/cachethq/cachet.git
    cd cachet
    
    composer install --no-dev -o
    # composerでエラーが出てupdateしろといわれたためupdate、これでインストールまでしてくれる
    composer update
    # 本体のアップデート
    composer update cachethq/core
    # 環境変数の編集
    cp .env.example .env
    
  3. .envの編集
    デフォルトでAPP_DEBUGがtrueなのでfalseにした方が良い。まだ開発版のためかTIMEZONEを設定してもトップ画面には反映されない。管理画面の一部では反映される。

    APP_DEBUG=false
    APP_TIMEZONE="Asia/Tokyo"
    APP_URL=https://status.example.com
    DB_CONNECTION=mysql
    DB_HOST=DBホスト
    DB_PORT=3306
    DB_DATABASE=データベース名
    DB_USERNAME=データベース名
    DB_PASSWORD=パスワード
    
  4. Cachetのセットアップ

    php artisan key:generate
    
    php artisan vendor:publish --tag=cachet
    php artisan migrate
    
    # envを閲覧不能にする
    cat <<'EOF' | tee .htaccess
    <Files .env>
    deny from all
    </Files>
    EOF
    
    # 403になることを確認
    curl https://status.example.com/.env
    
    php artisan cachet:make:user
    
  5. crontの設定。ステータスページ表示する機能しかないのにやる意味があるのかは謎。
    *   *   *   *   *   php /home/<username>/www/path/to/artisan schedule:run >> /dev/null 2>&1
    
  6. さくらのコンパネからドメインを開き、Web公開フォルダーをpath/to/cachet/publicにする。

備考

Cachet v3.x is currently in development and not yet released. The following instructions are intended for development purposes only and are subject to change.

現時点では上記のようにあり、開発版なのでバグはあると思われる。

トラブルシューティング

Illuminate\Database\QueryExceptionが出る

SQLiteを使っていて次のようなエラーが出る場合、MySQLに変えると直る。恐らくさくらのレンサバに入ってるSQLite拡張がjson_eachをサポートしてないのが原因。

!Illuminate\Database\QueryException

Internal Server Error


SQLSTATE[HY000]: General error: 1 no such table: json_each (Connection: sqlite, SQL: select *
from "webhook_subscriptions" where ("send_all_events" = 1 or exists (select 1 from
json_each("selected_events") where "json_each"."value" is component_updated)))

Expand vendor frames

app/Http/Middleware/TrustProxies.php :32

あとがき

ステータスページを作る以上の機能が中区、外形監視はしてくれなかった

外形監視をして、その結果をステータスに表示してくれるツールだと思っていたら、ステータスの設定を行う機能と、それを表示する機能しかなかった。

つまり手動でメンテナンス中とか出したり、外形監視からAPIを蹴って何か表示するのには使えるが、このツールにはそれ以上の機能はないようだ。

これはダッシュボードを作る画面とAPIを提供してくれるツールということだ。

親切だったユーザー作成ウィザード

install.phpにアクセスして設定を書き換えるみたいな、一瞬ではあるものの脆弱な瞬間がないのは便利だと思った。

簡単なものなら自作できそう

Cachetは画面操作によってステータスを変えたり、履歴を出したりできるが、curlを投げて落ちてたら画面に表示くらいならパパっと作れそうだなと思った。

とはいえ、画面のリッチさや、APIからも操作できることなどを考えると、そんなのを作るのも大変なので、Cachetのようなツールを使った方が楽なのは間違いない。

ほぼ自分しか使ってないサーバーのためにこんなリッチなものが必要なのか…?

まぁあった方が豪華だし…みたいな…。

保守やオペのコストの方が高いので結局使わずじまいになる可能性も無きにしも非ずではある。

さくらのレンタルサーバーに任意のCPANモジュールを入れて使う方法

ググって出てきた記事が軒並み古くて役に立たなかったので、令和八年最新版として書いておく。

やり方

  1. CPANMのインストール
    curl -L https://cpanmin.us | perl - App::cpanminus
    
  2. CPANMのパスを.cshrcに書く
    私はzshを使っているため以下に.zshrcでの設定例を記述する。デフォルト環境はcshなので、cshの人は.cshrcに同じようなことを書けば成り立つはずだ。
    echo PATH=${HOME}/perl5/bin:${PATH}
    
  3. local::libをインストールする
    local::libはroot以外にあるCPANモジュールを使うためのものらしい。これを自分のホームディレクトリ配下に入れるようにコマンドを流す。
    cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
    

使い方

以下のようなコマンドを流すとパスを指定してCPANモジュールを取得・展開できる。

# 書式
cpanm -l <パス> <モジュール名>

例えば以下を流すとpwd配下にextlibディレクトリが生成され、IP::Geolocation::MMDBがダウンロードされて展開される。勿論、依存関係も勝手に解決してくれる。

cpanm -l extlib IP::Geolocation::MMDB

モジュールを利用するときはライブラリの配置されているルートを指定し、次にモジュール名を指定するとうまくいくようだ。

use lib './extlib/lib/perl5';
use IP::Geolocation::MMDB;

あとがき

https://cpanmin.us/を見に行くと以下の記述があり、辿ってみると日本の人が作っていてちょっと驚いた。

# This is a pre-compiled source code for the cpanm (cpanminus) program.
# For more details about how to install cpanm, go to the following URL:
#
# https://github.com/miyagawa/cpanminus

さくらのレンタルサーバーにLet's EncryptのDNS-01 チャレンジの証明書を持ち込む

さくらのレンタルサーバーにLet's EncryptのDNS-01 チャレンジの証明書を持ち込む方法。自動更新できないので実用性はないが、一時的に使う場合に有用。

前提条件

DNS-01 チャレンジの証明書を既に作っている。

やり方

  1. 発行した証明書をhomeに移す
    sudo cp /etc/letsencrypt/live/<サイトディレクトリ>/*.pem .
    sudo chown $USER:$USER privkey.pem fullchain.pem
    
  2. さくらのコンパネから設定するドメインのSSL設定を開く
  3. SSL証明書の種類を選択→独自SSL
  4. 秘密鍵にprivkey.pemをアップロードする
  5. SSL証明書インストールでfullchain.pemの中身を張り付けて登録する