Convex 初期設定完全手順:CLI・環境変数・Secrets・権限までゼロから構築

モダンな Web アプリケーション開発において、バックエンドの構築と管理は開発者にとって大きな負担となることがあります。Convex は、この課題を解決する BaaS(Backend as a Service)として注目を集めており、リアルタイム同期と型安全性を兼ね備えた革新的なプラットフォームです。
本記事では、Convex の初期設定から CLI 環境構築、環境変数と Secrets の管理、そして権限設定まで、開発者が実際にプロダクション環境で運用するために必要な全手順を体系的に解説いたします。
背景
Convex とは何か:BaaS(Backend as a Service)の基本概念
Convex は、フルスタック開発を効率化する BaaS(Backend as a Service)プラットフォームです。従来のバックエンド開発で必要だったサーバー管理、データベース設計、API 構築といった複雑な作業を抽象化し、開発者がフロントエンド開発に集中できる環境を提供します。
以下の図は、Convex のアーキテクチャ全体を示しています:
mermaidflowchart TB
client["フロントエンド<br/>React/Next.js"] -->|リアルタイム通信| convex["Convex Platform"]
convex --> db[("データベース<br/>自動管理")]
convex --> functions["サーバーレス関数<br/>TypeScript"]
convex --> auth["認証システム<br/>内蔵"]
convex --> search["全文検索<br/>エンジン"]
dev["開発者"] -->|CLI操作| convex
dev -->|型安全なクエリ| client
図で理解できる要点:
- Convex は一元的なプラットフォームとして機能し、データベース、認証、検索などを統合管理します
- フロントエンドとバックエンドの間でリアルタイム通信が可能です
- 開発者は CLI を通じて全ての設定を管理できます
従来のバックエンド構築の課題と Convex の解決策
従来のバックエンド開発では、複数のサービスやツールを個別に設定し、それらを連携させる必要がありました。この複雑さが Convex によってどのように解決されるかを見てみましょう。
従来の課題 | Convex の解決策 |
---|---|
★ データベース設計とスキーマ管理 | 自動的なスキーマ推論と型生成 |
★ サーバーのスケーリングと運用 | フルマネージドなサーバーレス環境 |
★ リアルタイム機能の実装 | 内蔵されたリアルタイム同期機能 |
★ 認証システムの構築 | 統合された認証プロバイダー |
★ 環境間でのデータ整合性 | 一元的な環境管理システム |
Convex では、これらの課題が統合されたプラットフォーム内で自動的に解決されます。開発者は複雑なインフラ管理から解放され、ビジネスロジックの実装に専念できるのです。
リアルタイム同期と型安全性の重要性
現代の Web アプリケーションでは、リアルタイム性と型安全性が不可欠な要素となっています。Convex は、これら両方を同時に実現する独自のアプローチを採用しています。
リアルタイム同期の仕組み:
- WebSocket ベースの自動的なデータ同期
- クライアント間でのリアルタイムな状態共有
- オフライン時の自動的なデータキャッシュと同期
型安全性の実現:
- TypeScript ベースの完全な型推論
- コンパイル時のエラー検出
- IDE での強力なオートコンプリート機能
これらの特徴により、開発者は堅牢で保守性の高いアプリケーションを効率的に構築できます。
課題
CLI 環境の初期設定の複雑さ
Convex CLI の初期設定は、初めて利用する開発者にとって複数の課題を抱えています。Node.js 環境の確認から始まり、CLI 自体のインストール、そして認証設定まで、一連の手順で躓きやすいポイントが存在します。
特に以下のような問題が頻繁に発生します:
- Node.js のバージョン互換性の問題
- 権限不足によるインストールエラー
- 認証トークンの設定ミス
- プロジェクト初期化時の設定項目の理解不足
環境変数と Secrets の管理の難しさ
Convex では、開発環境、ステージング環境、本番環境それぞれで異なる設定値を管理する必要があります。この環境別の設定管理において、以下のような課題が発生することがあります:
mermaidflowchart LR
dev["開発環境"] -->|異なる設定値| staging["ステージング環境"]
staging -->|異なる設定値| prod["本番環境"]
subgraph issues ["よくある問題"]
leak["設定値の漏洩"]
sync["環境間の設定不整合"]
manage["設定値の煩雑な管理"]
end
dev -.->|課題| issues
staging -.->|課題| issues
prod -.->|課題| issues
図で理解できる要点:
- 各環境で設定値が異なるため、管理が複雑になります
- 設定の漏洩や不整合が発生しやすい構造です
- 環境数が増えるほど管理の複雑さが指数的に増加します
権限設定とセキュリティの考慮事項
Convex アプリケーションでは、適切な権限設定がセキュリティの要となります。しかし、権限システムの理解と実装には以下のような課題があります:
- ユーザーロールの適切な定義方法
- API 権限の細分化と設定
- データアクセスルールの記述
- セキュリティホールの回避方法
権限設定を誤ると、意図しないデータアクセスやセキュリティ脆弱性を生み出す可能性があるため、慎重な設計が必要です。
開発環境と本番環境の切り分け
開発プロセスにおいて、開発環境と本番環境の適切な分離は品質保証とリスク管理の観点から極めて重要です。Convex では以下の切り分け課題に直面することがあります:
- 環境間でのデータベーススキーマの同期
- 本番データの誤った操作防止
- デプロイプロセスの自動化と品質管理
- 環境固有の設定値の管理
これらの課題を解決するためには、体系的なアプローチと適切なツールの活用が不可欠です。
解決策
Convex CLI の段階的セットアップ手順
CLI 環境構築の課題を解決するため、Convex では段階的なセットアップアプローチを採用します。各ステップを明確に分離し、エラーが発生した場合の対処法も含めて体系的に進めることで、確実な環境構築が可能です。
セットアップの基本方針:
- 前提条件の事前確認
- 段階的なインストールと検証
- エラー時の詳細なトラブルシューティング
- 設定の永続化と共有方法
環境変数管理のベストプラクティス
環境変数の管理課題に対しては、以下のベストプラクティスを適用します:
項目 | 開発環境 | 本番環境 |
---|---|---|
★ 設定ファイル | .env.local | 環境変数として設定 |
★ バージョン管理 | Git 除外対象 | 暗号化して管理 |
★ アクセス権限 | 開発者全員 | 限定されたメンバーのみ |
★ ローテーション | 手動・不定期 | 自動・定期的 |
これらの方針により、セキュリティを保ちながら効率的な開発が可能になります。
Secrets の安全な設定方法
Secrets の管理では、暗号化、アクセス制御、監査ログの 3 つの柱を基軸とした包括的なアプローチを採用します:
mermaidflowchart TD
secrets["Secrets管理"] --> encrypt["暗号化"]
secrets --> access["アクセス制御"]
secrets --> audit["監査ログ"]
encrypt --> storage["安全な保存"]
encrypt --> transit["転送時の保護"]
access --> rbac["ロールベース制御"]
access --> mfa["多要素認証"]
audit --> logging["操作履歴"]
audit --> alert["異常検知"]
図で理解できる要点:
- Secrets の保護は 3 つの主要な要素で構成されます
- 各要素が相互に連携してセキュリティを強化します
- 包括的なアプローチにより漏洩リスクを最小化します
権限管理の体系的なアプローチ
権限設定の課題解決には、最小権限の原則に基づいた階層的な権限モデルを採用します。これにより、セキュリティを保ちながら開発効率を最大化できます。
権限設計の基本原則:
- デフォルトでアクセス拒否
- 明示的な権限付与のみ許可
- 定期的な権限レビューと更新
- 権限の継承とグループ管理
具体例
CLI 環境構築
Node.js 環境の確認
Convex CLI を利用するためには、Node.js 18.0.0 以上が必要です。まず現在の環境を確認しましょう。
bash# Node.jsのバージョン確認
node --version
# npmのバージョン確認
npm --version
バージョンが要件を満たさない場合は、Node.js の公式サイトまたは nvm(Node Version Manager)を使用してアップデートを行ってください。
bash# nvmを使用したNode.js最新LTS版のインストール
nvm install --lts
nvm use --lts
Convex CLI のインストール
Node.js 環境が準備できたら、Convex CLI をグローバルにインストールします。
bash# Convex CLIのグローバルインストール
npm install -g convex
# インストール確認
convex --version
インストールが完了したら、CLI が正常に動作することを確認してください。エラーが発生する場合は、権限の問題や既存の古いバージョンとの競合が考えられます。
一般的なインストールエラーと解決方法:
エラーメッセージ | 原因 | 解決方法 |
---|---|---|
★ EACCES: permission denied | 権限不足 | sudo を使用するか、npm の権限設定を変更 |
★ command not found: convex | PATH の問題 | .bashrc や.zshrc で PATH を設定 |
★ version conflict | 古いバージョンとの競合 | 既存バージョンをアンインストール後再インストール |
プロジェクト初期化とログイン
CLI のインストールが完了したら、新しいプロジェクトを初期化します。
bash# 新しいプロジェクトディレクトリの作成
mkdir my-convex-app
cd my-convex-app
# プロジェクトの初期化
npm init -y
次に、Convex プロジェクトとして初期化し、認証を行います。
bash# Convexプロジェクトの初期化
convex dev --once
# Convexアカウントへのログイン(ブラウザが開きます)
convex auth
ログイン処理では、ブラウザが自動的に開き、Convex ダッシュボードでの認証を行います。認証が完了すると、ローカル環境に認証トークンが保存され、CLI から Convex サービスにアクセスできるようになります。
環境変数設定
開発環境の設定
開発環境では、ローカルでの開発に必要な設定値を管理します。まず、環境変数用のファイルを作成しましょう。
bash# 開発環境用の環境変数ファイルを作成
touch .env.local
.env.local
ファイルに開発環境固有の設定を記述します:
env# 開発環境設定
CONVEX_DEPLOYMENT=dev:your-project-name
NEXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud
DATABASE_URL=your-dev-database-url
STRIPE_PUBLIC_KEY=pk_test_your_dev_stripe_key
このファイルは機密情報を含むため、.gitignore
に追加してバージョン管理から除外する必要があります。
gitignore# 環境変数ファイルをGitから除外
.env.local
.env.*.local
*.env
本番環境の設定
本番環境では、Convex ダッシュボードまたは CLI を通じて環境変数を設定します。セキュリティを考慮し、本番環境の設定値はローカルファイルには保存しません。
bash# 本番環境に環境変数を設定
convex env set DATABASE_URL your-prod-database-url --prod
convex env set STRIPE_PUBLIC_KEY pk_live_your_prod_stripe_key --prod
設定した環境変数は、以下のコマンドで確認できます:
bash# 環境変数の一覧表示
convex env list
# 特定の環境の環境変数を表示
convex env list --prod
環境別の変数管理
複数の環境を管理する場合、環境ごとに異なる設定値を体系的に管理することが重要です。
bash# 開発環境の設定
convex env set API_BASE_URL https://dev-api.example.com --dev
# ステージング環境の設定
convex env set API_BASE_URL https://staging-api.example.com --staging
# 本番環境の設定
convex env set API_BASE_URL https://api.example.com --prod
環境変数の命名規則を統一することで、管理の一貫性を保てます:
環境変数名 | 用途 | 例 |
---|---|---|
★ API_* | 外部 API 関連 | API_BASE_URL , API_KEY |
★ DB_* | データベース関連 | DB_URL , DB_NAME |
★ AUTH_* | 認証関連 | AUTH_SECRET , AUTH_PROVIDER |
★ FEATURE_* | 機能フラグ | FEATURE_ANALYTICS , FEATURE_BETA |
Secrets 管理
API キーの設定
Secrets は、API キーやパスワードなど、特に機密性の高い情報を安全に管理するための Convex の機能です。環境変数とは異なり、暗号化されて保存され、より厳格なアクセス制御が適用されます。
bash# 外部サービスのAPIキーをSecretsとして設定
convex secrets set OPENAI_API_KEY sk-your-openai-api-key
convex secrets set STRIPE_SECRET_KEY sk_live_your-stripe-secret-key
convex secrets set SENDGRID_API_KEY SG.your-sendgrid-api-key
Secrets の設定後、Convex 関数内でこれらの値を安全に使用できます:
typescript// convex/openai.ts
import { v } from 'convex/values';
import { action } from './_generated/server';
export const generateText = action({
args: { prompt: v.string() },
handler: async (ctx, args) => {
// SecretsからAPIキーを安全に取得
const apiKey = process.env.OPENAI_API_KEY;
const response = await fetch(
'https://api.openai.com/v1/completions',
{
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
prompt: args.prompt,
max_tokens: 100,
}),
}
);
return await response.json();
},
});
データベース接続情報
データベースの接続情報は、特に慎重に管理する必要があります。Convex では内蔵データベースを使用しますが、外部データベースとの連携が必要な場合もあります。
bash# 外部データベースの接続情報をSecretsとして設定
convex secrets set POSTGRES_URL postgresql://user:password@host:5432/database
convex secrets set REDIS_URL redis://user:password@host:6379
外部データベースへの接続を行う Convex 関数の例:
typescript// convex/database.ts
import { action } from './_generated/server';
import { Client } from 'pg';
export const queryExternalDB = action({
args: {},
handler: async (ctx) => {
const client = new Client({
connectionString: process.env.POSTGRES_URL,
});
try {
await client.connect();
const result = await client.query(
'SELECT * FROM users LIMIT 10'
);
return result.rows;
} catch (error) {
console.error('Database query failed:', error);
throw new Error('External database query failed');
} finally {
await client.end();
}
},
});
外部サービス認証情報
Oauth 認証や Webhook 検証に必要な認証情報も、Secrets として安全に管理します。
bash# OAuth認証情報の設定
convex secrets set GOOGLE_CLIENT_SECRET your-google-client-secret
convex secrets set GITHUB_CLIENT_SECRET your-github-client-secret
# Webhook検証用のシークレット
convex secrets set STRIPE_WEBHOOK_SECRET whsec_your-stripe-webhook-secret
設定した Secrets の一覧は以下のコマンドで確認できます:
bash# Secretsの一覧表示(値は表示されません)
convex secrets list
# 特定のSecretの存在確認
convex secrets list | grep OPENAI_API_KEY
権限設定
ユーザー権限の定義
Convex では、認証されたユーザーに対して細かな権限制御を実装できます。まず、基本的な権限モデルを定義しましょう。
typescript// convex/schema.ts
import { defineSchema, defineTable } from 'convex/server';
import { v } from 'convex/values';
export default defineSchema({
users: defineTable({
email: v.string(),
name: v.string(),
role: v.union(
v.literal('admin'),
v.literal('user'),
v.literal('moderator')
),
permissions: v.array(v.string()),
createdAt: v.number(),
lastLogin: v.optional(v.number()),
}).index('by_email', ['email']),
posts: defineTable({
title: v.string(),
content: v.string(),
authorId: v.id('users'),
published: v.boolean(),
createdAt: v.number(),
}).index('by_author', ['authorId']),
});
ユーザーの権限を確認するためのヘルパー関数を作成します:
typescript// convex/auth.ts
import { query } from './_generated/server';
import { v } from 'convex/values';
export const getCurrentUser = query({
args: {},
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) return null;
const user = await ctx.db
.query('users')
.withIndex('by_email', (q) =>
q.eq('email', identity.email)
)
.first();
return user;
},
});
export const hasPermission = query({
args: { permission: v.string() },
handler: async (ctx, args) => {
const user = await getCurrentUser(ctx, {});
if (!user) return false;
return (
user.permissions.includes(args.permission) ||
user.role === 'admin'
);
},
});
API 権限の設定
各 API 関数に対して、適切な権限チェックを実装します。
typescript// convex/posts.ts
import { mutation, query } from './_generated/server';
import { v } from 'convex/values';
export const createPost = mutation({
args: {
title: v.string(),
content: v.string(),
published: v.boolean(),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) {
throw new Error('認証が必要です');
}
const user = await ctx.db
.query('users')
.withIndex('by_email', (q) =>
q.eq('email', identity.email)
)
.first();
if (!user) {
throw new Error('ユーザーが見つかりません');
}
// 投稿権限のチェック
if (
!user.permissions.includes('create_post') &&
user.role !== 'admin'
) {
throw new Error('投稿権限がありません');
}
return await ctx.db.insert('posts', {
...args,
authorId: user._id,
createdAt: Date.now(),
});
},
});
セキュリティルールの実装
データの閲覧・編集に関するセキュリティルールを実装します。
typescript// convex/posts.ts (続き)
export const updatePost = mutation({
args: {
postId: v.id('posts'),
title: v.optional(v.string()),
content: v.optional(v.string()),
published: v.optional(v.boolean()),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) {
throw new Error('認証が必要です');
}
const user = await ctx.db
.query('users')
.withIndex('by_email', (q) =>
q.eq('email', identity.email)
)
.first();
if (!user) {
throw new Error('ユーザーが見つかりません');
}
const post = await ctx.db.get(args.postId);
if (!post) {
throw new Error('投稿が見つかりません');
}
// 所有者または管理者のみが編集可能
if (
post.authorId !== user._id &&
user.role !== 'admin'
) {
throw new Error('この投稿を編集する権限がありません');
}
const { postId, ...updateData } = args;
return await ctx.db.patch(postId, updateData);
},
});
ロールベースの権限チェック機能を共通化することで、保守性を向上させます:
typescript// convex/permissions.ts
import { DatabaseReader } from './_generated/server';
export async function requireRole(
ctx: { db: DatabaseReader; auth: any },
requiredRole: 'admin' | 'moderator' | 'user'
) {
const identity = await ctx.auth.getUserIdentity();
if (!identity) {
throw new Error('認証が必要です');
}
const user = await ctx.db
.query('users')
.withIndex('by_email', (q) =>
q.eq('email', identity.email)
)
.first();
if (!user) {
throw new Error('ユーザーが見つかりません');
}
const roleHierarchy = { admin: 3, moderator: 2, user: 1 };
if (
roleHierarchy[user.role] < roleHierarchy[requiredRole]
) {
throw new Error(`${requiredRole}権限が必要です`);
}
return user;
}
この共通関数を使用することで、権限チェックを簡潔に記述できます:
typescript// convex/admin.ts
import { mutation } from './_generated/server';
import { v } from 'convex/values';
import { requireRole } from './permissions';
export const deleteUser = mutation({
args: { userId: v.id('users') },
handler: async (ctx, args) => {
// 管理者権限が必要
await requireRole(ctx, 'admin');
return await ctx.db.delete(args.userId);
},
});
まとめ
Convex の初期設定から権限管理まで、本記事では開発者が実際のプロダクション環境で必要となる全ての手順を体系的に解説いたしました。
重要なポイントの振り返り:
-
CLI 環境構築では、Node.js 環境の確認から始まり、段階的なインストールと認証設定を行うことで、確実な開発環境を構築できます
-
環境変数管理では、開発環境と本番環境を適切に分離し、セキュリティを保ちながら効率的な設定管理を実現します
-
Secrets 管理では、API キーやデータベース接続情報などの機密情報を暗号化して安全に保存し、アクセス制御を徹底します
-
権限設定では、ロールベースアクセス制御を実装し、最小権限の原則に基づいたセキュアなアプリケーションを構築します
これらの設定を適切に行うことで、Convex を活用したモダンな Web アプリケーションの開発基盤が整います。特に、セキュリティと保守性を両立させた設計により、長期的な運用においても安心してサービスを提供できるでしょう。
Convex のパワフルな機能を最大限に活用し、効率的で安全なアプリケーション開発を始めましょう。
関連リンク
- article
Convex 初期設定完全手順:CLI・環境変数・Secrets・権限までゼロから構築
- article
【比較検証】Convex vs Firebase vs Supabase:リアルタイム性・整合性・学習コストの最適解
- article
【2025 年最新】Convex の全体像を 10 分で理解:リアルタイム DB× 関数基盤の要点まとめ
- article
Convex × React/Next.js 最速連携:useQuery/useMutation の実践パターン
- article
Convex の基本アーキテクチャ徹底解説:データベース・関数・リアルタイム更新
- article
Convex 入門:5 分でリアルタイム DB と関数 API を立ち上げる完全ガイド
- article
【保存版】Vite 設定オプション早見表:`resolve` / `optimizeDeps` / `build` / `server`
- article
JavaScript Web Workers 実践入門:重い処理を別スレッドへ逃がす最短手順
- article
htmx × Express/Node.js 高速セットアップ:テンプレ・部分テンプレ構成の定石
- article
TypeScript 型縮小(narrowing)パターン早見表:`in`/`instanceof`/`is`/`asserts`完全対応
- article
Homebrew を社内プロキシで使う設定完全ガイド:HTTP(S)_PROXY・証明書・ミラー最適化
- article
Tauri 開発環境の最速構築:Node・Rust・WebView ランタイムの完全セットアップ
- blog
iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
- blog
Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
- blog
【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
- blog
Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
- blog
Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
- blog
フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来