diff --git a/backend/app/dto/container.go b/backend/app/dto/container.go
index 90a351768..936db57bd 100644
--- a/backend/app/dto/container.go
+++ b/backend/app/dto/container.go
@@ -116,7 +116,7 @@ type PortHelper struct {
type ContainerOperation struct {
Names []string `json:"names" validate:"required"`
- Operation string `json:"operation" validate:"required,oneof=start stop restart kill pause unpause remove"`
+ Operation string `json:"operation" validate:"required,oneof=up start stop restart kill pause unpause remove"`
}
type ContainerRename struct {
@@ -217,7 +217,7 @@ type ComposeCreate struct {
type ComposeOperation struct {
Name string `json:"name" validate:"required"`
Path string `json:"path" validate:"required"`
- Operation string `json:"operation" validate:"required,oneof=start stop down"`
+ Operation string `json:"operation" validate:"required,oneof=up start stop down"`
WithFile bool `json:"withFile"`
}
type ComposeUpdate struct {
diff --git a/backend/app/model/compose_template.go b/backend/app/model/compose_template.go
index 5d5192eb3..4db9b6286 100644
--- a/backend/app/model/compose_template.go
+++ b/backend/app/model/compose_template.go
@@ -12,4 +12,5 @@ type Compose struct {
BaseModel
Name string `gorm:"type:varchar(256)" json:"name"`
+ Path string `gorm:"type:varchar(256)" json:"path"`
}
diff --git a/backend/app/repo/compose_template.go b/backend/app/repo/compose_template.go
index 4259e2fb5..b6f38c24b 100644
--- a/backend/app/repo/compose_template.go
+++ b/backend/app/repo/compose_template.go
@@ -19,6 +19,7 @@ type IComposeTemplateRepo interface {
CreateRecord(compose *model.Compose) error
DeleteRecord(opts ...DBOption) error
ListRecord() ([]model.Compose, error)
+ UpdateRecord(name string, vars map[string]interface{}) error
}
func NewIComposeTemplateRepo() IComposeTemplateRepo {
@@ -102,3 +103,7 @@ func (u *ComposeTemplateRepo) DeleteRecord(opts ...DBOption) error {
}
return db.Delete(&model.Compose{}).Error
}
+
+func (u *ComposeTemplateRepo) UpdateRecord(name string, vars map[string]interface{}) error {
+ return global.DB.Model(&model.Compose{}).Where("name = ?", name).Updates(vars).Error
+}
diff --git a/backend/app/service/container.go b/backend/app/service/container.go
index bc97676a6..b7a3ab96b 100644
--- a/backend/app/service/container.go
+++ b/backend/app/service/container.go
@@ -898,6 +898,10 @@ func (u *ContainerService) LoadContainerLogs(req dto.OperationWithNameAndType) s
break
}
}
+ if len(containers) == 0 {
+ composeItem, _ := composeRepo.GetRecord(commonRepo.WithByName(req.Name))
+ filePath = composeItem.Path
+ }
}
if _, err := os.Stat(filePath); err != nil {
return ""
diff --git a/backend/app/service/container_compose.go b/backend/app/service/container_compose.go
index 565abf292..b98734a9d 100644
--- a/backend/app/service/container_compose.go
+++ b/backend/app/service/container_compose.go
@@ -52,6 +52,20 @@ func (u *ContainerService) PageCompose(req dto.SearchWithPage) (int64, interface
}
composeCreatedByLocal, _ := composeRepo.ListRecord()
+
+ composeLocalMap := make(map[string]dto.ComposeInfo)
+ for _, localItem := range composeCreatedByLocal {
+ composeItemLocal := dto.ComposeInfo{
+ ContainerNumber: 0,
+ CreatedAt: localItem.CreatedAt.Format(constant.DateTimeLayout),
+ ConfigFile: localItem.Path,
+ Workdir: strings.TrimSuffix(localItem.Path, "/docker-compose.yml"),
+ }
+ composeItemLocal.CreatedBy = "1Panel"
+ composeItemLocal.Path = localItem.Path
+ composeLocalMap[localItem.Name] = composeItemLocal
+ }
+
composeMap := make(map[string]dto.ComposeInfo)
for _, container := range list {
if name, ok := container.Labels[composeProjectLabel]; ok {
@@ -95,12 +109,24 @@ func (u *ContainerService) PageCompose(req dto.SearchWithPage) (int64, interface
}
}
}
- for _, item := range composeCreatedByLocal {
- if err := composeRepo.DeleteRecord(commonRepo.WithByID(item.ID)); err != nil {
- global.LOG.Error(err)
+
+ mergedMap := make(map[string]dto.ComposeInfo)
+ for key, localItem := range composeLocalMap {
+ mergedMap[key] = localItem
+ }
+ for key, item := range composeMap {
+ if existingItem, exists := mergedMap[key]; exists {
+ if item.ContainerNumber > 0 {
+ if existingItem.ContainerNumber <= 0 {
+ mergedMap[key] = item
+ }
+ }
+ } else {
+ mergedMap[key] = item
}
}
- for key, value := range composeMap {
+
+ for key, value := range mergedMap {
value.Name = key
records = append(records, value)
}
@@ -186,7 +212,7 @@ func (u *ContainerService) CreateCompose(req dto.ComposeCreate) (string, error)
return
}
global.LOG.Infof("docker-compose up %s successful!", req.Name)
- _ = composeRepo.CreateRecord(&model.Compose{Name: req.Name})
+ _ = composeRepo.CreateRecord(&model.Compose{Name: req.Name, Path: req.Path})
_, _ = file.WriteString("docker-compose up successful!")
}()
@@ -200,14 +226,27 @@ func (u *ContainerService) ComposeOperation(req dto.ComposeOperation) error {
if _, err := os.Stat(req.Path); err != nil {
return fmt.Errorf("load file with path %s failed, %v", req.Path, err)
}
- if stdout, err := compose.Operate(req.Path, req.Operation); err != nil {
- return errors.New(string(stdout))
+ if req.Operation == "up" {
+ if stdout, err := compose.Up(req.Path); err != nil {
+ return errors.New(string(stdout))
+ }
+ } else {
+ if stdout, err := compose.Operate(req.Path, req.Operation); err != nil {
+ return errors.New(string(stdout))
+ }
}
global.LOG.Infof("docker-compose %s %s successful", req.Operation, req.Name)
if req.Operation == "down" {
- _ = composeRepo.DeleteRecord(commonRepo.WithByName(req.Name))
if req.WithFile {
+ _ = composeRepo.DeleteRecord(commonRepo.WithByName(req.Name))
_ = os.RemoveAll(path.Dir(req.Path))
+ } else {
+ composeItem, _ := composeRepo.GetRecord(commonRepo.WithByName(req.Name))
+ if composeItem.Path == "" {
+ upMap := make(map[string]interface{})
+ upMap["path"] = req.Path
+ _ = composeRepo.UpdateRecord(req.Name, upMap)
+ }
}
}
diff --git a/backend/init/migration/migrate.go b/backend/init/migration/migrate.go
index a3df39427..faa3ce419 100644
--- a/backend/init/migration/migrate.go
+++ b/backend/init/migration/migrate.go
@@ -94,6 +94,7 @@ func Init() {
migrations.AddClam,
migrations.AddClamStatus,
migrations.AddAlertMenu,
+ migrations.AddComposeColumn,
})
if err := m.Migrate(); err != nil {
global.LOG.Error(err)
diff --git a/backend/init/migration/migrations/v_1_10.go b/backend/init/migration/migrations/v_1_10.go
index f2b5f1d34..2915606b1 100644
--- a/backend/init/migration/migrations/v_1_10.go
+++ b/backend/init/migration/migrations/v_1_10.go
@@ -314,3 +314,13 @@ var AddAlertMenu = &gormigrate.Migration{
return tx.Model(&model.Setting{}).Where("key", "XpackHideMenu").Updates(map[string]interface{}{"value": string(data)}).Error
},
}
+
+var AddComposeColumn = &gormigrate.Migration{
+ ID: "20240906-add-compose-command",
+ Migrate: func(tx *gorm.DB) error {
+ if err := tx.AutoMigrate(&model.Compose{}); err != nil {
+ return err
+ }
+ return nil
+ },
+}
diff --git a/frontend/src/views/container/compose/detail/index.vue b/frontend/src/views/container/compose/detail/index.vue
index 2b7364ca1..a102f247c 100644
--- a/frontend/src/views/container/compose/detail/index.vue
+++ b/frontend/src/views/container/compose/detail/index.vue
@@ -7,7 +7,7 @@