VakKarma は、2 ちゃんねる風のスレッドフロート型 BBS です。
ゼロちゃんねるプラスを参考に開発されました。
- ゼロちゃんねるプラスに似た UI
- スレッドフロート型
- クライアントサイドで JavaScript を使用しない動作
- レスポンシブデザインへの対応(Tailwind CSS を採用)
- 1 コマンドでデプロイ(docker compose を採用)
- ChMateへの対応
- モダンで開発体験の良い技術スタック
- DDD に基づいた設計とレイヤー分割
当システムは Cloudflare Workers にデプロイすることができます。
まず依存関係をインストールします。
pnpm install必要となるデータベースを用意します。ここでは Neon を利用しますが、PostgreSQL 互換のデータベースであれば何でも構いません。 このガイドに従って、Neon のアカウントを作成し、データベースを作成してください。その際、データベースへの接続情報を取得する必要があります。
postgrest://username:password@hostname:port/database次に、dbmate を用いてデータベースのマイグレーションを行います。dbmate は、データベースのスキーマを管理するためのツールです。
pnpm dbmate up --url (取得した接続情報)Cloudflare Workers のアカウントを作成してください。こちらからアカウントを作成できます。すでに存在する場合は、ログインしてください。
デプロイを行ないます。内部で wrangler を使用しています。
pnpm run deploy:workersデプロイが完了すると、デプロイされた URL が表示されます。
最後に、データベース接続情報・JWT のシークレットを環境変数として設定します。
pnpm wrangler secret put DATABASE_URL
pnpm wrangler secret put JWT_SECRET_KEYそれぞれの内容を受け付けるプロンプトが表示されるので、入力してください。正常に設定されると、再度デプロイされます。
完了後、デプロイされた URL にアクセスできるようになります。
Docker における本番環境では、以下のコンテナが起動します。
| サービス | 概要 |
|---|---|
| Traefik | リバースプロキシ |
| PostgreSQL | データベース |
| Bun | アプリケーションサーバ (VakKarma) |
| DBMate | マイグレーションツール |
.envファイルを編集してください。
# 本番用の環境変数
TRUSTED_PROXY_ID=proxy1
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
POSTGRES_DB=myapp
JWT_SECRET_KEY=secretTRUSTED_PROXY_ID: リバースプロキシの識別子。ユーザに推測されないように設定してください。POSTGRES_USER: データベースのユーザ名POSTGRES_PASSWORD: データベースのパスワードPOSTGRES_DB: データベース名JWT_SECRET_KEY: JWT の秘密鍵。ユーザに推測されないように設定してください。
次に、Docker の有効な環境で以下のコマンドを実行してください。
docker compose -f docker-compose.prod.yml up -dアプリケーションは 80 ポートで起動します。 データベースへのマイグレーションは自動で行われます。
開発環境では、データベースのみを Docker で起動します。 アプリケーション自体は Vite で起動します。
.envファイルを編集してください。
# 開発環境用の環境変数
VITE_POSTGRES_USER=postgres
VITE_POSTGRES_PASSWORD=postgres
VITE_POSTGRES_DB=vakkarma-1
VITE_JWT_SECRET_KEY=secretVITE_POSTGRES_USER: データベースのユーザ名VITE_POSTGRES_PASSWORD: データベースのパスワードVITE_POSTGRES_DB: データベース名VITE_JWT_SECRET_KEY: JWT の秘密鍵。ユーザに推測されないように設定してください。
次に、以下のコマンドを実行してください。
docker compose -f docker-compose.dev.yml up -dアプリケーションを起動するには、以下のコマンドを実行してください。
pnpm install # 依存関係のインストール
sudo pnpm run dev # 開発サーバーの起動Vite が 80 ポートで起動します。
管理者権限が必要な場合は、sudoを付けてください。
なお、他のポートで動作させる場合や一般公開が必要ない場合は、vite.config.tsを編集してください。
VakKarma では、すべての画面がレスポンシブデザインに対応しています。
上位のスレッド 30 件の一覧と、先頭スレッド 1 件&上位スレッド 10 件のレスを表示します。 レスポンスの返信フォームやスレッドの新規作成フォームも表示されます。 UI はゼロちゃんねるプラスのものに準拠しています。
すべてのスレッドのレスを表示します。また、レスの返信フォームも表示されます。
/adminにアクセスすると、管理者画面にアクセスできます。
ログイン していない状態では、/login/adminにリダイレクトされます。ここでパスワードを入力すると、管理者画面にアクセスできます。
パスワードはデフォルトでpasswordです。
掲示板の名称やローカルルール、名無しの名前を変更できます。
また、パスワードの変更も可能です。
デフォルトのパスワードから変更することを強く推奨します。
スレッド作成・レス作成時はどちらもコンテンツの入力が必須です。
ユーザ名は任意ですが、名無しの場合は管理者画面で設定した名前が表示されます。
ユーザ名に#を含めることで、#以降の文字列がトリップとして表示されます。
https://(ホスト)/senbura/を URL に登録してください。
正常に読み込まれると、以下のように表示されます。
| パッケージ名 | バージョン | 説明 |
|---|---|---|
hono |
^4.7.0 |
軽量ウェブフレームワークで、Express や Koa に似ており、HTTP リクエストとレスポンスを処理。 |
honox |
^0.1.34 |
Hono に基づくメタフレームワークで、Hono と Vite を使用したアプリケーション開発を簡素化。 |
postgres |
^3.4.5 |
Node.js で PostgreSQL データベースとインタラクション。クエリやデータ操作に使用。 |
neverthrow |
^8.1.1 |
Result 型を提供し、エラーを機能的に安全に処理。コードの信頼性と可読性を向上。 |
uuidv7 |
^1.0.2 |
時間ベースのバージョン 7 UUID を生成。アプリケーション内で一意の識別子を生成。 |
bcrypt-ts |
^6.0.0 |
BCrypt アルゴリズムを使用したパスワードハッシュ化を TypeScript でサポート。パスワードの安全なハッシュ化と検証に使用。 |
iconv-lite |
^0.6.3 |
幅広い文字エンコーディングの変換をサポート。テキストデータのエンコーディング変換に使用。 |
encoding-japanese |
^2.2.0 |
日本語文字エンコーディングの変換(例:Shift-JIS と UTF-8)を処理。テキストデータの多言語対応に役立つ。 |
tailwindcss |
^4.0.5 |
ユーティリティファーストの CSS フレームワーク。迅速かつ一貫したスタイリングに使用。 |
vite |
^6.1.0 |
モダンウェブアプリケーションのビルドツール。ホットモジュールリプレイスメントと最適化を提供。 |
@tailwindcss/vite |
^4.0.5 |
Vite との Tailwind CSS 統合。迅速なスタイリングのためのユーティリティクラスを使用可能。 |
@ts-safeql/eslint-plugin |
^3.6.6 |
PostgreSQL の生 SQL クエリから TypeScript 型を検証・自動生成する ESLint プラグイン。SQL クエリの型安全性を確保。 |
- コンテンツの最大長制限への対応 (medium)
createResponseContentの非同期関数化
高階関数パターンの導入
- パスワード更新機能の実装 (medium)
- レスの範囲を指定するページの追加
- Config/Env をセットアップするシェルスクリプトの実装
- 信頼できる IP アドレスを外部から設定できるようにする
- https に対応するスクリプトの追加
- NG ワード機能の実装
- レス検索機能の実装
- Cloudflare Captcha(turnstile)への対応
- ログの出力
- 適切な粒度がわからないので見直しが必要
- エラーハンドリングの見直し
- エラーと例外の分離
- テストの記述
- ドメイン層のテスト
- ユースケース層のテスト
- リポジトリ層のテスト
- 複数板を扱う機能の実装(very hard)
- ログイン機能の実装(very hard)
MIT








