複数DBをブラウザから管理するための、管理ツールです。
apps/frontend: React + TypeScript + Vite + Tailwind のフロントエンドapps/backend: Fastify + TypeScript のバックエンドpackages/shared: 共通定数・型docker-compose.yml: 本番用 Docker Composedocker-compose.dev.yml: 開発用 MySQL / PostgreSQL
- DNS で
admin.example.comのような公開ドメインをこのサーバーへ向ける - このリポジトリをサーバーへ配置する
- Node.js 20 系と
pnpm@10.11.0をインストールする pnpm docker:initを実行して.envを作る.envのMODERN_DB_ADMIN_DOMAINとMODERN_DB_ADMIN_ACME_EMAILを本番値へ直すpnpm docker:upを実行するhttps://<あなたのドメイン>を開いて初期管理者を作成する
これで以下がまとめて起動します。
- backend: Node.js + SQLite
- web: Caddy による静的配信 +
/apiリバースプロキシ - HTTPS: Caddy が自動で証明書を取得して終端
補足:
- 80/443 番ポートが開いている必要があります
MODERN_DB_ADMIN_DOMAINは必ず実在する公開ドメインにしてください- 保存データは Docker volume
modern_db_admin_dataに永続化されます
- 本番初期化:
pnpm docker:init - 本番起動:
pnpm docker:up - 本番停止:
pnpm docker:down - 本番ログ:
pnpm docker:logs - 開発DB起動:
pnpm docker:dev:up - 開発DB停止:
pnpm docker:dev:down
- Node.js 20 系を使用する
pnpmは10.11.0を使用する- フロントエンドは静的配信、バックエンドは Node.js プロセスとして常駐させる
- ブラウザからは必ず HTTPS でアクセスする
docker-compose.dev.ymlは開発用サンプルDB用
- フロントエンド:
apps/frontend/distを Nginx などで静的配信 - バックエンド:
node apps/backend/dist/server.jsをsystemdなどで常駐化 - 内部データ:
SQLITE_DB_PATHに指定した SQLite ファイルを永続ボリュームに配置 - 接続先DB: 管理対象の MySQL / PostgreSQL 本体は外部サーバーまたはマネージドDBを使用
Modern DB Admin 自身のユーザー、ロール、監査ログ、保存済み接続情報は SQLite に保存されます。
MySQL / PostgreSQL は「このアプリが管理する対象」であり、このアプリの内部ストレージではありません。
Docker 構成ファイル:
docker-compose.yml: 本番用 composedocker-compose.dev.yml: 開発用 sample DB composedocker/backend.Dockerfile: backend 用イメージdocker/web.Dockerfile: frontend + Caddy 用イメージdocker/Caddyfile: HTTPS / 静的配信 //apiプロキシ設定.env.example: 本番環境変数の見本
npm install -g pnpm@10.11.0
pnpm install --frozen-lockfile
pnpm buildビルド後の配置先:
- フロントエンド成果物:
apps/frontend/dist - バックエンド成果物:
apps/backend/dist/server.js
本番では少なくとも次を設定します。
NODE_ENV=production
PORT=3001
JWT_SECRET=32文字以上の十分に長いランダム文字列
ENCRYPTION_KEY=32文字以上の十分に長いランダム文字列
SQLITE_DB_PATH=/opt/modern-db-admin/data/app.sqlite
CORS_ORIGIN=https://admin.example.comDocker 構成では .env に以下を置けば十分です。
MODERN_DB_ADMIN_DOMAIN=admin.example.com
MODERN_DB_ADMIN_ACME_EMAIL=admin@example.com
JWT_SECRET=32文字以上の十分に長いランダム文字列
ENCRYPTION_KEY=32文字以上の十分に長いランダム文字列注意:
JWT_SECRET、ENCRYPTION_KEY、CORS_ORIGINは本番で未設定のままだとバックエンドが起動しませんENCRYPTION_KEYを変更すると、保存済み接続パスワードを復号できなくなりますSQLITE_DB_PATHは本番では相対パスではなく絶対パスを推奨しますCORS_ORIGINはフロントエンド公開URLと完全一致させます
sudo mkdir -p /opt/modern-db-admin/data
sudo chown -R <backend-user>:<backend-user> /opt/modern-db-adminSQLite は app.sqlite に加えて -wal、-shm ファイルも作るため、ディレクトリ単位で永続化してください。
systemd 例:
[Unit]
Description=Modern DB Admin Backend
After=network.target
[Service]
Type=simple
User=<backend-user>
WorkingDirectory=/opt/modern-db-admin/app
Environment=NODE_ENV=production
Environment=PORT=3001
Environment=JWT_SECRET=<strong-random-secret>
Environment=ENCRYPTION_KEY=<strong-random-encryption-key>
Environment=SQLITE_DB_PATH=/opt/modern-db-admin/data/app.sqlite
Environment=CORS_ORIGIN=https://admin.example.com
ExecStart=/usr/bin/node /opt/modern-db-admin/app/apps/backend/dist/server.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target反映:
sudo systemctl daemon-reload
sudo systemctl enable --now modern-db-admin.service
sudo systemctl status modern-db-admin.serviceDocker を使うなら、この手順は不要です。pnpm docker:up が backend の常駐化までまとめて行います。
同一オリジンで /api をリバースプロキシする構成を推奨します。
この場合、VITE_API_BASE_URL は未設定でも動作します。
例:
sudo mkdir -p /var/www/modern-db-admin
sudo cp -R apps/frontend/dist/* /var/www/modern-db-admin/フロントエンドとAPIを別オリジンにする場合のみ、フロントエンドビルド時に VITE_API_BASE_URL を公開APIのURLへ設定してください。
例:
VITE_API_BASE_URL=https://api.example.com pnpm --filter @modern-db-admin/frontend buildDocker を使う場合、この手順は不要です。frontend のビルドと配信は docker/web.Dockerfile と Caddy が担当します。
Nginx 例:
server {
listen 80;
server_name admin.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name admin.example.com;
ssl_certificate /etc/letsencrypt/live/admin.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/admin.example.com/privkey.pem;
root /var/www/modern-db-admin;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}BrowserRouter を使っているため、/app/... への直接アクセスでも index.html にフォールバックする設定が必要です。
Docker を使う場合、この役割は docker/Caddyfile が担当します。
- バックエンドのヘルスチェックを確認する:
curl http://127.0.0.1:3001/api/health - ブラウザで
https://admin.example.comを開く - 初回セットアップ画面で管理者アカウントを作成する
- ログイン後に管理対象の MySQL / PostgreSQL 接続を登録する
- 接続一覧から
Testを実行して疎通確認する
- バックアップ対象は SQLite ディレクトリと
ENCRYPTION_KEY、JWT_SECRETです ENCRYPTION_KEYを失うと保存済み接続情報の復旧ができません- 更新時は
pnpm install --frozen-lockfile && pnpm buildを再実行し、フロントエンド配信物を差し替えた後にバックエンドを再起動します - HTTPS を使わないと本番では
Secureクッキーが機能せずログインできません - Docker 構成を更新する場合は
pnpm docker:upを再実行すれば再ビルド込みで反映できます
前提:
- Node.js 20 系
pnpm@10.11.0
Ubuntu などで pnpm が未導入なら、例えば以下で入れてください。
npm install -g pnpm@10.11.0手順:
pnpm installpnpm docker:dev:uppnpm dev
起動後:
- フロントエンド:
http://localhost:5173 - バックエンド:
http://localhost:3001 - 初回アクセス時はセットアップ画面で管理者アカウントを作成
DBユーザー・権限: MySQL / PostgreSQL 側に存在する実ユーザー・role と、そのGRANT/REVOKEを管理します。接続一覧、左の接続ツリー、またはテーブル画面から対象接続ごとに開きます。管理画面ユーザー: Modern DB Admin 自体にログインする内部ユーザーと内部ロールを管理します。
この 2 つは別物です。DB の権限を変えたい場合は、必ず対象接続の DBユーザー・権限 画面を使ってください。
pnpm docker:dev:up を実行すると、開発用の MySQL / PostgreSQL がローカルに立ち上がります。
Modern DB Admin から接続する手順は次の通りです。
http://localhost:5173を開く- 初回なら管理者アカウントを作成してログインする
- サイドバーまたは画面遷移から接続一覧を開く
新規接続を押す- 接続情報を入力して
接続を作成を押す - 保存後に
Testまたはこの接続をテストを押して疎通確認する
- 接続名:
Local PostgreSQL - DB種別:
PostgreSQL - ホスト:
127.0.0.1 - ポート:
5432 - 接続ユーザー:
postgres - パスワード:
rootpassword - 初期 database:
sample_db - SSL を使用:
OFF - 読み取り専用にする: 用途に応じて設定
- 接続名:
Local MySQL - DB種別:
MySQL - ホスト:
127.0.0.1 - ポート:
3307 - 接続ユーザー:
root - パスワード:
rootpassword - 初期 database:
sample_db - SSL を使用:
OFF - 読み取り専用にする: 用途に応じて設定
初期 databaseは任意です。空でも保存できます。- 接続先ホストはブラウザではなくバックエンドから見える値です。ローカル起動なら
127.0.0.1で問題ありません。 - ローカルに別の MySQL / MariaDB が常駐している場合の衝突を避けるため、開発用 MySQL は
3307に公開しています。 - 開発用DBの初期データは
docker/mysql/init.sqlとdocker/postgres/init.sqlで投入されます。
pnpm devpnpm reset:setuppnpm buildpnpm lintpnpm testpnpm format
バックエンド:
NODE_ENV=developmentPORT=3001JWT_SECRET=change-meENCRYPTION_KEY=0123456789abcdef0123456789abcdefSQLITE_DB_PATH=./data/app.sqliteCORS_ORIGIN=http://localhost:5173
フロントエンド:
VITE_API_BASE_URL=http://localhost:3001