strt's blog

🗒🔨🙍

自宅サーバ+PWA+mTLSでiPhoneからアプリっぽいものを使えるようにした

2025/04/10

前回からもうちょい実用化を進め、以下のようなことを実施しました。

何をやったのか

  • PWAアプリの作成・自宅サーバへの自動ビルド
  • Cloudflare Tunnelで外部公開+mTLS、WAFでクライアント証明書を入れたデバイスからのみにアクセス制限

PWAアプリの作成・自宅サーバへの自動ビルド

今回は、ちょっとGoを書く機会があったのでそこから継続してバックエンドをGo/echo、フロントをReact&Vite + ViteのPWA用プラグインという感じです。UIコンポーネントは楽なのでMantine UIです。

フロント側が完全にSPAなので、ビルドしてからnginxに配置する形でdockerで起動することにしました。

FROM node:22-slim as builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:1.25.2-alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 8090
CMD ["nginx", "-g", "daemon off;"]

ちょっと詰まったこととしては、開発環境ではバックエンドのみdocker composeで立ち上がるようにしておいて、本番環境ではフロントのdocker-compose.ymlとバックエンドのdocker-compose.ymlをマージして起動するつもりだったのですが、Self-hosted Runner内で走らせた際に不安定になったりして面倒だった(クリーンアップが上手くできないなど)ので、諦めて本番環境用のdocker-compose.ymlをおくことで対応しました。

余談ですが、今回はCline + Github Copilotにある程度プログラミングは任せてみました。

特にFrontを直させる時に思ったのですが、事前にコーディング規約などは定義して食わせておいた方がよさそうですね。UIには深くこだわるつもりはなかったので、Mantine UIのsx propsは使うな、とか。

あとUI調整はやっぱりリトライが何回か要りそうな感じでした。適切な環境を整備してあげた方がよさそうですね。

Cloudflare Tunnelで外部公開+mTLS、WAFでクライアント証明書を入れたデバイスからのみにアクセス制限

Cloudflare Tunnelで公開するのは前回と一緒なのですが、今回はフロントとバックエンドを両方公開する必要があったので、別々のサブドメをつけて公開しました。

また、認証方式に関しても、Cloudflare Accessで一旦いいかなと思い設定はしたのですが、フロント/バックエンドで共通の認証を使いまわせるよう設定してみたものの、どうにもiPhoneのSafariではクロスサイトのCookie送信が制限されている関係上、Safari側の設定変更が必要ということで、認証通すのも面倒だし、クライアント証明書方式とすることにしました。

クライアント証明書はこのドキュメントを見ながら発行し、opensslコマンドでp12形式に変更後iPhoneに入れるだけです。

また、WAFのルールもクライアント証明書発行画面から作成できるので、そこから作ればOKという形です。

ただ、PWAを上記で取り扱う際の注意点は一つあり、アイコンとして設定している静的画像のパスはmTLS認証をWAFでバイパスさせる必要があります。 バイパスさせてないとアイコンが読み込めないんですよね。

感想

前回よりも色々ややこしい部分はありましたが、自分や身内用のサービスであればこの形で提供するのがだいぶローコストで良いやり方だなと感じています。

雑にアプリを作り放題になったのはでかいです。