obsidian-multi-env-setup
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseObsidian Multi-Environment Setup
Obsidian多环境配置
Overview
概述
Configure separate development, testing, and production vaults for Obsidian plugin work. Covers vault templates for team onboarding, environment-specific plugin settings, sync strategies, and directory management across environments.
.obsidian/为Obsidian插件开发配置独立的开发、测试和生产vault。涵盖团队入职的vault模板、各环境专属插件设置、同步策略,以及跨环境的目录管理。
.obsidian/Prerequisites
前置要求
- Obsidian desktop app installed
- Node.js 18+ and npm/pnpm for plugin builds
- Git for version control (recommended)
- Basic understanding of symlinks and file system operations
- 已安装Obsidian桌面应用
- Node.js 18+以及npm/pnpm用于插件构建
- Git用于版本控制(推荐)
- 了解符号链接(symlink)和文件系统操作的基础知识
Instructions
使用说明
Step 1: Create the Environment Structure
步骤1:创建环境结构
Set up three isolated vaults -- dev, test, and prod:
bash
undefined搭建三个隔离的vault:开发(dev)、测试(test)、生产(prod):
bash
undefinedBase directory for all environments
Base directory for all environments
mkdir -p ~/obsidian-envs/{dev,test,prod}
mkdir -p ~/obsidian-envs/{dev,test,prod}
Dev vault: your working vault with symlinked plugin source
Dev vault: your working vault with symlinked plugin source
mkdir -p ~/obsidian-envs/dev/.obsidian/plugins/your-plugin
mkdir -p ~/obsidian-envs/dev/sandbox # scratch notes for testing
mkdir -p ~/obsidian-envs/dev/.obsidian/plugins/your-plugin
mkdir -p ~/obsidian-envs/dev/sandbox # scratch notes for testing
Test vault: clean environment for QA
Test vault: clean environment for QA
mkdir -p ~/obsidian-envs/test/.obsidian/plugins/your-plugin
mkdir -p ~/obsidian-envs/test/test-data
mkdir -p ~/obsidian-envs/test/.obsidian/plugins/your-plugin
mkdir -p ~/obsidian-envs/test/test-data
Prod vault: mirrors real user setup
Prod vault: mirrors real user setup
mkdir -p ~/obsidian-envs/prod/.obsidian/plugins/your-plugin
undefinedmkdir -p ~/obsidian-envs/prod/.obsidian/plugins/your-plugin
undefinedStep 2: Symlink Plugin Source for Development
步骤2:为开发环境创建插件源码符号链接
In the dev vault, symlink your plugin's build output so changes appear immediately:
bash
undefined在开发vault中,为插件的构建产物创建符号链接,修改可以立即生效:
bash
undefinedRemove the empty plugin directory in dev
Remove the empty plugin directory in dev
rm -rf ~/obsidian-envs/dev/.obsidian/plugins/your-plugin
rm -rf ~/obsidian-envs/dev/.obsidian/plugins/your-plugin
Symlink to your plugin's repo (contains manifest.json, main.js, styles.css)
Symlink to your plugin's repo (contains manifest.json, main.js, styles.css)
ln -s /path/to/your-plugin ~/obsidian-envs/dev/.obsidian/plugins/your-plugin
For hot reload during development, use the [Hot Reload plugin](https://github.com/pjeby/hot-reload):
```bashln -s /path/to/your-plugin ~/obsidian-envs/dev/.obsidian/plugins/your-plugin
开发过程中如需热重载,可以使用[Hot Reload plugin](https://github.com/pjeby/hot-reload):
```bashClone hot-reload into dev vault's plugins
Clone hot-reload into dev vault's plugins
git clone https://github.com/pjeby/hot-reload.git
~/obsidian-envs/dev/.obsidian/plugins/hot-reload
~/obsidian-envs/dev/.obsidian/plugins/hot-reload
Then enable both your plugin and hot-reload in `.obsidian/community-plugins.json`:
```json
["your-plugin", "hot-reload"]git clone https://github.com/pjeby/hot-reload.git
~/obsidian-envs/dev/.obsidian/plugins/hot-reload
~/obsidian-envs/dev/.obsidian/plugins/hot-reload
之后在`.obsidian/community-plugins.json`中启用你的插件和热重载插件:
```json
["your-plugin", "hot-reload"]Step 3: Environment-Specific Plugin Settings
步骤3:各环境专属插件配置
Each vault gets its own for your plugin. Create a config factory:
data.jsontypescript
// config/environments.ts
interface PluginConfig {
debugMode: boolean;
logLevel: 'debug' | 'info' | 'warn' | 'error';
apiEndpoint: string;
featureFlags: Record<string, boolean>;
}
const ENV_CONFIGS: Record<string, Partial<PluginConfig>> = {
dev: {
debugMode: true,
logLevel: 'debug',
apiEndpoint: 'http://localhost:3000',
featureFlags: { experimentalEditor: true, betaSync: true },
},
test: {
debugMode: true,
logLevel: 'info',
apiEndpoint: 'https://staging.api.example.com',
featureFlags: { experimentalEditor: true, betaSync: false },
},
prod: {
debugMode: false,
logLevel: 'error',
apiEndpoint: 'https://api.example.com',
featureFlags: {},
},
};
export function detectEnvironment(vaultPath: string): string {
if (vaultPath.includes('obsidian-envs/dev')) return 'dev';
if (vaultPath.includes('obsidian-envs/test')) return 'test';
return 'prod';
}
export function getConfig(env: string): PluginConfig {
const defaults: PluginConfig = {
debugMode: false,
logLevel: 'error',
apiEndpoint: '',
featureFlags: {},
};
return { ...defaults, ...ENV_CONFIGS[env] };
}Use it in your plugin's :
onload()typescript
async onload() {
const vaultPath = (this.app.vault.adapter as any).basePath;
const env = detectEnvironment(vaultPath);
const config = getConfig(env);
console.log(`[your-plugin] Running in ${env} mode`);
if (config.debugMode) {
// Register debug commands only in dev/test
this.addCommand({
id: 'dump-state',
name: 'Dump Plugin State (debug)',
callback: () => console.log(JSON.stringify(this.settings, null, 2)),
});
}
}每个vault都有独立的插件配置文件,你可以创建一个配置工厂:
data.jsontypescript
// config/environments.ts
interface PluginConfig {
debugMode: boolean;
logLevel: 'debug' | 'info' | 'warn' | 'error';
apiEndpoint: string;
featureFlags: Record<string, boolean>;
}
const ENV_CONFIGS: Record<string, Partial<PluginConfig>> = {
dev: {
debugMode: true,
logLevel: 'debug',
apiEndpoint: 'http://localhost:3000',
featureFlags: { experimentalEditor: true, betaSync: true },
},
test: {
debugMode: true,
logLevel: 'info',
apiEndpoint: 'https://staging.api.example.com',
featureFlags: { experimentalEditor: true, betaSync: false },
},
prod: {
debugMode: false,
logLevel: 'error',
apiEndpoint: 'https://api.example.com',
featureFlags: {},
},
};
export function detectEnvironment(vaultPath: string): string {
if (vaultPath.includes('obsidian-envs/dev')) return 'dev';
if (vaultPath.includes('obsidian-envs/test')) return 'test';
return 'prod';
}
export function getConfig(env: string): PluginConfig {
const defaults: PluginConfig = {
debugMode: false,
logLevel: 'error',
apiEndpoint: '',
featureFlags: {},
};
return { ...defaults, ...ENV_CONFIGS[env] };
}在插件的方法中使用该配置:
onload()typescript
async onload() {
const vaultPath = (this.app.vault.adapter as any).basePath;
const env = detectEnvironment(vaultPath);
const config = getConfig(env);
console.log(`[your-plugin] Running in ${env} mode`);
if (config.debugMode) {
// Register debug commands only in dev/test
this.addCommand({
id: 'dump-state',
name: 'Dump Plugin State (debug)',
callback: () => console.log(JSON.stringify(this.settings, null, 2)),
});
}
}Step 4: Vault Templates for Team Onboarding
步骤4:用于团队入职的vault模板
Create a template vault that new team members clone:
vault-template/
.obsidian/
app.json # Standard app settings
appearance.json # Theme and font settings
hotkeys.json # Team-standard keybindings
community-plugins.json # Approved plugin list
plugins/ # Pre-configured plugin data.json files
dataview/data.json
templater-obsidian/data.json
templates/ # Note templates (daily, meeting, project)
daily.md
meeting.md
project-kickoff.md
README.md # Vault orientation guideScript to provision a new team member's vault:
bash
#!/bin/bash创建一个模板vault,新团队成员可以直接克隆使用:
vault-template/
.obsidian/
app.json # 标准应用设置
appearance.json # 主题和字体设置
hotkeys.json # 团队统一快捷键
community-plugins.json # 审批通过的插件列表
plugins/ # 预配置的插件data.json文件
dataview/data.json
templater-obsidian/data.json
templates/ # 笔记模板(日报、会议、项目)
daily.md
meeting.md
project-kickoff.md
README.md # Vault使用指南为新团队成员预配置vault的脚本:
bash
#!/bin/bashprovision-vault.sh <username> <role>
provision-vault.sh <username> <role>
USERNAME=$1
ROLE=${2:-editor}
VAULT_DIR=~/obsidian-team-vaults/$USERNAME
cp -r vault-template "$VAULT_DIR"
USERNAME=$1
ROLE=${2:-editor}
VAULT_DIR=~/obsidian-team-vaults/$USERNAME
cp -r vault-template "$VAULT_DIR"
Inject user-specific settings
Inject user-specific settings
cat > "$VAULT_DIR/.obsidian/plugins/rbac-plugin/data.json" <<EOF
{
"userEmail": "${USERNAME}@company.com",
"role": "${ROLE}"
}
EOF
echo "Vault provisioned at $VAULT_DIR for $USERNAME ($ROLE)"
undefinedcat > "$VAULT_DIR/.obsidian/plugins/rbac-plugin/data.json" <<EOF
{
"userEmail": "${USERNAME}@company.com",
"role": "${ROLE}"
}
EOF
echo "Vault provisioned at $VAULT_DIR for $USERNAME ($ROLE)"
undefinedStep 5: Sync Strategies
步骤5:同步策略
Choose based on your team's needs:
Git sync (best for plugin developers):
bash
cd ~/obsidian-envs/prod
git init
cat > .gitignore <<'EOF'
.obsidian/workspace.json
.obsidian/workspace-mobile.json
.obsidian/cache
.trash/
EOF
git add -A && git commit -m "Initial vault state"Pair with the Obsidian Git plugin for auto-commit/push on a schedule.
Obsidian Sync (best for non-technical teams): Configure in Settings > Sync. Selective sync lets you exclude on certain devices to prevent config conflicts.
.obsidian/plugins/iCloud/Dropbox (simplest, most fragile): Place the vault inside the sync folder. Avoid editing on multiple devices simultaneously. conflicts are common -- keep a backup.
.obsidian/根据团队需求选择合适的同步方式:
Git同步(最适合插件开发者):
bash
cd ~/obsidian-envs/prod
git init
cat > .gitignore <<'EOF'
.obsidian/workspace.json
.obsidian/workspace-mobile.json
.obsidian/cache
.trash/
EOF
git add -A && git commit -m "Initial vault state"搭配Obsidian Git plugin使用,可以实现定时自动提交/推送。
Obsidian Sync(最适合非技术团队):在设置>同步中配置,选择性同步功能允许你在部分设备上排除目录,避免配置冲突。
.obsidian/plugins/iCloud/Dropbox同步(最简单但稳定性最差):将vault放在同步文件夹中,避免同时在多台设备上编辑,目录很容易出现冲突,请注意备份。
.obsidian/Step 6: Managing .obsidian/ Across Environments
步骤6:跨环境管理.obsidian/
目录
.obsidian/The directory holds all configuration. Key files and their sync behavior:
.obsidian/| File | Sync across envs? | Why |
|---|---|---|
| Yes | Core settings should be consistent |
| Yes | Theme consistency |
| Per-env | Dev may have debug plugins |
| Yes | Muscle memory matters |
| Never | Layout is per-device |
| Per-env | Settings differ by environment |
Script to sync safe configs from prod to other environments:
bash
#!/bin/bash.obsidian/| 文件 | 是否跨环境同步? | 原因 |
|---|---|---|
| 是 | 核心设置应当保持一致 |
| 是 | 保持主题一致性 |
| 按环境区分 | 开发环境可能会安装调试用插件 |
| 是 | 符合用户操作习惯 |
| 从不 | 布局是设备专属的 |
| 按环境区分 | 不同环境的设置存在差异 |
将安全配置从生产环境同步到其他环境的脚本:
bash
#!/bin/bashsync-config.sh -- copy safe configs from prod to dev/test
sync-config.sh -- copy safe configs from prod to dev/test
SAFE_FILES="app.json appearance.json hotkeys.json"
SRC=~/obsidian-envs/prod/.obsidian
for env in dev test; do
DST=~/obsidian-envs/$env/.obsidian
for f in $SAFE_FILES; do
cp "$SRC/$f" "$DST/$f" 2>/dev/null && echo "Synced $f to $env"
done
done
undefinedSAFE_FILES="app.json appearance.json hotkeys.json"
SRC=~/obsidian-envs/prod/.obsidian
for env in dev test; do
DST=~/obsidian-envs/$env/.obsidian
for f in $SAFE_FILES; do
cp "$SRC/$f" "$DST/$f" 2>/dev/null && echo "Synced $f to $env"
done
done
undefinedOutput
输出结果
- Three isolated vaults (dev/test/prod) with independent plugin configurations
- Symlinked plugin source in dev vault with hot reload
- Environment detection and config switching in plugin code
- Vault template and provisioning script for team onboarding
- Sync strategy configured (Git, Obsidian Sync, or cloud)
- management scripts for consistent cross-env config
.obsidian/
- 三个隔离的vault(开发/测试/生产),各自拥有独立的插件配置
- 开发环境vault中的插件源码通过符号链接关联,支持热重载
- 插件代码中内置环境检测和配置切换逻辑
- 用于团队入职的vault模板和预配置脚本
- 已配置的同步策略(Git、Obsidian Sync或云存储)
- 用于跨环境配置一致性的管理脚本
.obsidian/
Error Handling
错误处理
| Issue | Cause | Solution |
|---|---|---|
| Symlink not working | Permission denied on Windows | Run terminal as Administrator, or use |
| Plugin not appearing in dev vault | Symlink target missing | Run |
| Wrong config loaded | Vault path detection failed | Check |
| Hot reload not triggering | | Create empty |
Sync conflict on | Multiple devices open same vault | Add |
| Test vault has stale data | Forgot to refresh after plugin update | Copy latest build artifacts: |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 符号链接不生效 | Windows系统权限不足 | 以管理员身份运行终端,或使用 |
| 开发vault中不显示插件 | 符号链接目标缺少 | 先执行 |
| 加载了错误的配置 | vault路径检测失败 | 检查 |
| 热重载不触发 | 缺少 | 在插件目录下创建空的 |
| 多台设备同时打开同一个vault | 将 |
| 测试vault数据过时 | 插件更新后忘记刷新测试环境 | 复制最新的构建产物: |
Examples
示例
Solo developer workflow: Dev vault symlinked to plugin repo with hot reload. Test vault gets output copied in manually for final QA. Prod vault is your daily-driver vault with the released version from BRAT or community plugins.
npm run buildTeam onboarding: Run to create Alice's vault from the team template. She opens it in Obsidian, and all approved plugins with team-standard settings are pre-configured.
provision-vault.sh alice editorCI testing across Obsidian versions: Create a headless test vault with your plugin installed. Use or Electron automation to open the vault, run plugin commands, and verify output. Repeat for each Obsidian version in your support matrix.
obsidian-cli独立开发者工作流:开发vault通过符号链接关联插件仓库,开启热重载;手动将的产物复制到测试vault进行最终QA;生产vault是你日常使用的库,安装的是从BRAT或社区插件市场发布的正式版本。
npm run build团队入职:执行命令,从团队模板为Alice创建专属vault,她在Obsidian中打开后,所有已审批的插件和团队标准配置都已经预安装完成。
provision-vault.sh alice editor跨Obsidian版本的CI测试:创建一个安装了你的插件的无头测试vault,使用或Electron自动化工具打开vault,运行插件命令并验证输出,在你支持的所有Obsidian版本中重复该测试流程。
obsidian-cliResources
参考资源
Next Steps
后续步骤
For monitoring and logging across environments, see . For access control on shared vaults, see .
obsidian-observabilityobsidian-enterprise-rbac如需实现跨环境的监控和日志功能,请参考;如需为共享vault配置访问控制,请参考。
obsidian-observabilityobsidian-enterprise-rbac