diff --git a/Directory.Packages.props b/Directory.Packages.props
index 76e22d924..9fd4a9c79 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -103,7 +103,7 @@
-
+
@@ -116,7 +116,7 @@
-
+
diff --git a/Elsa.sln b/Elsa.sln
index 23d1ee4cc..f78fa138b 100644
--- a/Elsa.sln
+++ b/Elsa.sln
@@ -322,6 +322,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{AA5ACF
scripts\docker\build-and-run-all-in-one-web-docker.sh = scripts\docker\build-and-run-all-in-one-web-docker.sh
scripts\docker\docker-compose.yml = scripts\docker\docker-compose.yml
scripts\docker\docker-run-all-in-one-web.ps1 = scripts\docker\docker-run-all-in-one-web.ps1
+ scripts\docker\docker-compose-citus.yml = scripts\docker\docker-compose-citus.yml
+ scripts\docker\docker-compose-yugabyte.yml = scripts\docker\docker-compose-yugabyte.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "elsa-studio", "elsa-studio", "{DFFE6199-B5A7-4BA8-A5E1-77D0426C6468}"
diff --git a/scripts/docker/docker-compose-citus.yml b/scripts/docker/docker-compose-citus.yml
new file mode 100644
index 000000000..3575fac53
--- /dev/null
+++ b/scripts/docker/docker-compose-citus.yml
@@ -0,0 +1,65 @@
+services:
+ # Coordinator Node
+ citus-coordinator:
+ image: citusdata/citus:latest
+ container_name: citus-coordinator
+ ports:
+ - "9700:5432"
+ environment:
+ POSTGRES_DB: citus
+ POSTGRES_USER: citus
+ POSTGRES_PASSWORD: citus
+ CITUS_HOST: citus-coordinator
+ command: [ "postgres", "-c", "wal_level=logical" ]
+ healthcheck:
+ test: ["CMD", "pg_isready", "-U", "citus"]
+ interval: 10s
+ retries: 5
+ networks:
+ - citus-network
+
+ # Worker Node 1
+ citus-worker-1:
+ image: citusdata/citus:latest
+ container_name: citus-worker-1
+ environment:
+ POSTGRES_DB: citus
+ POSTGRES_USER: citus
+ POSTGRES_PASSWORD: citus
+ CITUS_HOST: citus-worker-1
+ command: [ "postgres", "-c", "wal_level=logical" ]
+ depends_on:
+ - citus-coordinator
+ networks:
+ - citus-network
+
+ # Worker Node 2
+ citus-worker-2:
+ image: citusdata/citus:latest
+ container_name: citus-worker-2
+ environment:
+ POSTGRES_DB: citus
+ POSTGRES_USER: citus
+ POSTGRES_PASSWORD: citus
+ CITUS_HOST: citus-worker-2
+ command: [ "postgres", "-c", "wal_level=logical" ]
+ depends_on:
+ - citus-coordinator
+ networks:
+ - citus-network
+
+ # Citus Manager (optional - registers worker nodes automatically)
+ citus-manager:
+ image: citusdata/citus:latest
+ container_name: citus-manager
+ depends_on:
+ - citus-coordinator
+ - citus-worker-1
+ - citus-worker-2
+ command: [ "citus_setup" ]
+ networks:
+ - citus-network
+
+networks:
+ citus-network:
+ driver: bridge
diff --git a/scripts/docker/docker-compose-yugabyte.yml b/scripts/docker/docker-compose-yugabyte.yml
new file mode 100644
index 000000000..9dd6c489e
--- /dev/null
+++ b/scripts/docker/docker-compose-yugabyte.yml
@@ -0,0 +1,55 @@
+version: '3.8'
+
+services:
+ yb-master:
+ image: yugabytedb/yugabyte:latest
+ container_name: yb-master
+ command: ["/home/yugabyte/bin/yb-master", "--fs_data_dirs=/mnt/data", "--master_addresses=yb-master:7100"]
+ ports:
+ - "7001:7000" # Master UI
+ networks:
+ - yugabytedb
+ environment:
+ - YB_ENABLED_IN_POSTGRES_MODE=1
+ volumes:
+ - yb-master-data:/mnt/data
+
+ yb-tserver-1:
+ image: yugabytedb/yugabyte:latest
+ container_name: yb-tserver-1
+ command: ["/home/yugabyte/bin/yb-tserver", "--fs_data_dirs=/mnt/data", "--tserver_master_addrs=yb-master:7100", "--pgsql_proxy_bind_address=0.0.0.0:5433"]
+ ports:
+ - "5543:5433" # Changed from 5433 -> 5543 for PostgreSQL
+ - "9000:9000" # TServer UI
+ networks:
+ - yugabytedb
+ depends_on:
+ - yb-master
+ environment:
+ - YB_ENABLED_IN_POSTGRES_MODE=1
+ volumes:
+ - yb-tserver-1-data:/mnt/data
+
+ yb-tserver-2:
+ image: yugabytedb/yugabyte:latest
+ container_name: yb-tserver-2
+ command: ["/home/yugabyte/bin/yb-tserver", "--fs_data_dirs=/mnt/data", "--tserver_master_addrs=yb-master:7100", "--pgsql_proxy_bind_address=0.0.0.0:5433"]
+ ports:
+ - "5544:5433" # Second worker node (internal)
+ - "9001:9000" # TServer UI
+ networks:
+ - yugabytedb
+ depends_on:
+ - yb-master
+ environment:
+ - YB_ENABLED_IN_POSTGRES_MODE=1
+ volumes:
+ - yb-tserver-2-data:/mnt/data
+
+networks:
+ yugabytedb:
+
+volumes:
+ yb-master-data:
+ yb-tserver-1-data:
+ yb-tserver-2-data:
diff --git a/scripts/docker/docker-compose.yml b/scripts/docker/docker-compose.yml
index 193fd0d94..f7c8198b2 100644
--- a/scripts/docker/docker-compose.yml
+++ b/scripts/docker/docker-compose.yml
@@ -71,6 +71,20 @@
expose:
- '3306'
+ citusdata:
+ image: citusdata/citus:13.0
+ container_name: citus_cluster
+ environment:
+ POSTGRES_USER: citus
+ POSTGRES_PASSWORD: citus_password
+ POSTGRES_DB: citus
+ ports:
+ - "9700:5432" # Citus uses PostgreSQL default port; 9700 avoids conflicts with other Postgres services
+ volumes:
+ - citusdata_data:/var/lib/postgresql/data
+
+ # (Other volume and network definitions)
+
redis:
image: redis:latest
ports:
@@ -116,7 +130,7 @@
ports:
- "4000:80"
- "2525:25"
-
+
networks:
consul:
@@ -124,5 +138,6 @@ volumes:
mongodb_data:
pgdata-3:
sqlserver_data:
+ citusdata_data:
elasticsearch-data:
driver: local
\ No newline at end of file
diff --git a/src/apps/Elsa.Server.LoadBalancer/Elsa.Server.LoadBalancer.csproj b/src/apps/Elsa.Server.LoadBalancer/Elsa.Server.LoadBalancer.csproj
index 1b2b2b688..ecf73e228 100644
--- a/src/apps/Elsa.Server.LoadBalancer/Elsa.Server.LoadBalancer.csproj
+++ b/src/apps/Elsa.Server.LoadBalancer/Elsa.Server.LoadBalancer.csproj
@@ -1,12 +1,5 @@
-
- net9.0
- Linux
- false
- latest
-
-
diff --git a/src/apps/Elsa.Server.Web/Enums/SqlDatabaseProvider.cs b/src/apps/Elsa.Server.Web/Enums/SqlDatabaseProvider.cs
index 651163385..72aad1b57 100644
--- a/src/apps/Elsa.Server.Web/Enums/SqlDatabaseProvider.cs
+++ b/src/apps/Elsa.Server.Web/Enums/SqlDatabaseProvider.cs
@@ -6,6 +6,8 @@ public enum SqlDatabaseProvider
Sqlite,
MySql,
PostgreSql,
+ Citus,
+ YugabyteDb,
Oracle,
CockroachDb
}
\ No newline at end of file
diff --git a/src/apps/Elsa.Server.Web/Program.cs b/src/apps/Elsa.Server.Web/Program.cs
index 85815a143..2818a232f 100644
--- a/src/apps/Elsa.Server.Web/Program.cs
+++ b/src/apps/Elsa.Server.Web/Program.cs
@@ -106,6 +106,8 @@ var identityTokenSection = identitySection.GetSection("Tokens");
var sqliteConnectionString = configuration.GetConnectionString("Sqlite")!;
var sqlServerConnectionString = configuration.GetConnectionString("SqlServer")!;
var postgresConnectionString = configuration.GetConnectionString("PostgreSql")!;
+var citusConnectionString = configuration.GetConnectionString("Citus")!;
+var yugabyteDbConnectionString = configuration.GetConnectionString("YugabyteDb")!;
var oracleConnectionString = configuration.GetConnectionString("Oracle")!;
var mySqlConnectionString = configuration.GetConnectionString("MySql")!;
var cockroachDbConnectionString = configuration.GetConnectionString("CockroachDb")!;
@@ -151,7 +153,7 @@ services
dapper.DbConnectionProvider = sp =>
{
if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer)
- return new SqlServerDbConnectionProvider(sqlServerConnectionString!);
+ return new SqlServerDbConnectionProvider(sqlServerConnectionString);
else
return new SqliteDbConnectionProvider(sqliteConnectionString);
};
@@ -204,15 +206,19 @@ services
identity.UseEntityFrameworkCore(ef =>
{
if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer)
- ef.UseSqlServer(sqlServerConnectionString!);
+ ef.UseSqlServer(sqlServerConnectionString);
else if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql)
- ef.UsePostgreSql(postgresConnectionString!);
+ ef.UsePostgreSql(postgresConnectionString);
+ else if (sqlDatabaseProvider == SqlDatabaseProvider.Citus)
+ ef.UsePostgreSql(citusConnectionString);
+ else if (sqlDatabaseProvider == SqlDatabaseProvider.YugabyteDb)
+ ef.UsePostgreSql(yugabyteDbConnectionString, configure: dbContextOptions => dbContextOptions.With());
#if !NET9_0
else if (sqlDatabaseProvider == SqlDatabaseProvider.MySql)
ef.UseMySql(mySqlConnectionString);
#endif
else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb)
- ef.UsePostgreSql(cockroachDbConnectionString!);
+ ef.UsePostgreSql(cockroachDbConnectionString);
else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle)
ef.UseOracle(oracleConnectionString, new()
{ SchemaName = "ELSA"});
@@ -248,15 +254,19 @@ services
management.UseEntityFrameworkCore(ef =>
{
if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer)
- ef.UseSqlServer(sqlServerConnectionString!);
+ ef.UseSqlServer(sqlServerConnectionString);
else if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql)
- ef.UsePostgreSql(postgresConnectionString!);
+ ef.UsePostgreSql(postgresConnectionString);
+ else if (sqlDatabaseProvider == SqlDatabaseProvider.Citus)
+ ef.UsePostgreSql(citusConnectionString);
+ else if (sqlDatabaseProvider == SqlDatabaseProvider.YugabyteDb)
+ ef.UsePostgreSql(yugabyteDbConnectionString);
#if !NET9_0
else if (sqlDatabaseProvider == SqlDatabaseProvider.MySql)
ef.UseMySql(mySqlConnectionString);
#endif
else if (sqlDatabaseProvider == SqlDatabaseProvider.CockroachDb)
- ef.UsePostgreSql(cockroachDbConnectionString!);
+ ef.UsePostgreSql(cockroachDbConnectionString);
else if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle)
ef.UseOracle(oracleConnectionString, new()
{ SchemaName = "ELSA"});
@@ -299,7 +309,11 @@ services
ef.DbContextOptionsBuilder = (_, db) => db.UseElsaSqlServer(migrationsAssembly, connectionString, null, configure => configure.CommandTimeout(60000));
}
else if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql)
- ef.UsePostgreSql(postgresConnectionString!);
+ ef.UsePostgreSql(postgresConnectionString);
+ else if (sqlDatabaseProvider == SqlDatabaseProvider.Citus)
+ ef.UsePostgreSql(citusConnectionString);
+ else if (sqlDatabaseProvider == SqlDatabaseProvider.YugabyteDb)
+ ef.UsePostgreSql(yugabyteDbConnectionString);
#if !NET9_0
else if (sqlDatabaseProvider == SqlDatabaseProvider.MySql)
ef.UseMySql(mySqlConnectionString);
@@ -448,6 +462,10 @@ services
ef.UseSqlServer(sqlServerConnectionString);
else if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql)
ef.UsePostgreSql(postgresConnectionString);
+ else if (sqlDatabaseProvider == SqlDatabaseProvider.Citus)
+ ef.UsePostgreSql(citusConnectionString);
+ else if (sqlDatabaseProvider == SqlDatabaseProvider.YugabyteDb)
+ ef.UsePostgreSql(yugabyteDbConnectionString);
#if !NET9_0
else if (sqlDatabaseProvider == SqlDatabaseProvider.MySql)
ef.UseMySql(mySqlConnectionString);
@@ -540,7 +558,7 @@ services
proto.PersistenceProvider = _ =>
{
if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer)
- return new SqlServerProvider(sqlServerConnectionString!, true, "", "proto_actor");
+ return new SqlServerProvider(sqlServerConnectionString, true, "", "proto_actor");
return new SqliteProvider(new(sqliteConnectionString));
};
@@ -641,6 +659,8 @@ services
if (sqlDatabaseProvider == SqlDatabaseProvider.Sqlite) ef.UseSqlite(sqliteConnectionString);
if (sqlDatabaseProvider == SqlDatabaseProvider.SqlServer) ef.UseSqlServer(sqlServerConnectionString);
if (sqlDatabaseProvider == SqlDatabaseProvider.PostgreSql) ef.UsePostgreSql(postgresConnectionString);
+ if (sqlDatabaseProvider == SqlDatabaseProvider.Citus) ef.UsePostgreSql(citusConnectionString);
+ if (sqlDatabaseProvider == SqlDatabaseProvider.YugabyteDb) ef.UsePostgreSql(yugabyteDbConnectionString);
if (sqlDatabaseProvider == SqlDatabaseProvider.Oracle) ef.UseOracle(oracleConnectionString, new()
{ SchemaName = "ELSA"});
#if !NET9_0
diff --git a/src/apps/Elsa.Server.Web/appsettings.json b/src/apps/Elsa.Server.Web/appsettings.json
index e361f3077..9010bf944 100644
--- a/src/apps/Elsa.Server.Web/appsettings.json
+++ b/src/apps/Elsa.Server.Web/appsettings.json
@@ -15,6 +15,8 @@
"Sqlite": "Data Source=App_Data/elsa.sqlite.db;Cache=Shared;",
"MySql": "Server=localhost;Database=elsa;Uid=admin;Pwd=password;",
"PostgreSql": "Server=localhost;Username=elsa;Database=elsa;Port=5432;Password=elsa;SSLMode=Prefer;MaxPoolSize=2000;Timeout=60",
+ "Citus": "Server=localhost;Username=citus;Database=citus;Port=9700;Password=citus;SSLMode=Prefer;MaxPoolSize=2000;Timeout=60",
+ "YugabyteDb": "Host=localhost;Port=5433;Database=elsa;Username=yugabyte;Password=yugabyte;Pooling=true",
"Oracle": "Data Source=(DESCRIPTION = (ADDRESS_LIST = (FAILOVER =ON) (LOAD_BALANCE = OFF) (ADDRESS = (PROTOCOL =TCP)(HOST=localhost)(PORT=1521))) (CONNECT_DATA = (SID= FREE) ));User Id=ELSA;Password=elsa;",
"CockroachDb": "Host=localhost;Port=26257;Database=elsa;SslMode=Disable;Username=root;IncludeErrorDetail=true",
"MongoDb": "mongodb://localhost:27017/elsa-workflows",