Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ jobs:
uses: actions/checkout@v6

- name: Package deploy bundle
run: zip -r noone-nightly-deploy.zip compose.nightly.yml deploy/nginx/default.conf
run: zip -r noone-nightly-deploy.zip compose.nightly.yml compose.postgres.yml deploy/nginx/default.conf

- name: Upload deploy bundle
uses: actions/upload-artifact@v7
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@ bin/
.DS_Store

**/application-dev.yaml

# Default local SQLite database and its journal/WAL files
**/noone.db*
27 changes: 7 additions & 20 deletions compose.dev.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
services:
postgres:
image: postgres:17.6
environment:
POSTGRES_DB: noone
POSTGRES_PASSWORD: noone
POSTGRES_USER: noone
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U noone -d noone" ]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped

noone-server:
image: reajason/noone-server:nightly
depends_on:
postgres:
condition: service_healthy
environment:
SPRING_DATASOURCE_PASSWORD: noone
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/noone
SPRING_DATASOURCE_USERNAME: noone
SPRING_DATASOURCE_URL: "jdbc:sqlite:/app/data/noone.db?busy_timeout=5000&journal_mode=WAL&foreign_keys=true"
volumes:
- sqlite-data:/app/data

noone-web:
image: reajason/noone-web:nightly
Expand All @@ -41,4 +25,7 @@ services:
ports:
- "80:80"
volumes:
- ./deploy/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
- ./deploy/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro

volumes:
sqlite-data:
27 changes: 7 additions & 20 deletions compose.nightly.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
services:
postgres:
image: postgres:17.6
environment:
POSTGRES_DB: noone
POSTGRES_PASSWORD: noone
POSTGRES_USER: noone
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U noone -d noone" ]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped

noone-server:
image: reajason/noone-server:nightly
depends_on:
postgres:
condition: service_healthy
environment:
SPRING_DATASOURCE_PASSWORD: noone
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/noone
SPRING_DATASOURCE_USERNAME: noone
SPRING_DATASOURCE_URL: "jdbc:sqlite:/app/data/noone.db?busy_timeout=5000&journal_mode=WAL&foreign_keys=true"
volumes:
- sqlite-data:/app/data

noone-web:
image: reajason/noone-web:nightly
Expand All @@ -41,4 +25,7 @@ services:
ports:
- "80:80"
volumes:
- ./deploy/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
- ./deploy/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro

volumes:
sqlite-data:
28 changes: 28 additions & 0 deletions compose.postgres.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
services:
postgres:
image: postgres:17.6
environment:
POSTGRES_DB: ${POSTGRES_DB:-noone}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-noone}
POSTGRES_USER: ${POSTGRES_USER:-noone}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-noone} -d ${POSTGRES_DB:-noone}"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
- postgres-data-prod:/var/lib/postgresql/data

noone-server:
depends_on:
postgres:
condition: service_healthy
environment:
SPRING_PROFILES_ACTIVE: postgresql
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-noone}
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-noone}
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-noone}

volumes:
postgres-data-prod:
26 changes: 4 additions & 22 deletions compose.prod.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
services:
postgres:
image: postgres:17.6
environment:
POSTGRES_DB: ${POSTGRES_DB:-noone}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-noone}
POSTGRES_USER: ${POSTGRES_USER:-noone}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-noone} -d ${POSTGRES_DB:-noone}"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
- postgres-data-prod:/var/lib/postgresql/data

noone-server:
image: ghcr.io/${GHCR_OWNER:-reajason}/noone-server:${NOONE_SERVER_TAG:-latest}
depends_on:
postgres:
condition: service_healthy
environment:
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-noone}
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-noone}
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-noone}
SPRING_DATASOURCE_URL: "jdbc:sqlite:/app/data/noone.db?busy_timeout=5000&journal_mode=WAL&foreign_keys=true"
volumes:
- sqlite-data:/app/data
restart: unless-stopped

noone-web:
Expand All @@ -49,4 +31,4 @@ services:
- ./deploy/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro

volumes:
postgres-data-prod:
sqlite-data:
2 changes: 1 addition & 1 deletion noone-docs/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ No One(无名):Next Generation Polyglot Website Manager,打破语言边

前端:React 19、React Router V7 SSR、shadcn/ui

数据库:PostgreSQL
数据库:SQLite(默认)、PostgreSQL(可选)

部署:Docker、NGINX

Expand Down
23 changes: 21 additions & 2 deletions noone-docs/content/docs/quick-start.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,34 @@ icon: Rocket
```txt
 .
├──  compose.nightly.yml
├──  compose.postgres.yml
└──  deploy
└──  nginx
└── 󱁻 default.conf
```

使用 docker compose 命令运行 compose.nightly.yml 即可启动平台
### SQLite(默认)

使用 docker compose 命令运行 compose.nightly.yml 即可启动平台,无需单独部署数据库:

```bash
docker compose -f compose.nightly.yml up -d
```

启动之后访问 http://localhost ,账号密码在 noone-server 会在容器日志中展示
SQLite 数据库保存在 `sqlite-data` Docker 数据卷中,重建容器不会丢失数据。启动之后访问 http://localhost ,账号密码会在 noone-server 容器日志中展示。

### PostgreSQL(可选)

需要 PostgreSQL 时,额外加载 `compose.postgres.yml`:

```bash
POSTGRES_PASSWORD=your-strong-password docker compose \
-f compose.nightly.yml \
-f compose.postgres.yml \
up -d
```

可通过 `POSTGRES_DB`、`POSTGRES_USER` 和 `POSTGRES_PASSWORD` 配置数据库。直接运行 JAR 时,默认数据库文件为工作目录下的 `noone.db`;设置 `SPRING_PROFILES_ACTIVE=postgresql`,并按需设置 `SPRING_DATASOURCE_URL`、`SPRING_DATASOURCE_USERNAME` 和 `SPRING_DATASOURCE_PASSWORD` 即可使用 PostgreSQL。

> [!NOTE]
> 切换数据库类型不会自动迁移已有数据。SQLite 适用于单实例部署;请定期备份数据库文件或 Docker 数据卷。
2 changes: 2 additions & 0 deletions noone-server/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ dependencies {
implementation(libs.memshell.party.packer) {
exclude(group = "commons-logging", module = "commons-logging")
}
implementation("org.hibernate.orm:hibernate-community-dialects")
runtimeOnly("org.postgresql:postgresql")
runtimeOnly("org.xerial:sqlite-jdbc")
implementation(libs.byte.buddy)
implementation(libs.asm.commons)
implementation(libs.commons.lang3)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.expression.MethodBasedEvaluationContext;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.Ordered;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.Order;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
Expand All @@ -19,15 +21,17 @@
@Slf4j
@Aspect
@Component
// Finish the business transaction before starting the independent audit transaction.
@Order(Ordered.HIGHEST_PRECEDENCE)
@RequiredArgsConstructor
public class AuditLogAspect {

private final AuditLogService auditLogService;
private final ExpressionParser parser = new SpelExpressionParser();
private final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();

@Around("@annotation(auditLog)")
public Object around(ProceedingJoinPoint joinPoint, AuditLog auditLog) throws Throwable {
@Around("@annotation(com.reajason.noone.server.audit.AuditLog)")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = null;
boolean success = true;
Expand All @@ -44,6 +48,7 @@ public Object around(ProceedingJoinPoint joinPoint, AuditLog auditLog) throws Th
long durationMs = System.currentTimeMillis() - start;
try {
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
AuditLog auditLog = method.getAnnotation(AuditLog.class);
EvaluationContext context = new MethodBasedEvaluationContext(
joinPoint.getTarget(), method, joinPoint.getArgs(), parameterNameDiscoverer);
if (result != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public class AuditLogEntity {
private String requestUri;

@JdbcTypeCode(SqlTypes.JSON)
@Column(columnDefinition = "jsonb")
@Column
private Map<String, Object> details;

@CreatedDate
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.reajason.noone.server.config;

import org.hibernate.community.dialect.SQLiteDialect;
import org.hibernate.community.dialect.identity.SQLiteIdentityColumnSupport;
import org.hibernate.dialect.identity.IdentityColumnSupport;

/**
* Keeps the INTEGER type on SQLite identity columns when earlier columns also use INTEGER.
* Hibernate 7.2 checks the identity token case-sensitively against a lower-cased partial
* CREATE TABLE statement and can otherwise emit an untyped primary key.
*/
public final class NoOneSQLiteDialect extends SQLiteDialect {
private static final IdentityColumnSupport IDENTITY_COLUMN_SUPPORT = new SQLiteIdentityColumnSupport() {
@Override
public String getIdentityColumnString(int type) {
return "INTEGER";
}
};

@Override
public IdentityColumnSupport getIdentityColumnSupport() {
return IDENTITY_COLUMN_SUPPORT;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

@Enumerated(EnumType.STRING)
@Column(length = 20)
private PluginSource source = PluginSource.BUILTIN;

Check warning on line 49 in noone-server/src/main/java/com/reajason/noone/server/plugin/Plugin.java

View workflow job for this annotation

GitHub Actions / server

@builder will ignore the initializing expression entirely. If you want the initializing expression to serve as default, add @Builder.Default. If it is not supposed to be settable during building, make the field final.

@Column(columnDefinition = "text")
private String description;
Expand All @@ -58,11 +58,11 @@
private String payload;

@JdbcTypeCode(SqlTypes.JSON)
@Column(columnDefinition = "jsonb")
@Column
private Map<String, Object> actions;

@JdbcTypeCode(SqlTypes.JSON)
@Column(columnDefinition = "jsonb")
@Column
private Map<String, Object> meta;

@CreatedDate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,22 @@ public class ProfileEntity {
@Column(name = "protocol_type", nullable = false)
private ProtocolType protocolType = ProtocolType.HTTP;

@Column(name = "identifier", columnDefinition = "jsonb")
@Column(name = "identifier")
@JdbcTypeCode(SqlTypes.JSON)
private IdentifierConfig identifier;

@Column(name = "protocol_config", columnDefinition = "jsonb")
@Column(name = "protocol_config")
@JdbcTypeCode(SqlTypes.JSON)
private ProtocolConfig protocolConfig;

@Column(nullable = false)
private String password;

@Column(name = "request_transformations", columnDefinition = "jsonb")
@Column(name = "request_transformations")
@JdbcTypeCode(SqlTypes.JSON)
private List<String> requestTransformations;

@Column(name = "response_transformations", columnDefinition = "jsonb")
@Column(name = "response_transformations")
@JdbcTypeCode(SqlTypes.JSON)
private List<String> responseTransformations;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public class Shell {
/**
* Legacy shell-level custom headers kept for backward-compatible reads.
*/
@Column(name = "custom_headers", columnDefinition = "jsonb")
@Column(name = "custom_headers")
@JdbcTypeCode(SqlTypes.JSON)
private Map<String, String> customHeaders;

Expand Down Expand Up @@ -111,23 +111,23 @@ public class Shell {
private Long retryDelayMs;

/**
* Protocol-agnostic client configuration stored as JSONB.
* Protocol-agnostic client configuration stored as JSON.
* Supported keys vary by protocol type:
* <ul>
* <li>HTTP: proxyUrl, customHeaders, connectTimeoutMs, readTimeoutMs, skipSslVerify, maxRetries, retryDelayMs</li>
* <li>WebSocket: proxyUrl, customHeaders, connectTimeoutMs, readTimeoutMs, skipSslVerify</li>
* <li>Dubbo: readTimeoutMs</li>
* </ul>
*/
@Column(name = "client_config", columnDefinition = "jsonb")
@Column(name = "client_config")
@JdbcTypeCode(SqlTypes.JSON)
private Map<String, Object> clientConfig;

/**
* Normalized system info collected from the system-info plugin.
* Keys: os, arch, runtimeType, runtimeVersion.
*/
@Column(name = "basic_info", columnDefinition = "jsonb")
@Column(name = "basic_info")
@JdbcTypeCode(SqlTypes.JSON)
private Map<String, Object> basicInfo;

Expand Down
Loading
Loading