Skip to content

Commit 1ac1d15

Browse files
authored
Merge pull request #376 from 0xJacky/docker/s6-overlay
Enhance nginx ui docker image
2 parents 8623e1e + e0366f9 commit 1ac1d15

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+5241
-5171
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
database.db
33
tmp
44
node_modules
5+
.pnpm-store
56
app.ini
67
dist
78
*.exe

Dockerfile

+21-10
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,28 @@ FROM --platform=$TARGETPLATFORM uozi/nginx-ui-base:latest
22
ARG TARGETOS
33
ARG TARGETARCH
44
ARG TARGETVARIANT
5-
WORKDIR /app
65
EXPOSE 80 443
76

8-
COPY resources/docker/start.sh /app/start.sh
9-
COPY resources/docker/nginx.conf /usr/etc/nginx/nginx.conf
10-
COPY resources/docker/nginx-ui.conf /usr/etc/nginx/conf.d/nginx-ui.conf
11-
COPY resources/docker/nginx-ui.conf /etc/nginx/conf.d/nginx-ui.conf
12-
COPY nginx-ui-$TARGETOS-$TARGETARCH$TARGETVARIANT/nginx-ui /app/nginx-ui
7+
ENV NGINX_UI_OFFICIAL_DOCKER=true
138

14-
RUN cd /app && chmod a+x /app/start.sh \
15-
&& rm -f /etc/nginx/conf.d/default.conf \
16-
&& rm -f /usr/etc/nginx/conf.d/default.conf
9+
# register nginx-ui service
10+
COPY resources/docker/nginx-ui.run /etc/s6-overlay/s6-rc.d/nginx-ui/run
11+
RUN echo 'longrun' > /etc/s6-overlay/s6-rc.d/nginx-ui/type && \
12+
touch /etc/s6-overlay/s6-rc.d/user/contents.d/nginx-ui
1713

18-
ENTRYPOINT ["./start.sh"]
14+
# copy nginx config
15+
COPY resources/docker/nginx.conf /usr/local/etc/nginx/nginx.conf
16+
COPY resources/docker/nginx-ui.conf /usr/local/etc/nginx/conf.d/nginx-ui.conf
17+
18+
# copy nginx-ui executable binary
19+
COPY nginx-ui-$TARGETOS-$TARGETARCH$TARGETVARIANT/nginx-ui /usr/local/bin/nginx-ui
20+
21+
# remove default nginx config
22+
RUN rm -f /etc/nginx/conf.d/default.conf \
23+
&& rm -f /usr/local/etc/nginx/conf.d/default.conf
24+
25+
# recreate access.log and error.log
26+
RUN rm -f /var/log/nginx/access.log && \
27+
touch /var/log/nginx/access.log && \
28+
rm -f /var/log/nginx/error.log && \
29+
touch /var/log/nginx/error.log

README-es.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ pnpm build
235235
Primero compile la interfaz y luego ejecute el siguiente comando en el directorio raíz del proyecto.
236236

237237
```shell
238-
go build -o nginx-ui -v main.go
238+
go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/settings.buildTime=$(date +%s)'" -o nginx-ui -v main.go
239239
```
240240

241241
## Script para Linux

README-vi_VN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ pnpm build
298298
Vui lòng build Frontend trước, sau đó thực hiện lệnh sau trong thư mục gốc của dự án.
299299

300300
```shell
301-
go build -o nginx-ui -v main.go
301+
go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/settings.buildTime=$(date +%s)'" -o nginx-ui -v main.go
302302
```
303303

304304
## Tập lệnh cho Linux

README-zh_CN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ pnpm build
229229
请先完成前端编译,再回到项目的根目录执行以下命令。
230230

231231
```shell
232-
go build -o nginx-ui -v main.go
232+
go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/settings.buildTime=$(date +%s)'" -o nginx-ui -v main.go
233233
```
234234

235235
## Linux 安装脚本

README-zh_TW.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ pnpm build
234234
請先完成前端編譯,再回到專案的根目錄執行以下命令。
235235

236236
```shell
237-
go build -o nginx-ui -v main.go
237+
go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/settings.buildTime=$(date +%s)'" -o nginx-ui -v main.go
238238
```
239239

240240
## Linux 安裝指令

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ pnpm build
295295
Please build the app first, and then execute the following command in the project root directory.
296296

297297
```shell
298-
go build -o nginx-ui -v main.go
298+
go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/settings.buildTime=$(date +%s)'" -o nginx-ui -v main.go
299299
```
300300

301301
## Script for Linux

api/cluster/environment.go

+37-85
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ package cluster
33
import (
44
"github.com/0xJacky/Nginx-UI/api"
55
"github.com/0xJacky/Nginx-UI/internal/analytic"
6-
"github.com/0xJacky/Nginx-UI/internal/environment"
6+
"github.com/0xJacky/Nginx-UI/internal/cluster"
7+
"github.com/0xJacky/Nginx-UI/internal/cosy"
78
"github.com/0xJacky/Nginx-UI/model"
89
"github.com/0xJacky/Nginx-UI/query"
10+
"github.com/0xJacky/Nginx-UI/settings"
911
"github.com/gin-gonic/gin"
1012
"github.com/spf13/cast"
1113
"net/http"
12-
"regexp"
1314
)
1415

1516
func GetEnvironment(c *gin.Context) {
@@ -27,117 +28,68 @@ func GetEnvironment(c *gin.Context) {
2728
}
2829

2930
func GetEnvironmentList(c *gin.Context) {
30-
data, err := environment.RetrieveEnvironmentList()
31-
if err != nil {
32-
api.ErrHandler(c, err)
33-
return
34-
}
35-
c.JSON(http.StatusOK, gin.H{
36-
"data": data,
37-
})
38-
}
39-
40-
type EnvironmentManageJson struct {
41-
Name string `json:"name" binding:"required"`
42-
URL string `json:"url" binding:"required"`
43-
Token string `json:"token" binding:"required"`
44-
OperationSync bool `json:"operation_sync"`
45-
SyncApiRegex string `json:"sync_api_regex"`
46-
}
47-
48-
func validateRegex(data EnvironmentManageJson) error {
49-
if data.OperationSync {
50-
_, err := regexp.Compile(data.SyncApiRegex)
51-
return err
52-
}
53-
return nil
31+
cosy.Core[model.Environment](c).
32+
SetFussy("name").
33+
SetEqual("enabled").
34+
SetTransformer(func(m *model.Environment) any {
35+
return analytic.GetNode(m)
36+
}).PagingList()
5437
}
5538

5639
func AddEnvironment(c *gin.Context) {
57-
var json EnvironmentManageJson
58-
if !api.BindAndValid(c, &json) {
59-
return
60-
}
61-
if err := validateRegex(json); err != nil {
62-
api.ErrHandler(c, err)
63-
return
64-
}
65-
66-
env := model.Environment{
67-
Name: json.Name,
68-
URL: json.URL,
69-
Token: json.Token,
70-
OperationSync: json.OperationSync,
71-
SyncApiRegex: json.SyncApiRegex,
72-
}
73-
74-
envQuery := query.Environment
75-
76-
err := envQuery.Create(&env)
77-
if err != nil {
78-
api.ErrHandler(c, err)
79-
return
80-
}
81-
82-
go analytic.RestartRetrieveNodesStatus()
83-
84-
c.JSON(http.StatusOK, env)
40+
cosy.Core[model.Environment](c).SetValidRules(gin.H{
41+
"name": "required",
42+
"url": "required,url",
43+
"token": "required",
44+
"enabled": "omitempty,boolean",
45+
}).ExecutedHook(func(c *cosy.Ctx[model.Environment]) {
46+
go analytic.RestartRetrieveNodesStatus()
47+
}).Create()
8548
}
8649

8750
func EditEnvironment(c *gin.Context) {
88-
id := cast.ToInt(c.Param("id"))
89-
90-
var json EnvironmentManageJson
91-
if !api.BindAndValid(c, &json) {
92-
return
93-
}
94-
if err := validateRegex(json); err != nil {
95-
api.ErrHandler(c, err)
96-
return
97-
}
51+
cosy.Core[model.Environment](c).SetValidRules(gin.H{
52+
"name": "required",
53+
"url": "required,url",
54+
"token": "required",
55+
"enabled": "omitempty,boolean",
56+
}).ExecutedHook(func(c *cosy.Ctx[model.Environment]) {
57+
go analytic.RestartRetrieveNodesStatus()
58+
}).Modify()
59+
}
9860

61+
func DeleteEnvironment(c *gin.Context) {
62+
id := cast.ToInt(c.Param("id"))
9963
envQuery := query.Environment
10064

10165
env, err := envQuery.FirstByID(id)
10266
if err != nil {
10367
api.ErrHandler(c, err)
10468
return
10569
}
106-
107-
_, err = envQuery.Where(envQuery.ID.Eq(env.ID)).Updates(&model.Environment{
108-
Name: json.Name,
109-
URL: json.URL,
110-
Token: json.Token,
111-
OperationSync: json.OperationSync,
112-
SyncApiRegex: json.SyncApiRegex,
113-
})
114-
70+
err = envQuery.DeleteByID(env.ID)
11571
if err != nil {
11672
api.ErrHandler(c, err)
11773
return
11874
}
11975

12076
go analytic.RestartRetrieveNodesStatus()
12177

122-
GetEnvironment(c)
78+
c.JSON(http.StatusNoContent, nil)
12379
}
12480

125-
func DeleteEnvironment(c *gin.Context) {
126-
id := cast.ToInt(c.Param("id"))
127-
envQuery := query.Environment
128-
129-
env, err := envQuery.FirstByID(id)
130-
if err != nil {
131-
api.ErrHandler(c, err)
132-
return
133-
}
134-
err = envQuery.DeleteByID(env.ID)
81+
func LoadEnvironmentFromSettings(c *gin.Context) {
82+
err := settings.ReloadCluster()
13583
if err != nil {
13684
api.ErrHandler(c, err)
13785
return
13886
}
13987

88+
cluster.RegisterPredefinedNodes()
89+
14090
go analytic.RestartRetrieveNodesStatus()
14191

142-
c.JSON(http.StatusNoContent, nil)
92+
c.JSON(http.StatusOK, gin.H{
93+
"message": "ok",
94+
})
14395
}

api/cluster/router.go

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import "github.com/gin-gonic/gin"
55
func InitRouter(r *gin.RouterGroup) {
66
// Environment
77
r.GET("environments", GetEnvironmentList)
8+
r.POST("environments/load_from_settings", LoadEnvironmentFromSettings)
89
envGroup := r.Group("environment")
910
{
1011
envGroup.GET("/:id", GetEnvironment)

api/nginx/control.go

+19-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"github.com/0xJacky/Nginx-UI/internal/nginx"
55
"github.com/gin-gonic/gin"
66
"net/http"
7+
"os"
78
)
89

910
func Reload(c *gin.Context) {
@@ -23,9 +24,24 @@ func Test(c *gin.Context) {
2324
}
2425

2526
func Restart(c *gin.Context) {
26-
output := nginx.Restart()
2727
c.JSON(http.StatusOK, gin.H{
28-
"message": output,
29-
"level": nginx.GetLogLevel(output),
28+
"message": "ok",
29+
})
30+
go nginx.Restart()
31+
}
32+
33+
func Status(c *gin.Context) {
34+
pidPath := nginx.GetPIDPath()
35+
lastOutput := nginx.GetLastOutput()
36+
37+
running := true
38+
if fileInfo, err := os.Stat(pidPath); err != nil || fileInfo.Size() == 0 { // fileInfo.Size() == 0 no process id
39+
running = false
40+
}
41+
42+
c.JSON(http.StatusOK, gin.H{
43+
"running": running,
44+
"message": lastOutput,
45+
"level": nginx.GetLogLevel(lastOutput),
3046
})
3147
}

0 commit comments

Comments
 (0)