diff --git a/index.html b/index.html
index b2c0742..5336cb3 100644
--- a/index.html
+++ b/index.html
@@ -9,7 +9,7 @@
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json
index 350e3b4..4bcede5 100644
--- a/src/i18n/locales/en-US.json
+++ b/src/i18n/locales/en-US.json
@@ -27,7 +27,7 @@
"profile": "Profile",
"profileLabel": "Configuration Mode",
"quickStart": "Quick Start (Recommended for new users)",
- "quickStartDescription": "Get started quickly with minimal configuration",
+ "quickStartDescription": "Get started quickly with SQLite database, no PostgreSQL configuration needed",
"fullCustom": "Full Custom",
"fullCustomDescription": "Complete control over all configuration options",
"profileHelp": "Choose your configuration experience. You can switch modes at any time.",
@@ -58,6 +58,9 @@
"databaseConfig": "Database Configuration",
"databaseType": "Database Type",
"selectDatabaseType": "Select database type",
+ "sqliteDatabase": "SQLite Database",
+ "sqliteDescription": "Lightweight embedded database, no additional container needed, ideal for quick start and development environments.",
+ "sqliteDataLocation": "Data storage location",
"internalPostgresql": "Internal PostgreSQL",
"externalDatabase": "External Database",
"databaseName": "Database Name",
diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json
index 6540ceb..ccb22a9 100644
--- a/src/i18n/locales/zh-CN.json
+++ b/src/i18n/locales/zh-CN.json
@@ -27,7 +27,7 @@
"profile": "配置模式",
"profileLabel": "配置模式",
"quickStart": "本地快速体验 (推荐新用户)",
- "quickStartDescription": "使用最小配置快速开始",
+ "quickStartDescription": "使用 SQLite 数据库快速开始,无需额外配置 PostgreSQL",
"fullCustom": "完整自定义",
"fullCustomDescription": "完全控制所有配置选项",
"profileHelp": "选择您的配置体验。您可以随时切换模式。",
@@ -58,6 +58,9 @@
"databaseConfig": "数据库配置",
"databaseType": "数据库类型",
"selectDatabaseType": "选择数据库类型",
+ "sqliteDatabase": "SQLite 数据库",
+ "sqliteDescription": "轻量级嵌入式数据库,无需额外容器,适合快速体验和开发环境。",
+ "sqliteDataLocation": "数据存储位置",
"internalPostgresql": "内部 PostgreSQL",
"externalDatabase": "外部数据库",
"databaseName": "数据库名称",
diff --git a/src/lib/docker-compose/__tests__/__verify__/__snapshots__/api-provider-snapshots.test.ts.snap b/src/lib/docker-compose/__tests__/__verify__/__snapshots__/api-provider-snapshots.test.ts.snap
index 1789d95..e3cdcd8 100644
--- a/src/lib/docker-compose/__tests__/__verify__/__snapshots__/api-provider-snapshots.test.ts.snap
+++ b/src/lib/docker-compose/__tests__/__verify__/__snapshots__/api-provider-snapshots.test.ts.snap
@@ -15,13 +15,14 @@ exports[`API Provider Profiles - Complete File Verification with YAML Parsing >
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
- ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
+ Database__Provider: sqlite
+ ConnectionStrings__Default: "Data Source=/app/data/hagicode.db"
License__Activation__LicenseKey: "public-license-key"
# ==================================================
# Claude Code Configuration
@@ -35,34 +36,13 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
- depends_on:
- postgres:
- condition: service_healthy
- networks:
- - pcode-network
- restart: unless-stopped
-
- postgres:
- image: bitnami/postgresql:latest
- environment:
- POSTGRES_DATABASE: hagicode
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- POSTGRES_HOST_AUTH_METHOD: trust
- TZ: Asia/Shanghai
- volumes:
- - postgres-data:/bitnami/postgresql
- healthcheck:
- test: ["CMD", "pg_isready", "-U", "postgres"]
- interval: 10s
- timeout: 3s
- retries: 3
+ - hagicode_data:/app/data
networks:
- pcode-network
restart: unless-stopped
volumes:
- postgres-data:
+ hagicode_data:
networks:
pcode-network:
@@ -84,13 +64,14 @@ exports[`API Provider Profiles - Complete File Verification with YAML Parsing >
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
- ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
+ Database__Provider: sqlite
+ ConnectionStrings__Default: "Data Source=/app/data/hagicode.db"
License__Activation__LicenseKey: "public-license-key"
# ==================================================
# Claude Code Configuration
@@ -105,34 +86,13 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
- depends_on:
- postgres:
- condition: service_healthy
- networks:
- - pcode-network
- restart: unless-stopped
-
- postgres:
- image: bitnami/postgresql:latest
- environment:
- POSTGRES_DATABASE: hagicode
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- POSTGRES_HOST_AUTH_METHOD: trust
- TZ: Asia/Shanghai
- volumes:
- - postgres-data:/bitnami/postgresql
- healthcheck:
- test: ["CMD", "pg_isready", "-U", "postgres"]
- interval: 10s
- timeout: 3s
- retries: 3
+ - hagicode_data:/app/data
networks:
- pcode-network
restart: unless-stopped
volumes:
- postgres-data:
+ hagicode_data:
networks:
pcode-network:
@@ -154,13 +114,14 @@ exports[`API Provider Profiles - Complete File Verification with YAML Parsing >
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
- ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
+ Database__Provider: sqlite
+ ConnectionStrings__Default: "Data Source=/app/data/hagicode.db"
License__Activation__LicenseKey: "public-license-key"
# ==================================================
# Claude Code Configuration
@@ -175,34 +136,13 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
- depends_on:
- postgres:
- condition: service_healthy
- networks:
- - pcode-network
- restart: unless-stopped
-
- postgres:
- image: bitnami/postgresql:latest
- environment:
- POSTGRES_DATABASE: hagicode
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- POSTGRES_HOST_AUTH_METHOD: trust
- TZ: Asia/Shanghai
- volumes:
- - postgres-data:/bitnami/postgresql
- healthcheck:
- test: ["CMD", "pg_isready", "-U", "postgres"]
- interval: 10s
- timeout: 3s
- retries: 3
+ - hagicode_data:/app/data
networks:
- pcode-network
restart: unless-stopped
volumes:
- postgres-data:
+ hagicode_data:
networks:
pcode-network:
diff --git a/src/lib/docker-compose/__tests__/__verify__/__snapshots__/full-custom-snapshots.test.ts.snap b/src/lib/docker-compose/__tests__/__verify__/__snapshots__/full-custom-snapshots.test.ts.snap
index 40aea29..0056119 100644
--- a/src/lib/docker-compose/__tests__/__verify__/__snapshots__/full-custom-snapshots.test.ts.snap
+++ b/src/lib/docker-compose/__tests__/__verify__/__snapshots__/full-custom-snapshots.test.ts.snap
@@ -15,12 +15,13 @@ exports[`Full Custom Profiles - Complete File Verification with YAML Parsing > s
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
+ Database__Provider: postgresql
ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
License__Activation__LicenseKey: "public-license-key"
PUID: 1000
@@ -37,6 +38,7 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
+ - hagicode_data:/app/data
depends_on:
postgres:
condition: service_healthy
@@ -64,6 +66,7 @@ services:
restart: unless-stopped
volumes:
+ hagicode_data:
postgres-data:
networks:
@@ -86,12 +89,13 @@ exports[`Full Custom Profiles - Complete File Verification with YAML Parsing > s
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
+ Database__Provider: postgresql
ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
License__Activation__LicenseKey: "public-license-key"
# ==================================================
@@ -106,6 +110,7 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
+ - hagicode_data:/app/data
depends_on:
postgres:
condition: service_healthy
@@ -133,6 +138,7 @@ services:
restart: unless-stopped
volumes:
+ hagicode_data:
postgres-data:
networks:
@@ -155,12 +161,13 @@ exports[`Full Custom Profiles - Complete File Verification with YAML Parsing > s
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
+ Database__Provider: postgresql
ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
License__Activation__LicenseKey: "public-license-key"
# ==================================================
@@ -175,6 +182,7 @@ services:
- "8080:45000"
volumes:
- C:\\\\repos:/app/workdir
+ - hagicode_data:/app/data
depends_on:
postgres:
condition: service_healthy
@@ -202,6 +210,7 @@ services:
restart: unless-stopped
volumes:
+ hagicode_data:
postgres-data:
networks:
@@ -224,12 +233,13 @@ exports[`Full Custom Profiles - Complete File Verification with YAML Parsing > s
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
+ Database__Provider: postgresql
ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
License__Activation__LicenseKey: "public-license-key"
PUID: 1000
@@ -246,6 +256,7 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
+ - hagicode_data:/app/data
depends_on:
postgres:
condition: service_healthy
@@ -272,6 +283,9 @@ services:
- pcode-network
restart: unless-stopped
+volumes:
+ hagicode_data:
+
networks:
pcode-network:
driver: bridge"
@@ -292,12 +306,13 @@ exports[`Full Custom Profiles - Complete File Verification with YAML Parsing > s
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
+ Database__Provider: postgresql
ConnectionStrings__Default: "Host=external-postgres.example.com;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
License__Activation__LicenseKey: "public-license-key"
# ==================================================
@@ -312,10 +327,14 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
+ - hagicode_data:/app/data
networks:
- pcode-network
restart: unless-stopped
+volumes:
+ hagicode_data:
+
networks:
pcode-network:
driver: bridge"
diff --git a/src/lib/docker-compose/__tests__/__verify__/__snapshots__/quick-start-snapshots.test.ts.snap b/src/lib/docker-compose/__tests__/__verify__/__snapshots__/quick-start-snapshots.test.ts.snap
index 2a74fd2..5d3e1a6 100644
--- a/src/lib/docker-compose/__tests__/__verify__/__snapshots__/quick-start-snapshots.test.ts.snap
+++ b/src/lib/docker-compose/__tests__/__verify__/__snapshots__/quick-start-snapshots.test.ts.snap
@@ -15,13 +15,14 @@ exports[`Quick Start Profiles - Complete File Verification with YAML Parsing > s
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
- ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
+ Database__Provider: sqlite
+ ConnectionStrings__Default: "Data Source=/app/data/hagicode.db"
License__Activation__LicenseKey: "public-license-key"
# ==================================================
# Claude Code Configuration
@@ -35,34 +36,13 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
- depends_on:
- postgres:
- condition: service_healthy
- networks:
- - pcode-network
- restart: unless-stopped
-
- postgres:
- image: bitnami/postgresql:latest
- environment:
- POSTGRES_DATABASE: hagicode
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- POSTGRES_HOST_AUTH_METHOD: trust
- TZ: Asia/Shanghai
- volumes:
- - postgres-data:/bitnami/postgresql
- healthcheck:
- test: ["CMD", "pg_isready", "-U", "postgres"]
- interval: 10s
- timeout: 3s
- retries: 3
+ - hagicode_data:/app/data
networks:
- pcode-network
restart: unless-stopped
volumes:
- postgres-data:
+ hagicode_data:
networks:
pcode-network:
@@ -84,13 +64,14 @@ exports[`Quick Start Profiles - Complete File Verification with YAML Parsing > s
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
- ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
+ Database__Provider: sqlite
+ ConnectionStrings__Default: "Data Source=/app/data/hagicode.db"
License__Activation__LicenseKey: "public-license-key"
# ==================================================
# Claude Code Configuration
@@ -105,34 +86,13 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
- depends_on:
- postgres:
- condition: service_healthy
- networks:
- - pcode-network
- restart: unless-stopped
-
- postgres:
- image: bitnami/postgresql:latest
- environment:
- POSTGRES_DATABASE: hagicode
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- POSTGRES_HOST_AUTH_METHOD: trust
- TZ: Asia/Shanghai
- volumes:
- - postgres-data:/bitnami/postgresql
- healthcheck:
- test: ["CMD", "pg_isready", "-U", "postgres"]
- interval: 10s
- timeout: 3s
- retries: 3
+ - hagicode_data:/app/data
networks:
- pcode-network
restart: unless-stopped
volumes:
- postgres-data:
+ hagicode_data:
networks:
pcode-network:
@@ -154,13 +114,14 @@ exports[`Quick Start Profiles - Complete File Verification with YAML Parsing > s
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
- ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
+ Database__Provider: sqlite
+ ConnectionStrings__Default: "Data Source=/app/data/hagicode.db"
License__Activation__LicenseKey: "public-license-key"
# ==================================================
# Claude Code Configuration
@@ -175,34 +136,13 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
- depends_on:
- postgres:
- condition: service_healthy
- networks:
- - pcode-network
- restart: unless-stopped
-
- postgres:
- image: bitnami/postgresql:latest
- environment:
- POSTGRES_DATABASE: hagicode
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- POSTGRES_HOST_AUTH_METHOD: trust
- TZ: Asia/Shanghai
- volumes:
- - postgres-data:/bitnami/postgresql
- healthcheck:
- test: ["CMD", "pg_isready", "-U", "postgres"]
- interval: 10s
- timeout: 3s
- retries: 3
+ - hagicode_data:/app/data
networks:
- pcode-network
restart: unless-stopped
volumes:
- postgres-data:
+ hagicode_data:
networks:
pcode-network:
@@ -224,13 +164,14 @@ exports[`Quick Start Profiles - Complete File Verification with YAML Parsing > s
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
- ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
+ Database__Provider: sqlite
+ ConnectionStrings__Default: "Data Source=/app/data/hagicode.db"
License__Activation__LicenseKey: "public-license-key"
# ==================================================
# Claude Code Configuration
@@ -244,34 +185,13 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
- depends_on:
- postgres:
- condition: service_healthy
- networks:
- - pcode-network
- restart: unless-stopped
-
- postgres:
- image: bitnami/postgresql:latest
- environment:
- POSTGRES_DATABASE: hagicode
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- POSTGRES_HOST_AUTH_METHOD: trust
- TZ: Asia/Shanghai
- volumes:
- - postgres-data:/bitnami/postgresql
- healthcheck:
- test: ["CMD", "pg_isready", "-U", "postgres"]
- interval: 10s
- timeout: 3s
- retries: 3
+ - hagicode_data:/app/data
networks:
- pcode-network
restart: unless-stopped
volumes:
- postgres-data:
+ hagicode_data:
networks:
pcode-network:
@@ -293,13 +213,14 @@ exports[`Quick Start Profiles - Complete File Verification with YAML Parsing > s
services:
hagicode:
- image: newbe36524/hagicode:latest
+ image: newbe36524/hagicode:0
container_name: hagicode
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:45000
TZ: Asia/Shanghai
- ConnectionStrings__Default: "Host=postgres;Port=5432;Database=hagicode;Username=postgres;Password=postgres"
+ Database__Provider: sqlite
+ ConnectionStrings__Default: "Data Source=/app/data/hagicode.db"
License__Activation__LicenseKey: "public-license-key"
# ==================================================
# Claude Code Configuration
@@ -313,34 +234,13 @@ services:
- "8080:45000"
volumes:
- /home/user/repos:/app/workdir
- depends_on:
- postgres:
- condition: service_healthy
- networks:
- - pcode-network
- restart: unless-stopped
-
- postgres:
- image: bitnami/postgresql:latest
- environment:
- POSTGRES_DATABASE: hagicode
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- POSTGRES_HOST_AUTH_METHOD: trust
- TZ: Asia/Shanghai
- volumes:
- - postgres-data:/bitnami/postgresql
- healthcheck:
- test: ["CMD", "pg_isready", "-U", "postgres"]
- interval: 10s
- timeout: 3s
- retries: 3
+ - hagicode_data:/app/data
networks:
- pcode-network
restart: unless-stopped
volumes:
- postgres-data:
+ hagicode_data:
networks:
pcode-network:
diff --git a/src/lib/docker-compose/__tests__/__verify__/api-provider-snapshots.test.ts b/src/lib/docker-compose/__tests__/__verify__/api-provider-snapshots.test.ts
index bad3924..2d0d6b8 100644
--- a/src/lib/docker-compose/__tests__/__verify__/api-provider-snapshots.test.ts
+++ b/src/lib/docker-compose/__tests__/__verify__/api-provider-snapshots.test.ts
@@ -174,7 +174,9 @@ describe('API Provider Profiles - Complete File Verification with YAML Parsing',
});
it('should validate postgres service healthcheck structure', async () => {
- const config = createZaiProviderConfig();
+ const config = createZaiProviderConfig({
+ databaseType: 'internal' // 明确设置内部 PostgreSQL 以测试 postgres healthcheck
+ });
const yaml = generateYAML(config, 'zh-CN', FIXED_DATE);
const parsed = parseDockerComposeYAML(yaml);
diff --git a/src/lib/docker-compose/__tests__/__verify__/full-custom-snapshots.test.ts b/src/lib/docker-compose/__tests__/__verify__/full-custom-snapshots.test.ts
index 1b4d6cd..14e475d 100644
--- a/src/lib/docker-compose/__tests__/__verify__/full-custom-snapshots.test.ts
+++ b/src/lib/docker-compose/__tests__/__verify__/full-custom-snapshots.test.ts
@@ -123,8 +123,10 @@ describe('Full Custom Profiles - Complete File Verification with YAML Parsing',
expect(hasService(yaml, 'hagicode')).toBe(true);
expect(hasService(yaml, 'postgres')).toBe(false);
- // 验证没有顶层卷配置
- expect(validation.parsed.volumes).toBeUndefined();
+ // 验证只有 hagicode_data 卷(没有 postgres-data)
+ expect(validation.parsed.volumes).toBeDefined();
+ expect(validation.parsed.volumes?.hagicode_data).toBeDefined();
+ expect(validation.parsed.volumes?.postgres_data).toBeUndefined();
// 验证外部数据库连接字符串
const connectionString = getServiceEnvVar(yaml, 'hagicode', 'ConnectionStrings__Default');
@@ -158,8 +160,10 @@ describe('Full Custom Profiles - Complete File Verification with YAML Parsing',
const postgresVolumes = getServiceVolumes(yaml, 'postgres');
expect(postgresVolumes).toContain('/data/postgres:/bitnami/postgresql');
- // 验证没有顶层卷配置(绑定挂载不需要)
- expect(validation.parsed.volumes).toBeUndefined();
+ // 验证只有 hagicode_data 卷(没有 postgres-data,因为使用绑定挂载)
+ expect(validation.parsed.volumes).toBeDefined();
+ expect(validation.parsed.volumes?.hagicode_data).toBeDefined();
+ expect(validation.parsed.volumes?.postgres_data).toBeUndefined();
// 验证 PUID/PGID
expect(hasEnvVar(yaml, 'hagicode', 'PUID')).toBe(true);
diff --git a/src/lib/docker-compose/__tests__/__verify__/quick-start-snapshots.test.ts b/src/lib/docker-compose/__tests__/__verify__/quick-start-snapshots.test.ts
index 0601b55..3c3c795 100644
--- a/src/lib/docker-compose/__tests__/__verify__/quick-start-snapshots.test.ts
+++ b/src/lib/docker-compose/__tests__/__verify__/quick-start-snapshots.test.ts
@@ -29,12 +29,13 @@ describe('Quick Start Profiles - Complete File Verification with YAML Parsing',
expect(validation.errors).toEqual([]);
expect(validation.valid).toBe(true);
- // 验证服务存在
+ // 验证服务存在(快速启动现在使用 SQLite,没有 postgres 服务)
expect(hasService(yaml, 'hagicode')).toBe(true);
- expect(hasService(yaml, 'postgres')).toBe(true);
+ expect(hasService(yaml, 'postgres')).toBe(false);
- // 验证卷存在(内部数据库使用命名卷)
- expect(hasVolume(yaml, 'postgres-data')).toBe(true);
+ // 验证卷存在(SQLite 只使用 hagicode_data)
+ expect(hasVolume(yaml, 'hagicode_data')).toBe(true);
+ expect(hasVolume(yaml, 'postgres-data')).toBe(false);
// 验证网络存在
expect(hasNetwork(yaml, 'pcode-network')).toBe(true);
@@ -44,9 +45,8 @@ describe('Quick Start Profiles - Complete File Verification with YAML Parsing',
expect(hasEnvVar(yaml, 'hagicode', 'ANTHROPIC_AUTH_TOKEN')).toBe(true);
expect(hasEnvVar(yaml, 'hagicode', 'ConnectionStrings__Default')).toBe(true);
- // 验证镜像
- expect(getServiceImage(yaml, 'hagicode')).toBe('newbe36524/hagicode:latest');
- expect(getServiceImage(yaml, 'postgres')).toContain('postgresql');
+ // 验证镜像(快速启动现在使用镜像标签 0)
+ expect(getServiceImage(yaml, 'hagicode')).toBe('newbe36524/hagicode:0');
// 验证端口映射
const ports = getServicePorts(yaml, 'hagicode');
@@ -69,9 +69,9 @@ describe('Quick Start Profiles - Complete File Verification with YAML Parsing',
expect(validation.errors).toEqual([]);
expect(validation.valid).toBe(true);
- // 验证服务
+ // 验证服务(快速启动现在使用 SQLite,没有 postgres 服务)
expect(hasService(yaml, 'hagicode')).toBe(true);
- expect(hasService(yaml, 'postgres')).toBe(true);
+ expect(hasService(yaml, 'postgres')).toBe(false);
// 验证网络
expect(hasNetwork(yaml, 'pcode-network')).toBe(true);
@@ -156,19 +156,12 @@ describe('Quick Start Profiles - Complete File Verification with YAML Parsing',
const parsed = validateDockerComposeStructure(yaml);
expect(parsed.valid).toBe(true);
- // 验证 hagicode 服务依赖 postgres
+ // 快速启动使用 SQLite,没有 postgres 服务,所以没有 depends_on
const hagicodeService = parsed.parsed.services.hagicode;
- expect(hagicodeService.depends_on).toBeDefined();
- expect(hagicodeService.depends_on.postgres).toBeDefined();
- expect(hagicodeService.depends_on.postgres.condition).toBe('service_healthy');
-
- // 验证 postgres 的 healthcheck
- const postgresService = parsed.parsed.services.postgres;
- expect(postgresService.healthcheck).toBeDefined();
- expect(postgresService.healthcheck.test).toContain('pg_isready');
- expect(postgresService.healthcheck.interval).toBe('10s');
- expect(postgresService.healthcheck.timeout).toBe('3s');
- expect(postgresService.healthcheck.retries).toBe(3);
+ expect(hagicodeService.depends_on).toBeUndefined();
+
+ // 验证没有 postgres 服务
+ expect(parsed.parsed.services.postgres).toBeUndefined();
});
it('should validate network configuration', async () => {
@@ -183,9 +176,11 @@ describe('Quick Start Profiles - Complete File Verification with YAML Parsing',
expect(network).toBeDefined();
expect(network.driver).toBe('bridge');
- // 验证服务连接到网络
+ // 验证 hagicode 服务连接到网络
expect(parsed.parsed.services.hagicode.networks).toContain('pcode-network');
- expect(parsed.parsed.services.postgres.networks).toContain('pcode-network');
+
+ // 快速启动使用 SQLite,没有 postgres 服务
+ expect(parsed.parsed.services.postgres).toBeUndefined();
});
it('should validate restart policy', async () => {
@@ -197,6 +192,8 @@ describe('Quick Start Profiles - Complete File Verification with YAML Parsing',
// 验证重启策略
expect(parsed.parsed.services.hagicode.restart).toBe('unless-stopped');
- expect(parsed.parsed.services.postgres.restart).toBe('unless-stopped');
+
+ // 快速启动使用 SQLite,没有 postgres 服务
+ expect(parsed.parsed.services.postgres).toBeUndefined();
});
});
diff --git a/src/lib/docker-compose/__tests__/bdd/edge-cases.test.ts b/src/lib/docker-compose/__tests__/bdd/edge-cases.test.ts
index 72bfd77..a5d3c3a 100644
--- a/src/lib/docker-compose/__tests__/bdd/edge-cases.test.ts
+++ b/src/lib/docker-compose/__tests__/bdd/edge-cases.test.ts
@@ -233,7 +233,8 @@ describe('Docker Compose Generation: Edge Cases', () => {
// Given
const config = createMockConfig({
imageRegistry: 'docker-hub',
- imageTag: 'v1.2.3'
+ imageTag: 'v1.2.3',
+ databaseType: 'internal' // Explicitly set to get postgres service
});
// When
@@ -248,7 +249,8 @@ describe('Docker Compose Generation: Edge Cases', () => {
// Given
const config = createMockConfig({
imageRegistry: 'aliyun-acr',
- imageTag: 'v2.0.0'
+ imageTag: 'v2.0.0',
+ databaseType: 'internal' // Explicitly set to get postgres service
});
// When
@@ -263,7 +265,8 @@ describe('Docker Compose Generation: Edge Cases', () => {
// Given
const config = createMockConfig({
imageRegistry: 'azure-acr',
- imageTag: 'latest'
+ imageTag: 'latest',
+ databaseType: 'internal' // Explicitly set to get postgres service
});
// When
diff --git a/src/lib/docker-compose/__tests__/bdd/full-custom-scenarios.test.ts b/src/lib/docker-compose/__tests__/bdd/full-custom-scenarios.test.ts
index e4b74d8..ceab09a 100644
--- a/src/lib/docker-compose/__tests__/bdd/full-custom-scenarios.test.ts
+++ b/src/lib/docker-compose/__tests__/bdd/full-custom-scenarios.test.ts
@@ -129,7 +129,7 @@ describe('Docker Compose Generation: Full Custom Profile', () => {
});
describe('Scenario 5: Internal Database with Bind Mount', () => {
- it('Given an internal database with bind mount, When generating YAML, Then volume section should not be included', () => {
+ it('Given an internal database with bind mount, When generating YAML, Then volumes section should include hagicode_data but not postgres-data', () => {
// Given
const config = createMockConfig({
databaseType: 'internal',
@@ -141,10 +141,10 @@ describe('Docker Compose Generation: Full Custom Profile', () => {
// When
const result = generateYAML(config, 'zh-CN', FIXED_DATE);
- // Then - check that there's no top-level volumes section
- const networksIndex = result.indexOf('\nnetworks:');
- const beforeNetworks = result.substring(0, networksIndex);
- expect(beforeNetworks).not.toContain('\nvolumes:');
+ // Then - hagicode_data is always present, but postgres-data is not for bind mounts
+ expect(result).toContain('\nvolumes:');
+ expect(result).toContain('hagicode_data:');
+ expect(result).not.toContain('postgres-data:');
});
it('Given an internal database with bind mount, When generating YAML, Then postgres service should use bind mount', () => {
@@ -190,17 +190,17 @@ describe('Docker Compose Generation: Full Custom Profile', () => {
expect(result).toContain('ConnectionStrings__Default: "Host=external-db.example.com;Port=5433');
});
- it('Given an external database configuration, When generating YAML, Then volumes section should not be included', () => {
+ it('Given an external database configuration, When generating YAML, Then volumes section should include hagicode_data but not postgres-data', () => {
// Given
const config = createExternalDbConfig();
// When
const result = generateYAML(config, 'zh-CN', FIXED_DATE);
- // Then - check that there's no top-level volumes section
- const servicesEnd = result.indexOf('restart: unless-stopped');
- const afterServices = result.substring(servicesEnd);
- expect(afterServices).not.toContain('\nvolumes:');
+ // Then - hagicode_data is always present, but postgres-data should not be for external db
+ expect(result).toContain('\nvolumes:');
+ expect(result).toContain('hagicode_data:');
+ expect(result).not.toContain('postgres-data:');
});
});
});
diff --git a/src/lib/docker-compose/__tests__/bdd/quick-start-scenarios.test.ts b/src/lib/docker-compose/__tests__/bdd/quick-start-scenarios.test.ts
index 673c2f3..8546906 100644
--- a/src/lib/docker-compose/__tests__/bdd/quick-start-scenarios.test.ts
+++ b/src/lib/docker-compose/__tests__/bdd/quick-start-scenarios.test.ts
@@ -20,7 +20,8 @@ describe('Docker Compose Generation: Quick Start Profile', () => {
// Then: output should contain required sections
expect(result).toContain('services:');
expect(result).toContain('hagicode:');
- expect(result).toContain('postgres:');
+ // Quick start now uses SQLite, so no postgres service
+ expect(result).not.toContain('postgres:');
expect(result).toContain('volumes:');
expect(result).toContain('networks:');
});
diff --git a/src/lib/docker-compose/__tests__/helpers/config.ts b/src/lib/docker-compose/__tests__/helpers/config.ts
index 2327130..b483830 100644
--- a/src/lib/docker-compose/__tests__/helpers/config.ts
+++ b/src/lib/docker-compose/__tests__/helpers/config.ts
@@ -12,12 +12,12 @@ export function createMockConfig(
profile: 'quick-start',
httpPort: '8080',
containerName: 'hagicode',
- imageTag: 'latest',
+ imageTag: '0',
hostOS: 'linux',
imageRegistry: 'docker-hub',
aspNetEnvironment: 'Production',
timezone: 'Asia/Shanghai',
- databaseType: 'internal',
+ databaseType: 'sqlite',
postgresDatabase: 'hagicode',
postgresUser: 'postgres',
postgresPassword: 'postgres',
@@ -49,7 +49,7 @@ export function createQuickStartConfig(
profile: 'quick-start',
hostOS: 'linux',
workdirCreatedByRoot: true,
- databaseType: 'internal',
+ databaseType: 'sqlite',
volumeType: 'named',
...overrides
});
diff --git a/src/lib/docker-compose/__tests__/unit/generator.test.ts b/src/lib/docker-compose/__tests__/unit/generator.test.ts
index 6ff1e41..3e2d805 100644
--- a/src/lib/docker-compose/__tests__/unit/generator.test.ts
+++ b/src/lib/docker-compose/__tests__/unit/generator.test.ts
@@ -46,7 +46,7 @@ describe('buildAppService', () => {
const appServiceStr = appService.join('\n');
expect(appService).toContain(' hagicode:');
- expect(appServiceStr).toContain('image: newbe36524/hagicode:latest');
+ expect(appServiceStr).toContain('image: newbe36524/hagicode:0');
expect(appServiceStr).toContain('container_name: hagicode');
});
@@ -55,7 +55,7 @@ describe('buildAppService', () => {
const appService = buildAppService(config);
const appServiceStr = appService.join('\n');
- expect(appServiceStr).toContain('image: registry.cn-hangzhou.aliyuncs.com/hagicode/hagicode:latest');
+ expect(appServiceStr).toContain('image: registry.cn-hangzhou.aliyuncs.com/hagicode/hagicode:0');
});
it('should include Anthropic API configuration', () => {
@@ -275,15 +275,18 @@ describe('buildVolumesSection', () => {
expect(volumesStr).toContain('postgres-data:');
});
- it('should not generate volumes for external database', () => {
+ it('should not generate postgres-data volume for external database', () => {
const config = createMockConfig({ databaseType: 'external' });
const volumes = buildVolumesSection(config);
const volumesStr = volumes.join('\n');
- expect(volumesStr).not.toContain('volumes:');
+ // hagicode_data is always present, but postgres-data should not be
+ expect(volumesStr).toContain('volumes:');
+ expect(volumesStr).toContain('hagicode_data:');
+ expect(volumesStr).not.toContain('postgres-data:');
});
- it('should not generate volumes for bind mount', () => {
+ it('should generate hagicode_data volume for bind mount (no postgres-data)', () => {
const config = createMockConfig({
databaseType: 'internal',
volumeType: 'bind'
@@ -291,7 +294,10 @@ describe('buildVolumesSection', () => {
const volumes = buildVolumesSection(config);
const volumesStr = volumes.join('\n');
- expect(volumesStr).not.toContain('volumes:');
+ // hagicode_data is always present, but postgres-data is not for bind mounts
+ expect(volumesStr).toContain('volumes:');
+ expect(volumesStr).toContain('hagicode_data:');
+ expect(volumesStr).not.toContain('postgres-data:');
});
});
@@ -325,7 +331,7 @@ describe('generateYAML', () => {
expect(yaml).toContain('pcode-network:');
});
- it('should generate YAML without volumes for external database', () => {
+ it('should generate YAML with hagicode_data volume for external database (no postgres-data)', () => {
const config = createMockConfig({
databaseType: 'external',
externalDbHost: 'external-host',
@@ -337,10 +343,12 @@ describe('generateYAML', () => {
expect(yaml).toContain('hagicode:');
expect(yaml).not.toContain('postgres:');
- // Check that there's no top-level volumes section (after the services section)
+ // hagicode_data volume is always present, but postgres-data should not be
const servicesEnd = yaml.indexOf('restart: unless-stopped');
const afterServices = yaml.substring(servicesEnd);
- expect(afterServices).not.toContain('\nvolumes:');
+ expect(afterServices).toContain('\nvolumes:');
+ expect(afterServices).toContain('hagicode_data:');
+ expect(afterServices).not.toContain('postgres-data:');
});
it('should use fixed date when provided', () => {
diff --git a/src/lib/docker-compose/defaultConfig.ts b/src/lib/docker-compose/defaultConfig.ts
index 7b5fe94..0587e6e 100644
--- a/src/lib/docker-compose/defaultConfig.ts
+++ b/src/lib/docker-compose/defaultConfig.ts
@@ -4,12 +4,12 @@ export const defaultConfig: DockerComposeConfig = {
profile: 'quick-start',
httpPort: '45000',
containerName: 'hagicode-app',
- imageTag: 'latest',
+ imageTag: '0',
hostOS: 'linux',
imageRegistry: 'aliyun-acr',
aspNetEnvironment: 'Production',
timezone: 'Asia/Shanghai',
- databaseType: 'internal',
+ databaseType: 'sqlite',
postgresDatabase: 'hagicode',
postgresUser: 'postgres',
postgresPassword: 'postgres',
diff --git a/src/lib/docker-compose/generator.ts b/src/lib/docker-compose/generator.ts
index 884f753..e8a42b5 100644
--- a/src/lib/docker-compose/generator.ts
+++ b/src/lib/docker-compose/generator.ts
@@ -74,10 +74,15 @@ export function buildAppService(config: DockerComposeConfig): string[] {
lines.push(' ASPNETCORE_URLS: http://+:45000');
lines.push(` TZ: ${config.timezone}`);
- // Database connection string
- if (config.databaseType === 'internal') {
+ // Database connection string and provider
+ if (config.databaseType === 'sqlite') {
+ lines.push(' Database__Provider: sqlite');
+ lines.push(' ConnectionStrings__Default: "Data Source=/app/data/hagicode.db"');
+ } else if (config.databaseType === 'internal') {
+ lines.push(' Database__Provider: postgresql');
lines.push(` ConnectionStrings__Default: "Host=postgres;Port=5432;Database=${config.postgresDatabase};Username=${config.postgresUser};Password=${config.postgresPassword}"`);
} else {
+ lines.push(' Database__Provider: postgresql');
lines.push(` ConnectionStrings__Default: "Host=${config.externalDbHost};Port=${config.externalDbPort};Database=${config.postgresDatabase};Username=${config.postgresUser};Password=${config.postgresPassword}"`);
}
@@ -137,7 +142,11 @@ export function buildAppService(config: DockerComposeConfig): string[] {
lines.push(` - ${config.workdirPath || '/home/user/repos'}:/app/workdir`);
}
- // Depends on
+ // Application data volume (always present for all database types)
+ // Contains SQLite database file when using SQLite, or Orleans grain storage, logs, etc. for PostgreSQL
+ lines.push(' - hagicode_data:/app/data');
+
+ // Depends on (only for internal PostgreSQL)
if (config.databaseType === 'internal') {
lines.push(' depends_on:');
lines.push(' postgres:');
@@ -230,10 +239,15 @@ export function buildServicesSection(config: DockerComposeConfig): string[] {
export function buildVolumesSection(config: DockerComposeConfig): string[] {
const lines: string[] = [];
+ lines.push('');
+ lines.push('volumes:');
+
+ // hagicode_data is always present (contains app data: SQLite database or Orleans grain storage, logs, etc.)
+ lines.push(' hagicode_data:');
+
+ // postgres-data volume only for internal PostgreSQL
if (config.databaseType === 'internal' && config.volumeType === 'named') {
const volName = config.volumeName || 'postgres-data';
- lines.push('');
- lines.push('volumes:');
lines.push(` ${volName}:`);
}
diff --git a/src/lib/docker-compose/slice.ts b/src/lib/docker-compose/slice.ts
index c31334a..e5dc7a5 100644
--- a/src/lib/docker-compose/slice.ts
+++ b/src/lib/docker-compose/slice.ts
@@ -2,6 +2,9 @@ import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
import type { DockerComposeConfig } from '../../lib/docker-compose/types';
import { defaultConfig } from '../../lib/docker-compose/defaultConfig';
+// Configuration version - increment to invalidate old localStorage caches
+const CONFIG_VERSION = '2.0';
+
interface DockerComposeState {
config: DockerComposeConfig;
isLoading: boolean;
@@ -14,6 +17,17 @@ const getInitialConfig = (): DockerComposeConfig => {
}
try {
+ const savedVersion = localStorage.getItem('docker-compose-config-version');
+
+ // If version doesn't match, clear old config and use new defaults
+ if (savedVersion !== CONFIG_VERSION) {
+ console.log('Config version mismatch, resetting to defaults');
+ localStorage.setItem('docker-compose-config-version', CONFIG_VERSION);
+ localStorage.removeItem('docker-compose-config');
+ localStorage.setItem('docker-compose-image-registry', defaultConfig.imageRegistry);
+ return { ...defaultConfig };
+ }
+
const savedConfig = localStorage.getItem('docker-compose-config');
if (savedConfig) {
return { ...defaultConfig, ...JSON.parse(savedConfig) };
@@ -49,6 +63,7 @@ const dockerComposeSlice = createSlice({
// Save to localStorage
if (typeof window !== 'undefined') {
try {
+ localStorage.setItem('docker-compose-config-version', CONFIG_VERSION);
localStorage.setItem('docker-compose-config', JSON.stringify(state.config));
localStorage.setItem('docker-compose-image-registry', state.config.imageRegistry);
} catch (error) {
@@ -77,9 +92,15 @@ const dockerComposeSlice = createSlice({
const { field, value } = action.payload;
state.config[field] = value;
+ // Auto-reset database type to SQLite when switching to quick-start profile
+ if (field === 'profile' && value === 'quick-start') {
+ state.config.databaseType = 'sqlite';
+ }
+
// Save to localStorage
if (typeof window !== 'undefined') {
try {
+ localStorage.setItem('docker-compose-config-version', CONFIG_VERSION);
localStorage.setItem('docker-compose-config', JSON.stringify(state.config));
if (field === 'imageRegistry') {
localStorage.setItem('docker-compose-image-registry', value as string);
diff --git a/src/lib/docker-compose/types.ts b/src/lib/docker-compose/types.ts
index 6ae3215..bb7a5b0 100644
--- a/src/lib/docker-compose/types.ts
+++ b/src/lib/docker-compose/types.ts
@@ -3,7 +3,7 @@
* Migrated from pcode-docs project
*/
-export type DatabaseType = 'internal' | 'external';
+export type DatabaseType = 'sqlite' | 'internal' | 'external';
export type HostOS = 'windows' | 'linux';
export type LicenseKeyType = 'public' | 'custom';
export type VolumeType = 'named' | 'bind';