以前はブラウザ版Gmailで他社メールを受信する機能もありましたが、すでにこの機能は廃止されています。また、外部メールに対応していても受信間隔が長かったりと実用が難しいところもあったりします。この用途だと「Zoho Mail」が使いやすく、昔使っていたこともありますが、外部メールに対応するWebメールをセルフホスト出来れば便利かなと試してみました。
出来れば複数アカウントを1画面で表示出来るものはないかと探したところ、「Cypht」がその要件を満たせそうでした。

LXDコンテナ内にセットアップ
LXDコンテナでセットアップしてみました。DockerやTailscale認証も済んでいる環境で、以下をコピペすればインストールされます。
#!/bin/bash
set -e
# ─────────────────────────────────────────
# Cypht セルフホスト セットアップスクリプト
# 対象: Ubuntu 26.04 LXD コンテナ (Docker済み, Tailscale認証済み)
# 配置先: /opt/cypht
# 公開: Tailscale Serve https://<host>.ts.net:3315
# ─────────────────────────────────────────
echo "========================================"
echo " Cypht セットアップ"
echo "========================================"
echo ""
# ── ユーザー入力 ──────────────────────────
read -p "Cypht 管理者ユーザー名を入力してください: " CYPHT_USER
if [[ -z "$CYPHT_USER" ]]; then
echo "エラー: ユーザー名が空です。" && exit 1
fi
while true; do
read -s -p "Cypht 管理者パスワードを入力してください: " CYPHT_PASS
echo ""
read -s -p "パスワードを再入力してください: " CYPHT_PASS2
echo ""
if [[ "$CYPHT_PASS" == "$CYPHT_PASS2" ]]; then
break
else
echo "パスワードが一致しません。再入力してください。"
fi
done
if [[ ${#CYPHT_PASS} -lt 8 ]]; then
echo "エラー: パスワードは8文字以上にしてください。" && exit 1
fi
echo ""
echo "ユーザー名: $CYPHT_USER"
echo "設定を開始します..."
echo ""
# ── 変数定義 ──────────────────────────────
CYPHT_DIR="/opt/cypht"
INTERNAL_PORT=8880
TAILSCALE_PORT=3315
DB_PASS=$(openssl rand -hex 16)
DB_ROOT_PASS=$(openssl rand -hex 16)
# ── ディレクトリ作成 ───────────────────────
mkdir -p "$CYPHT_DIR"
# ── Docker Compose ファイル生成 ────────────
cat > "$CYPHT_DIR/docker-compose.yml" << EOF
services:
db:
image: mariadb:10.11
container_name: cypht_db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}
MYSQL_DATABASE: cypht
MYSQL_USER: cypht
MYSQL_PASSWORD: ${DB_PASS}
volumes:
- cypht_db_data:/var/lib/mysql
networks:
- cypht_net
app:
image: cypht/cypht:latest
container_name: cypht_app
restart: unless-stopped
depends_on:
- db
ports:
- "127.0.0.1:${INTERNAL_PORT}:80"
environment:
AUTH_USERNAME: ${CYPHT_USER}
AUTH_PASSWORD: ${CYPHT_PASS}
DB_CONNECTION_TYPE: host
DB_DRIVER: mysql
DB_HOST: db
DB_NAME: cypht
DB_USER: cypht
DB_PASS: ${DB_PASS}
SESSION_TYPE: DB
USER_CONFIG_TYPE: DB
volumes:
- cypht_user_data:/var/lib/hm3/users
- cypht_attachments:/var/lib/hm3/attachments
networks:
- cypht_net
volumes:
cypht_db_data:
cypht_user_data:
cypht_attachments:
networks:
cypht_net:
driver: bridge
EOF
echo "docker-compose.yml を生成しました"
# ── 認証情報をファイルに保存 ──────────────
cat > "$CYPHT_DIR/.credentials" << EOF
# Cypht 認証情報 - 確認後に削除してください
# rm ${CYPHT_DIR}/.credentials
ユーザー名 : ${CYPHT_USER}
DB パスワード : ${DB_PASS}
DB root パスワード : ${DB_ROOT_PASS}
EOF
chmod 600 "$CYPHT_DIR/.credentials"
# ── 起動 ──────────────────────────────────
echo ""
echo "Docker イメージを取得・起動しています..."
cd "$CYPHT_DIR"
docker compose pull
docker compose up -d
# ── DB初期化待機 ──────────────────────────
echo ""
echo "データベースの初期化を待っています (最大90秒)..."
for i in $(seq 1 18); do
sleep 5
if docker compose exec -T db mysqladmin ping -u"cypht" -p"${DB_PASS}" --silent 2>/dev/null; then
echo "データベース準備完了 ($((i*5))秒)"
break
fi
echo "待機中... ($((i*5))秒)"
done
# ── Cypht起動待機 ─────────────────────────
echo ""
echo "Cyphtの起動を待っています (最大60秒)..."
for i in $(seq 1 12); do
sleep 5
if curl -sf "http://localhost:${INTERNAL_PORT}/" &>/dev/null; then
echo "Cypht 起動確認 ($((i*5))秒)"
break
fi
echo "待機中... ($((i*5))秒)"
done
# ── Tailscale Serve 設定 ──────────────────
echo ""
echo "Tailscale Serve を設定中..."
# 既存設定バックアップ
tailscale serve status --json 2>/dev/null \
> "${CYPHT_DIR}/tailscale-serve-backup-$(date +%Y%m%d%H%M%S).json" || true
# --bg で既存設定を保持したまま3315番を追加
tailscale serve --bg --https="${TAILSCALE_PORT}" "http://localhost:${INTERNAL_PORT}"
# ── 完了メッセージ ────────────────────────
TS_HOSTNAME=$(tailscale status --json 2>/dev/null \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d['Self']['DNSName'].rstrip('.'))" \
2>/dev/null || echo "<your-hostname>.ts.net")
echo ""
echo "========================================"
echo " ✅ Cypht セットアップ完了!"
echo "========================================"
echo ""
echo " アクセスURL : https://${TS_HOSTNAME}:${TAILSCALE_PORT}/"
echo " ユーザー名 : ${CYPHT_USER}"
echo " パスワード : (入力したもの)"
echo ""
echo " 認証情報の保存先: ${CYPHT_DIR}/.credentials"
echo " 確認後に削除 : rm ${CYPHT_DIR}/.credentials"
echo ""
echo " ログ確認: cd ${CYPHT_DIR} && docker compose logs -f"
echo " 停止 : cd ${CYPHT_DIR} && docker compose down"
echo ""
echo " 現在の Tailscale Serve 設定:"
tailscale serve status
echo "========================================"
unset CYPHT_PASS CYPHT_PASS2
日本語表示やタイムゾーンを設定
起動したら設定したユーザー名とパスワードでログインします。

設定で日本語表示やタイムゾーンを変更できます。

アカウント設定が問題なければ、このような感じでメールが一覧表示されます。

機能的には満たしているんでしょうけど、いまいち使いやすさを感じなく。操作や動作も古臭い感じがありますし。
もっと良いものがないか、探してみたいと思います。

