diff --git a/README.md b/README.md
index cea92a58..d4f04b11 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,18 @@ curl -L https://raw.githubusercontent.com/OpenCSGs/csghub-server/main/docker-com
docker-compose -f docker-compose.yml up -d
```
+## Start CSGHub Server Services Locally
+
+CSGHub supports TOML format for config files. When starting any service from the command line, you can specify the config file with the `--config` option:
+
+```
+go run cmd/csghub-server/main.go start server --config local.toml
+go run cmd/csghub-server/main.go deploy runner --config local.toml
+...
+```
+
+We provide an [example config file](common/config/config.toml.example), you can rename it, modify as needed and use. All available configurations are defined in [this Go file](common/config/config.go). The TOML configuration uses snake_case naming convention, and names automatically map to corresponding struct field names.
+
## Technical Architecture
diff --git a/builder/git/gitserver/gitea/client.go b/builder/git/gitserver/gitea/client.go
index 9e62672f..af348d68 100644
--- a/builder/git/gitserver/gitea/client.go
+++ b/builder/git/gitserver/gitea/client.go
@@ -38,7 +38,7 @@ type TokenResponse struct {
func NewClient(config *config.Config) (client *Client, err error) {
httpClient := &http.Client{
- Timeout: time.Duration(config.GitServer.TimtoutSEC) * time.Second,
+ Timeout: time.Duration(config.GitServer.TimeoutSEC) * time.Second,
}
token, err := findOrCreateAccessToken(context.Background(), config)
if err != nil {
diff --git a/common/config/README.md b/common/config/README.md
new file mode 100644
index 00000000..37717ea7
--- /dev/null
+++ b/common/config/README.md
@@ -0,0 +1,22 @@
+CSGHub server supports two configuration methods: using environment variables or configuration files. You can also combine them, for example, by placing non-sensitive configurations in a config file and overriding sensitive configurations with environment variables.
+
+### Using a Config File
+
+CSGHub supports TOML format for config files. When starting any service from the command line, you can specify the config file with the `--config` option:
+
+```
+go run cmd/csghub-server/main.go start server --config local.toml
+go run cmd/csghub-server/main.go deploy runner --config local.toml
+```
+
+We provide an [example config file](common/config/config.toml.example), you can rename it, modify as needed and use. All available configurations are defined in [this Go file](common/config/config.go). The TOML configuration uses snake_case naming convention, and names automatically map to corresponding struct field names.
+
+If a config value is missing in the config file, the `default` tag value specified in the Go struct file will be used.
+
+### Using Environment Variables
+
+CSGHub also supports configuration through environment variables. The relevant environment variable names are defined in [this Go file](common/config/config.go) under the `env` tag. If an environment variable is absent, the value in the `default` tag will be used.
+
+### Combining Config File with Environment Variables
+
+You can use config file together with environment variables. When both are used, environment variables take **higher priority** than the config file. For example, if you have a `Port` setting, and you specify it in the TOML file as `port=1234` and in an environment variable as `export PORT=5678`, the environment variable value (5678) will be used for the port configuration.
diff --git a/common/config/config.go b/common/config/config.go
index a0096fdb..9f684c2d 100644
--- a/common/config/config.go
+++ b/common/config/config.go
@@ -1,216 +1,242 @@
package config
-import "github.com/kelseyhightower/envconfig"
+import (
+ "context"
+ "os"
+
+ "github.com/naoina/toml"
+ "github.com/sethvargo/go-envconfig"
+)
+
+var configFile = ""
type Config struct {
- Saas bool `envconfig:"STARHUB_SERVER_SAAS" default:"false"`
- InstanceID string `envconfig:"STARHUB_SERVER_INSTANCE_ID"`
- EnableSwagger bool `envconfig:"STARHUB_SERVER_ENABLE_SWAGGER" default:"false"`
- APIToken string `envconfig:"STARHUB_SERVER_API_TOKEN" default:"0c11e6e4f2054444374ba3f0b70de4145935a7312289d404814cd5907c6aa93cc65cd35dbf94e04c13a3dedbf51f1694de84240c8acb7238b54a2c3ac8e87c59"`
+ Saas bool `env:"STARHUB_SERVER_SAAS, default=false"`
+ InstanceID string `env:"STARHUB_SERVER_INSTANCE_ID"`
+ EnableSwagger bool `env:"STARHUB_SERVER_ENABLE_SWAGGER, default=false"`
+ APIToken string `env:"STARHUB_SERVER_API_TOKEN, default=0c11e6e4f2054444374ba3f0b70de4145935a7312289d404814cd5907c6aa93cc65cd35dbf94e04c13a3dedbf51f1694de84240c8acb7238b54a2c3ac8e87c59"`
// enable if you want to acess csghub through https, especially for space rproxy
- EnableHTTPS bool `envconfig:"STARHUB_SERVER_ENABLE_HTTPS" default:"false"`
+ EnableHTTPS bool `env:"STARHUB_SERVER_ENABLE_HTTPS, default=false"`
APIServer struct {
- Port int `envconfig:"STARHUB_SERVER_SERVER_PORT" default:"8080"`
- PublicDomain string `envconfig:"STARHUB_SERVER_PUBLIC_DOMAIN" default:"http://localhost:8080"`
- SSHDomain string `envconfig:"STARHUB_SERVER_SSH_DOMAIN" default:"ssh://git@localhost:2222"`
+ Port int `env:"STARHUB_SERVER_SERVER_PORT, default=8080"`
+ PublicDomain string `env:"STARHUB_SERVER_PUBLIC_DOMAIN, default=http://localhost:8080"`
+ SSHDomain string `env:"STARHUB_SERVER_SSH_DOMAIN, default=git@localhost:2222"`
}
Mirror struct {
- URL string `envconfig:"STARHUB_SERVER_MIRROR_URL" default:"http://localhost:8085"`
- Token string `envconfig:"STARHUB_SERVER_MIRROR_Token" default:""`
- Port int `envconfig:"STARHUB_SERVER_MIRROR_PORT" default:"8085"`
- SessionSecretKey string `envconfig:"STARHUB_SERVER_MIRROR_SESSION_SECRET_KEY" default:"mirror"`
- WorkerNumber int `envconfig:"STARHUB_SERVER_MIRROR_WORKER_NUMBER" default:"5"`
+ URL string `env:"STARHUB_SERVER_MIRROR_URL, default=http://localhost:8085"`
+ Token string `env:"STARHUB_SERVER_MIRROR_Token, default="`
+ Port int `env:"STARHUB_SERVER_MIRROR_PORT, default=8085"`
+ SessionSecretKey string `env:"STARHUB_SERVER_MIRROR_SESSION_SECRET_KEY, default=mirror"`
+ WorkerNumber int `env:"STARHUB_SERVER_MIRROR_WORKER_NUMBER, default=5"`
}
- DocsHost string `envconfig:"STARHUB_SERVER_SERVER_DOCS_HOST" default:"http://localhost:6636"`
+ DocsHost string `env:"STARHUB_SERVER_SERVER_DOCS_HOST, default=http://localhost:6636"`
Database struct {
- Driver string `envconfig:"STARHUB_DATABASE_DRIVER" default:"pg"`
- DSN string `envconfig:"STARHUB_DATABASE_DSN" default:"postgresql://postgres:postgres@localhost:5432/starhub_server?sslmode=disable"`
- TimeZone string `envconfig:"STARHUB_DATABASE_TIMEZONE" default:"Asia/Shanghai"`
+ Driver string `env:"STARHUB_DATABASE_DRIVER, default=pg"`
+ DSN string `env:"STARHUB_DATABASE_DSN, default=postgresql://postgres:postgres@localhost:5432/starhub_server?sslmode=disable"`
+ TimeZone string `env:"STARHUB_DATABASE_TIMEZONE, default=Asia/Shanghai"`
}
Redis struct {
- Endpoint string `envconfig:"STARHUB_SERVER_REDIS_ENDPOINT" default:"localhost:6379"`
- MaxRetries int `envconfig:"STARHUB_SERVER_REDIS_MAX_RETRIES" default:"3"`
- MinIdleConnections int `envconfig:"STARHUB_SERVER_REDIS_MIN_IDLE_CONNECTIONS" default:"0"`
- User string `envconfig:"STARHUB_SERVER_REDIS_USER"`
- Password string `envconfig:"STARHUB_SERVER_REDIS_PASSWORD"`
- SentinelMode bool `envconfig:"STARHUB_SERVER_REDIS_USE_SENTINEL" default:"false"`
- SentinelMaster string `envconfig:"STARHUB_SERVER_REDIS_SENTINEL_MASTER"`
- SentinelEndpoint string `envconfig:"STARHUB_SERVER_REDIS_SENTINEL_ENDPOINT"`
+ Endpoint string `env:"STARHUB_SERVER_REDIS_ENDPOINT, default=localhost:6379"`
+ MaxRetries int `env:"STARHUB_SERVER_REDIS_MAX_RETRIES, default=3"`
+ MinIdleConnections int `env:"STARHUB_SERVER_REDIS_MIN_IDLE_CONNECTIONS, default=0"`
+ User string `env:"STARHUB_SERVER_REDIS_USER"`
+ Password string `env:"STARHUB_SERVER_REDIS_PASSWORD"`
+ SentinelMode bool `env:"STARHUB_SERVER_REDIS_USE_SENTINEL, default=false"`
+ SentinelMaster string `env:"STARHUB_SERVER_REDIS_SENTINEL_MASTER"`
+ SentinelEndpoint string `env:"STARHUB_SERVER_REDIS_SENTINEL_ENDPOINT"`
}
GitServer struct {
- URL string `envconfig:"STARHUB_SERVER_GITSERVER_URL" default:"http://localhost:3000"`
- Type string `envconfig:"STARHUB_SERVER_GITSERVER_TYPE" default:"gitea"`
- Host string `envconfig:"STARHUB_SERVER_GITSERVER_HOST" default:"http://localhost:3000"`
- SecretKey string `envconfig:"STARHUB_SERVER_GITSERVER_SECRET_KEY" default:"619c849c49e03754454ccd4cda79a209ce0b30b3"`
- Username string `envconfig:"STARHUB_SERVER_GITSERVER_USERNAME" default:"root"`
- Password string `envconfig:"STARHUB_SERVER_GITSERVER_PASSWORD" default:"password123"`
- TimtoutSEC int `envconfig:"STARHUB_SERVER_GITSERVER_TIMEOUT_SEC" default:"5"`
+ URL string `env:"STARHUB_SERVER_GITSERVER_URL, default=http://localhost:3000"`
+ Type string `env:"STARHUB_SERVER_GITSERVER_TYPE, default=gitea"`
+ Host string `env:"STARHUB_SERVER_GITSERVER_HOST, default=http://localhost:3000"`
+ SecretKey string `env:"STARHUB_SERVER_GITSERVER_SECRET_KEY, default=619c849c49e03754454ccd4cda79a209ce0b30b3"`
+ Username string `env:"STARHUB_SERVER_GITSERVER_USERNAME, default=root"`
+ Password string `env:"STARHUB_SERVER_GITSERVER_PASSWORD, default=password123"`
+ TimeoutSEC int `env:"STARHUB_SERVER_GITSERVER_TIMEOUT_SEC, default=5"`
}
GitalyServer struct {
- Address string `envconfig:"STARHUB_SERVER_GITALY_SERVER_SOCKET" default:"tcp://localhost:9999"`
- Storge string `envconfig:"STARHUB_SERVER_GITALY_STORGE" default:"default"`
- Token string `envconfig:"STARHUB_SERVER_GITALY_TOKEN" default:"abc123secret"`
- JWTSecret string `envconfig:"STARHUB_SERVER_GITALY_JWT_SECRET" default:"signing-key"`
+ Address string `env:"STARHUB_SERVER_GITALY_SERVER_SOCKET, default=tcp://localhost:9999"`
+ Storge string `env:"STARHUB_SERVER_GITALY_STORGE, default=default"`
+ Token string `env:"STARHUB_SERVER_GITALY_TOKEN, default=abc123secret"`
+ JWTSecret string `env:"STARHUB_SERVER_GITALY_JWT_SECRET, default=signing-key"`
}
MirrorServer struct {
- Enable bool `envconfig:"STARHUB_SERVER_MIRRORSERVER_ENABLE" default:"true"`
- URL string `envconfig:"STARHUB_SERVER_MIRRORSERVER_URL" default:"http://localhost:3001"`
- Type string `envconfig:"STARHUB_SERVER_MIRRORSERVER_TYPE" default:"gitea"`
- Host string `envconfig:"STARHUB_SERVER_MIRRORSERVER_HOST" default:"http://localhost:3001"`
- SecretKey string `envconfig:"STARHUB_SERVER_MIRRORSERVER_SECRET_KEY" default:"619c849c49e03754454ccd4cda79a209ce0b30b3"`
- Username string `envconfig:"STARHUB_SERVER_MIRRORSERVER_USERNAME" default:"root"`
- Password string `envconfig:"STARHUB_SERVER_MIRRORSERVER_PASSWORD" default:"password123"`
+ Enable bool `env:"STARHUB_SERVER_MIRRORSERVER_ENABLE, default=true"`
+ URL string `env:"STARHUB_SERVER_MIRRORSERVER_URL, default=http://localhost:3001"`
+ Type string `env:"STARHUB_SERVER_MIRRORSERVER_TYPE, default=gitea"`
+ Host string `env:"STARHUB_SERVER_MIRRORSERVER_HOST, default=http://localhost:3001"`
+ SecretKey string `env:"STARHUB_SERVER_MIRRORSERVER_SECRET_KEY, default=619c849c49e03754454ccd4cda79a209ce0b30b3"`
+ Username string `env:"STARHUB_SERVER_MIRRORSERVER_USERNAME, default=root"`
+ Password string `env:"STARHUB_SERVER_MIRRORSERVER_PASSWORD, default=password123"`
}
Frontend struct {
- URL string `envconfig:"STARHUB_SERVER_FRONTEND_URL" default:"https://opencsg.com"`
+ URL string `env:"STARHUB_SERVER_FRONTEND_URL, default=https://opencsg.com"`
}
S3 struct {
- SSL bool `envconfig:"STARHUB_SERVER_S3_SSL" default:"false"`
- AccessKeyID string `envconfig:"STARHUB_SERVER_S3_ACCESS_KEY_ID"`
- AccessKeySecret string `envconfig:"STARHUB_SERVER_S3_ACCESS_KEY_SECRET"`
- Region string `envconfig:"STARHUB_SERVER_S3_REGION"`
- Endpoint string `envconfig:"STARHUB_SERVER_S3_ENDPOINT" default:"localhost:9000"`
+ SSL bool `env:"STARHUB_SERVER_S3_SSL, default=false"`
+ AccessKeyID string `env:"STARHUB_SERVER_S3_ACCESS_KEY_ID"`
+ AccessKeySecret string `env:"STARHUB_SERVER_S3_ACCESS_KEY_SECRET"`
+ Region string `env:"STARHUB_SERVER_S3_REGION"`
+ Endpoint string `env:"STARHUB_SERVER_S3_ENDPOINT, default=localhost:9000"`
//for better performance of LFS downloading from s3. (can ignore if S3.Endpoint is alreay an internal domain or ip address)
- InternalEndpoint string `envconfig:"STARHUB_SERVER_S3_INTERNAL_ENDPOINT" default:""`
- Bucket string `envconfig:"STARHUB_SERVER_S3_BUCKET" default:"opencsg-test"`
- EnableSSL bool `envconfig:"STARHUB_SERVER_S3_ENABLE_SSL" default:"false"`
+ InternalEndpoint string `env:"STARHUB_SERVER_S3_INTERNAL_ENDPOINT, default="`
+ Bucket string `env:"STARHUB_SERVER_S3_BUCKET, default=opencsg-test"`
+ EnableSSL bool `env:"STARHUB_SERVER_S3_ENABLE_SSL, default=false"`
}
SensitiveCheck struct {
- Enable bool `envconfig:"STARHUB_SERVER_SENSITIVE_CHECK_ENABLE" default:"false"`
- AccessKeyID string `envconfig:"STARHUB_SERVER_SENSITIVE_CHECK_ACCESS_KEY_ID"`
- AccessKeySecret string `envconfig:"STARHUB_SERVER_SENSITIVE_CHECK_ACCESS_KEY_SECRET"`
- Region string `envconfig:"STARHUB_SERVER_SENSITIVE_CHECK_REGION"`
- Endpoint string `envconfig:"STARHUB_SERVER_SENSITIVE_CHECK_ENDPOINT" default:"oss-cn-beijing.aliyuncs.com"`
- EnableSSL bool `envconfig:"STARHUB_SERVER_S3_ENABLE_SSH" default:"true"`
+ Enable bool `env:"STARHUB_SERVER_SENSITIVE_CHECK_ENABLE, default=false"`
+ AccessKeyID string `env:"STARHUB_SERVER_SENSITIVE_CHECK_ACCESS_KEY_ID"`
+ AccessKeySecret string `env:"STARHUB_SERVER_SENSITIVE_CHECK_ACCESS_KEY_SECRET"`
+ Region string `env:"STARHUB_SERVER_SENSITIVE_CHECK_REGION"`
+ Endpoint string `env:"STARHUB_SERVER_SENSITIVE_CHECK_ENDPOINT, default=oss-cn-beijing.aliyuncs.com"`
+ EnableSSL bool `env:"STARHUB_SERVER_S3_ENABLE_SSH, default=true"`
}
JWT struct {
- SigningKey string `envconfig:"STARHUB_JWT_SIGNING_KEY" default:"signing-key"`
- ValidHour int `envconfig:"STARHUB_JWT_VALIDATE_HOUR" default:"24"`
+ SigningKey string `env:"STARHUB_JWT_SIGNING_KEY, default=signing-key"`
+ ValidHour int `env:"STARHUB_JWT_VALIDATE_HOUR, default=24"`
}
Inference struct {
- ServerAddr string `envconfig:"STARHUB_SERVER_INFERENCE_SERVER_ADDR" default:"http://localhost:8000"`
+ ServerAddr string `env:"STARHUB_SERVER_INFERENCE_SERVER_ADDR, default=http://localhost:8000"`
}
Space struct {
- BuilderEndpoint string `envconfig:"STARHUB_SERVER_SPACE_BUILDER_ENDPOINT" default:"http://localhost:8081"`
+ BuilderEndpoint string `env:"STARHUB_SERVER_SPACE_BUILDER_ENDPOINT, default=http://localhost:8081"`
// base url for space api running in k8s cluster
- RunnerEndpoint string `envconfig:"STARHUB_SERVER_SPACE_RUNNER_ENDPOINT" default:"http://localhost:8082"`
- RunnerServerPort int `envconfig:"STARHUB_SERVER_SPACE_RUNNER_SERVER_PORT" default:"8082"`
+ RunnerEndpoint string `env:"STARHUB_SERVER_SPACE_RUNNER_ENDPOINT, default=http://localhost:8082"`
+ RunnerServerPort int `env:"STARHUB_SERVER_SPACE_RUNNER_SERVER_PORT, default=8082"`
// the internal root domain will be proxied to, should be internal access only
- InternalRootDomain string `envconfig:"STARHUB_SERVER_INTERNAL_ROOT_DOMAIN" default:"internal.example.com"`
+ InternalRootDomain string `env:"STARHUB_SERVER_INTERNAL_ROOT_DOMAIN, default=internal.example.com"`
// the public root domain will be proxied from
- PublicRootDomain string `envconfig:"STARHUB_SERVER_PUBLIC_ROOT_DOMAIN" default:"public.example.com"`
- DockerRegBase string `envconfig:"STARHUB_SERVER_DOCKER_REG_BASE" default:"registry.cn-beijing.aliyuncs.com/opencsg_public/"`
- ImagePullSecret string `envconfig:"STARHUB_SERVER_DOCKER_IMAGE_PULL_SECRET" default:"opencsg-pull-secret"`
+ PublicRootDomain string `env:"STARHUB_SERVER_PUBLIC_ROOT_DOMAIN, default=public.example.com"`
+ DockerRegBase string `env:"STARHUB_SERVER_DOCKER_REG_BASE, default=registry.cn-beijing.aliyuncs.com/opencsg_public/"`
+ ImagePullSecret string `env:"STARHUB_SERVER_DOCKER_IMAGE_PULL_SECRET, default=opencsg-pull-secret"`
// reverse proxy listening port
- RProxyServerPort int `envconfig:"STARHUB_SERVER_SPACE_RPROXY_SERVER_PORT" default:"8083"`
+ RProxyServerPort int `env:"STARHUB_SERVER_SPACE_RPROXY_SERVER_PORT, default=8083"`
// secret key for session encryption
- SessionSecretKey string `envconfig:"STARHUB_SERVER_SPACE_SESSION_SECRET_KEY" default:"secret"`
- DeployTimeoutInMin int `envconfig:"STARHUB_SERVER_SPACE_DEPLOY_TIMEOUT_IN_MINUTES" default:"30"`
+ SessionSecretKey string `env:"STARHUB_SERVER_SPACE_SESSION_SECRET_KEY, default=secret"`
+ DeployTimeoutInMin int `env:"STARHUB_SERVER_SPACE_DEPLOY_TIMEOUT_IN_MINUTES, default=30"`
// gpu model label
- GPUModelLabel string `envconfig:"STARHUB_SERVER_GPU_MODEL_LABEL" default:"aliyun.accelerator/nvidia_name"`
- ReadnessDelaySeconds int `envconfig:"STARHUB_SERVER_READNESS_DELAY_SECONDS" default:"120"`
- ReadnessPeriodSeconds int `envconfig:"STARHUB_SERVER_READNESS_PERIOD_SECONDS" default:"10"`
- ReadnessFailureThreshold int `envconfig:"STARHUB_SERVER_READNESS_FAILURE_THRESHOLD" default:"3"`
+ GPUModelLabel string `env:"STARHUB_SERVER_GPU_MODEL_LABEL, default=aliyun.accelerator/nvidia_name"`
+ ReadnessDelaySeconds int `env:"STARHUB_SERVER_READNESS_DELAY_SECONDS, default=120"`
+ ReadnessPeriodSeconds int `env:"STARHUB_SERVER_READNESS_PERIOD_SECONDS, default=10"`
+ ReadnessFailureThreshold int `env:"STARHUB_SERVER_READNESS_FAILURE_THRESHOLD, default=3"`
}
Model struct {
- DeployTimeoutInMin int `envconfig:"STARHUB_SERVER_MODEL_DEPLOY_TIMEOUT_IN_MINUTES" default:"60"`
- DownloadEndpoint string `envconfig:"STARHUB_SERVER_MODEL_DOWNLOAD_ENDPOINT" default:"https://hub.opencsg.com"`
- DockerRegBase string `envconfig:"STARHUB_SERVER_MODEL_DOCKER_REG_BASE" default:"opencsg-registry.cn-beijing.cr.aliyuncs.com/public/"`
- NimDockerSecretName string `envconfig:"STARHUB_SERVER_MODEL_NIM_DOCKER_SECRET_NAME" default:"ngc-secret"`
- NimNGCSecretName string `envconfig:"STARHUB_SERVER_MODEL_NIM_NGC_SECRET_NAME" default:"nvidia-nim-secrets"`
+ DeployTimeoutInMin int `env:"STARHUB_SERVER_MODEL_DEPLOY_TIMEOUT_IN_MINUTES, default=60"`
+ DownloadEndpoint string `env:"STARHUB_SERVER_MODEL_DOWNLOAD_ENDPOINT, default=https://hub.opencsg.com"`
+ DockerRegBase string `env:"STARHUB_SERVER_MODEL_DOCKER_REG_BASE, default=opencsg-registry.cn-beijing.cr.aliyuncs.com/public/"`
+ NimDockerSecretName string `env:"STARHUB_SERVER_MODEL_NIM_DOCKER_SECRET_NAME, default=ngc-secret"`
+ NimNGCSecretName string `env:"STARHUB_SERVER_MODEL_NIM_NGC_SECRET_NAME, default=nvidia-nim-secrets"`
}
// send events
Event struct {
- SyncInterval int `envconfig:"STARHUB_SERVER_SYNC_IN_MINUTES" default:"1"`
+ SyncInterval int `env:"STARHUB_SERVER_SYNC_IN_MINUTES, default=1"`
}
Casdoor struct {
- ClientID string `envconfig:"STARHUB_SERVER_CASDOOR_CLIENT_ID" default:"client_id"`
- ClientSecret string `envconfig:"STARHUB_SERVER_CASDOOR_CLIENT_SECRET" default:"client_secret"`
- Endpoint string `envconfig:"STARHUB_SERVER_CASDOOR_ENDPOINT" default:"http://localhost:80"`
- Certificate string `envconfig:"STARHUB_SERVER_CASDOOR_CERTIFICATE" default:"/etc/casdoor/certificate.pem"`
- OrganizationName string `envconfig:"STARHUB_SERVER_CASDOOR_ORGANIZATION_NAME" default:"opencsg"`
- ApplicationName string `envconfig:"STARHUB_SERVER_CASDOOR_APPLICATION_NAME" default:"opencsg"`
+ ClientID string `env:"STARHUB_SERVER_CASDOOR_CLIENT_ID, default=client_id"`
+ ClientSecret string `env:"STARHUB_SERVER_CASDOOR_CLIENT_SECRET, default=client_secret"`
+ Endpoint string `env:"STARHUB_SERVER_CASDOOR_ENDPOINT, default=http://localhost:80"`
+ Certificate string `env:"STARHUB_SERVER_CASDOOR_CERTIFICATE, default=/etc/casdoor/certificate.pem"`
+ OrganizationName string `env:"STARHUB_SERVER_CASDOOR_ORGANIZATION_NAME, default=opencsg"`
+ ApplicationName string `env:"STARHUB_SERVER_CASDOOR_APPLICATION_NAME, default=opencsg"`
}
Nats struct {
- URL string `envconfig:"OPENCSG_ACCOUNTING_NATS_URL" default:"nats://account:g98dc5FA8v4J7ck90w@natsmaster:4222"`
- MsgFetchTimeoutInSEC int `envconfig:"OPENCSG_ACCOUNTING_MSG_FETCH_TIMEOUTINSEC" default:"5"`
- MeterRequestSubject string `envconfig:"OPENCSG_ACCOUNTING_METER_EVENT_SUBJECT" default:"accounting.metering.>"`
- MeterDurationSendSubject string `envconfig:"STARHUB_SERVER_METER_DURATION_SEND_SUBJECT" default:"accounting.metering.duration"`
- MeterTokenSendSubject string `envconfig:"STARHUB_SERVER_METER_TOKEN_SEND_SUBJECT" default:"accounting.metering.token"`
- MeterQuotaSendSubject string `envconfig:"STARHUB_SERVER_METER_QUOTA_SEND_SUBJECT" default:"accounting.metering.quota"`
+ URL string `env:"OPENCSG_ACCOUNTING_NATS_URL, default=nats://account:g98dc5FA8v4J7ck90w@natsmaster:4222"`
+ MsgFetchTimeoutInSEC int `env:"OPENCSG_ACCOUNTING_MSG_FETCH_TIMEOUTINSEC, default=5"`
+ MeterRequestSubject string `env:"OPENCSG_ACCOUNTING_METER_EVENT_SUBJECT, default=accounting.metering.>"`
+ MeterDurationSendSubject string `env:"STARHUB_SERVER_METER_DURATION_SEND_SUBJECT, default=accounting.metering.duration"`
+ MeterTokenSendSubject string `env:"STARHUB_SERVER_METER_TOKEN_SEND_SUBJECT, default=accounting.metering.token"`
+ MeterQuotaSendSubject string `env:"STARHUB_SERVER_METER_QUOTA_SEND_SUBJECT, default=accounting.metering.quota"`
}
Accounting struct {
- Host string `envconfig:"OPENCSG_ACCOUNTING_SERVER_HOST" default:"http://localhost"`
- Port int `envconfig:"OPENCSG_ACCOUNTING_SERVER_PORT" default:"8086"`
+ Host string `env:"OPENCSG_ACCOUNTING_SERVER_HOST, default=http://localhost"`
+ Port int `env:"OPENCSG_ACCOUNTING_SERVER_PORT, default=8086"`
}
User struct {
- Host string `envconfig:"OPENCSG_USER_SERVER_HOST" default:"http://localhost"`
- Port int `envconfig:"OPENCSG_USER_SERVER_PORT" default:"8088"`
- SigninSuccessRedirectURL string `envconfig:"OPENCSG_USER_SERVER_SIGNIN_SUCCESS_REDIRECT_URL" default:"http://localhost:3000/server/callback"`
+ Host string `env:"OPENCSG_USER_SERVER_HOST, default=http://localhost"`
+ Port int `env:"OPENCSG_USER_SERVER_PORT, default=8088"`
+ SigninSuccessRedirectURL string `env:"OPENCSG_USER_SERVER_SIGNIN_SUCCESS_REDIRECT_URL, default=http://localhost:3000/server/callback"`
}
MultiSync struct {
- SaasAPIDomain string `envconfig:"OPENCSG_SAAS_API_DOMAIN" default:"https://hub.opencsg.com"`
- SaasSyncDomain string `envconfig:"OPENCSG_SAAS_SYNC_DOMAIN" default:"https://sync.opencsg.com"`
- Enabled bool `envconfig:"STARHUB_SERVER_MULTI_SYNC_ENABLED" default:"true"`
+ SaasAPIDomain string `env:"OPENCSG_SAAS_API_DOMAIN, default=https://hub.opencsg.com"`
+ SaasSyncDomain string `env:"OPENCSG_SAAS_SYNC_DOMAIN, default=https://sync.opencsg.com"`
+ Enabled bool `env:"STARHUB_SERVER_MULTI_SYNC_ENABLED, default=true"`
}
Telemetry struct {
- Enable bool `envconfig:"STARHUB_SERVER_TELEMETRY_ENABLE" default:"true"`
- ReportURL string `envconfig:"STARHUB_SERVER_TELEMETRY_URL" default:"http://hub.opencsg.com/api/v1/telemetry"`
+ Enable bool `env:"STARHUB_SERVER_TELEMETRY_ENABLE, default=true"`
+ ReportURL string `env:"STARHUB_SERVER_TELEMETRY_URL, default=http://hub.opencsg.com/api/v1/telemetry"`
}
AutoClean struct {
- Instance bool `envconfig:"OPENCSG_AUTO_CLEANUP_INSTANCE_ENABLE" default:"false"`
+ Instance bool `env:"OPENCSG_AUTO_CLEANUP_INSTANCE_ENABLE, default=false"`
}
Dataset struct {
- PromptMaxJsonlFileSize int64 `envconfig:"OPENCSG_PROMPT_MAX_JSONL_FILESIZE_BYTES" default:"1048576"` // 1MB
+ PromptMaxJsonlFileSize int64 `env:"OPENCSG_PROMPT_MAX_JSONL_FILESIZE_BYTES, default=1048576"` // 1MB
}
Dataflow struct {
- Host string `envconfig:"OPENCSG_DATAFLOW_SERVER_HOST" default:"http://127.0.0.1"`
- Port int `envconfig:"OPENCSG_DATAFLOW_SERVER_PORT" default:"8000"`
+ Host string `env:"OPENCSG_DATAFLOW_SERVER_HOST, default=http://127.0.0.1"`
+ Port int `env:"OPENCSG_DATAFLOW_SERVER_PORT, default=8000"`
}
Moderation struct {
- Host string `envconfig:"OPENCSG_MODERATION_SERVER_HOST" default:"http://localhost"`
- Port int `envconfig:"OPENCSG_MODERATION_SERVER_PORT" default:"8089"`
+ Host string `env:"OPENCSG_MODERATION_SERVER_HOST, default=http://localhost"`
+ Port int `env:"OPENCSG_MODERATION_SERVER_PORT, default=8089"`
// comma splitted, and base64 encoded
- EncodedSensitiveWords string `envconfig:"OPENCSG_MODERATION_SERVER_ENCODED_SENSITIVE_WORDS" default:"5Lmg6L+R5bmzLHhpamlucGluZw=="`
+ EncodedSensitiveWords string `env:"OPENCSG_MODERATION_SERVER_ENCODED_SENSITIVE_WORDS, default=5Lmg6L+R5bmzLHhpamlucGluZw=="`
}
WorkFLow struct {
- Endpoint string `envconfig:"OPENCSG_WORKFLOW_SERVER_ENDPOINT" default:"localhost:7233"`
+ Endpoint string `env:"OPENCSG_WORKFLOW_SERVER_ENDPOINT, default=localhost:7233"`
}
}
-func LoadConfig() (cfg *Config, err error) {
- cfg = new(Config)
- err = envconfig.Process("", cfg)
- if err != nil {
- return
- }
+func SetConfigFile(file string) {
+ configFile = file
+}
- return
+func LoadConfig() (*Config, error) {
+ cfg := &Config{}
+
+ if configFile != "" {
+ f, err := os.Open(configFile)
+ if err != nil {
+ return nil, err
+ }
+ err = toml.NewDecoder(f).Decode(cfg)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // Always read environment variables, even if a config file exists. If a config value is present in both the
+ // config file and the environment, the environment value takes priority. If a config value is missing from
+ // the config file, the default value (specified by the struct field's default tag) will be used.
+ err := envconfig.ProcessWith(context.Background(), &envconfig.Config{
+ Target: cfg,
+ DefaultOverwrite: true,
+ })
+ return cfg, err
}
diff --git a/common/config/config.toml.example b/common/config/config.toml.example
new file mode 100644
index 00000000..bdbba68a
--- /dev/null
+++ b/common/config/config.toml.example
@@ -0,0 +1,174 @@
+[saas]
+enabled = false
+
+[instance]
+id = ""
+
+[swagger]
+enabled = false
+
+[api]
+token = "0c11e6e4f2054444374ba3f0b70de4145935a7312289d404814cd5907c6aa93cc65cd35dbf94e04c13a3dedbf51f1694de84240c8acb7238b54a2c3ac8e87c59"
+
+[https]
+enabled = false
+
+[api_server]
+port = 8080
+public_domain = "http://localhost:8080"
+ssh_domain = "git@localhost:2222"
+
+[mirror]
+url = "http://localhost:8085"
+token = ""
+port = 8085
+session_secret_key = "mirror"
+worker_number = 5
+
+[docs_host]
+url = "http://localhost:6636"
+
+[database]
+driver = "pg"
+dsn = "postgresql://postgres:postgres@localhost:5432/starhub_server?sslmode=disable"
+timezone = "Asia/Shanghai"
+
+[redis]
+endpoint = "localhost:6379"
+max_retries = 3
+min_idle_connections = 0
+user = ""
+password = ""
+sentinel_mode = false
+sentinel_master = ""
+sentinel_endpoint = ""
+
+[git_server]
+url = "http://localhost:3000"
+type = "gitea"
+host = "http://localhost:3000"
+secret_key = "619c849c49e03754454ccd4cda79a209ce0b30b3"
+username = "root"
+password = "password123"
+timeout_sec = 5
+
+[gitaly_server]
+address = "tcp://localhost:9999"
+storage = "default"
+token = "abc123secret"
+jwt_secret = "signing-key"
+
+[mirror_server]
+enabled = true
+url = "http://localhost:3001"
+type = "gitea"
+host = "http://localhost:3001"
+secret_key = "619c849c49e03754454ccd4cda79a209ce0b30b3"
+username = "root"
+password = "password123"
+
+[frontend]
+url = "https://opencsg.com"
+
+[s3]
+ssl = false
+access_key_id = ""
+access_key_secret = ""
+region = ""
+endpoint = "localhost:9000"
+internal_endpoint = ""
+bucket = "opencsg-test"
+enable_ssl = false
+
+[sensitive_check]
+enabled = false
+access_key_id = ""
+access_key_secret = ""
+region = ""
+endpoint = "oss-cn-beijing.aliyuncs.com"
+enable_ssl = true
+
+[jwt]
+signing_key = "signing-key"
+valid_hour = 24
+
+[inference]
+server_addr = "http://localhost:8000"
+
+[space]
+builder_endpoint = "http://localhost:8081"
+runner_endpoint = "http://localhost:8082"
+runner_server_port = 8082
+internal_root_domain = "internal.example.com"
+public_root_domain = "public.example.com"
+docker_reg_base = "registry.cn-beijing.aliyuncs.com/opencsg_public/"
+image_pull_secret = "opencsg-pull-secret"
+rproxy_server_port = 8083
+session_secret_key = "secret"
+deploy_timeout_in_min = 30
+gpu_model_label = "aliyun.accelerator/nvidia_name"
+readiness_delay_seconds = 120
+readiness_period_seconds = 10
+readiness_failure_threshold = 3
+
+[model]
+deploy_timeout_in_min = 60
+download_endpoint = "https://hub.opencsg.com"
+docker_reg_base = "opencsg-registry.cn-beijing.cr.aliyuncs.com/public/"
+nim_docker_secret_name = "ngc-secret"
+nim_ngc_secret_name = "nvidia-nim-secrets"
+
+[event]
+sync_interval = 1
+
+[casdoor]
+client_id = "client_id"
+client_secret = "client_secret"
+endpoint = "http://localhost:80"
+certificate = "/etc/casdoor/certificate.pem"
+organization_name = "opencsg"
+application_name = "opencsg"
+
+[nats]
+url = "nats://account:g98dc5FA8v4J7ck90w@natsmaster:4222"
+msg_fetch_timeout_in_sec = 5
+meter_request_subject = "accounting.metering.>"
+meter_duration_send_subject = "accounting.metering.duration"
+meter_token_send_subject = "accounting.metering.token"
+meter_quota_send_subject = "accounting.metering.quota"
+
+[accounting]
+host = "http://localhost"
+port = 8086
+
+[user]
+host = "http://localhost"
+port = 8088
+signin_success_redirect_url = "http://localhost:3000/server/callback"
+
+[multi_sync]
+saas_api_domain = "https://hub.opencsg.com"
+saas_sync_domain = "https://sync.opencsg.com"
+enabled = true
+
+[telemetry]
+enabled = true
+report_url = "http://hub.opencsg.com/api/v1/telemetry"
+
+[auto_clean]
+instance = false
+
+[dataset]
+prompt_max_jsonl_file_size = 1048576
+
+[dataflow]
+host = "http://127.0.0.1"
+port = 8000
+
+[moderation]
+host = "http://localhost"
+port = 8089
+encoded_sensitive_words = "5Lmg6L+R5bmzLHhpamlucGluZw=="
+
+[workflow]
+endpoint = "localhost:7233"
diff --git a/common/config/config_test.go b/common/config/config_test.go
new file mode 100644
index 00000000..c72203a8
--- /dev/null
+++ b/common/config/config_test.go
@@ -0,0 +1,41 @@
+package config
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestConfig_LoadConfig(t *testing.T) {
+ t.Run("config env", func(t *testing.T) {
+ t.Setenv("STARHUB_SERVER_INSTANCE_ID", "foo")
+ t.Setenv("STARHUB_SERVER_SERVER_PORT", "6789")
+ cfg, err := LoadConfig()
+ require.Nil(t, err)
+
+ require.Equal(t, "foo", cfg.InstanceID)
+ require.Equal(t, 6789, cfg.APIServer.Port)
+ require.Equal(t, "git@localhost:2222", cfg.APIServer.SSHDomain)
+ })
+
+ t.Run("config file", func(t *testing.T) {
+ SetConfigFile("test.toml")
+ cfg, err := LoadConfig()
+ require.Nil(t, err)
+
+ require.Equal(t, "bar", cfg.InstanceID)
+ require.Equal(t, 4321, cfg.APIServer.Port)
+ require.Equal(t, "git@localhost:2222", cfg.APIServer.SSHDomain)
+ })
+
+ t.Run("file and env", func(t *testing.T) {
+ SetConfigFile("test.toml")
+ t.Setenv("STARHUB_SERVER_INSTANCE_ID", "foobar")
+ cfg, err := LoadConfig()
+ require.Nil(t, err)
+
+ require.Equal(t, "foobar", cfg.InstanceID)
+ require.Equal(t, 4321, cfg.APIServer.Port)
+ require.Equal(t, "git@localhost:2222", cfg.APIServer.SSHDomain)
+ })
+}
diff --git a/common/config/test.toml b/common/config/test.toml
new file mode 100644
index 00000000..8d2f2d57
--- /dev/null
+++ b/common/config/test.toml
@@ -0,0 +1,4 @@
+instance_id = "bar"
+
+[api_server]
+port = 4321
diff --git a/go.mod b/go.mod
index 1f1d2f85..1c035042 100644
--- a/go.mod
+++ b/go.mod
@@ -18,12 +18,14 @@ require (
github.com/gin-gonic/gin v1.9.1
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f
- github.com/kelseyhightower/envconfig v1.4.0
github.com/marcboeker/go-duckdb v1.5.6
github.com/minio/minio-go/v7 v7.0.66
github.com/minio/sha256-simd v1.0.1
+ github.com/naoina/toml v0.1.1
github.com/redis/go-redis/v9 v9.3.0
+ github.com/sethvargo/go-envconfig v1.1.0
github.com/spf13/cobra v1.8.0
+ github.com/stretchr/testify v1.9.0
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0
github.com/swaggo/swag v1.16.2
@@ -73,6 +75,7 @@ require (
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 // indirect
github.com/lightstep/lightstep-tracer-go v0.25.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
+ github.com/naoina/go-stringutil v0.1.0 // indirect
github.com/nats-io/nkeys v0.4.7 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/nexus-rpc/sdk-go v0.0.11 // indirect
@@ -90,7 +93,6 @@ require (
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a // indirect
github.com/shirou/gopsutil/v3 v3.21.12 // indirect
github.com/stretchr/objx v0.5.2 // indirect
- github.com/stretchr/testify v1.9.0 // indirect
github.com/tinylib/msgp v1.1.2 // indirect
github.com/tklauser/go-sysconf v0.3.9 // indirect
github.com/tklauser/numcpus v0.3.0 // indirect
diff --git a/go.sum b/go.sum
index 4aa0dc9c..8820611f 100644
--- a/go.sum
+++ b/go.sum
@@ -328,8 +328,6 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
-github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
-github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
@@ -348,6 +346,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
@@ -392,6 +392,10 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks=
+github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
+github.com/naoina/toml v0.1.1 h1:PT/lllxVVN0gzzSqSlHEmP8MJB4MY2U7STGxiouV4X8=
+github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
github.com/nats-io/nats.go v1.35.0 h1:XFNqNM7v5B+MQMKqVGAyHwYhyKb48jrenXNxIU20ULk=
github.com/nats-io/nats.go v1.35.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI=
@@ -470,6 +474,8 @@ github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a h1:iLcLb5Fwwz7g/DLK89F+uQBDeAhHhwdzB5fSlVdhGcM=
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0=
+github.com/sethvargo/go-envconfig v1.1.0 h1:cWZiJxeTm7AlCvzGXrEXaSTCNgip5oJepekh/BOQuog=
+github.com/sethvargo/go-envconfig v1.1.0/go.mod h1:JLd0KFWQYzyENqnEPWWZ49i4vzZo/6nRidxI8YvGiHw=
github.com/shirou/gopsutil/v3 v3.21.2/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
github.com/shirou/gopsutil/v3 v3.21.12 h1:VoGxEW2hpmz0Vt3wUvHIl9fquzYLNpVpgNNB7pGJimA=
github.com/shirou/gopsutil/v3 v3.21.12/go.mod h1:BToYZVTlSVlfazpDDYFnsVZLaoRG+g8ufT6fPQLdJzA=