Skip to content

Commit 103d765

Browse files
authored
feat: 将静态内容调整为embed嵌入,减少外部依赖文件 (#325)
* feat: 将静态内容调整为embed嵌入,减少外部依赖文件
1 parent 114a7c3 commit 103d765

27 files changed

+179
-176
lines changed

.dockerignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
tmp
2+
logs
3+
public/static/dist

.github/workflows/go-binary-release.yml renamed to .github/workflows/buildAndPush-binary-to-release.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: build
1+
name: build and push binary to release
22

33
on:
44
release:
@@ -16,11 +16,13 @@ jobs:
1616
goos: windows
1717
steps:
1818
- uses: actions/checkout@v3
19+
- run: |
20+
release_url=$(curl -s https://api.github.com/repos/eryajf/go-ldap-admin-ui/releases/latest | grep "browser_download_url" | grep -v 'dist.zip.md5' | cut -d '"' -f 4); wget $release_url && unzip dist.zip && rm dist.zip && mv dist public/static
1921
- uses: wangyoucao577/go-release-action@v1
2022
with:
2123
github_token: ${{ secrets.GITHUB_TOKEN }} # 一个默认的变量,用来实现往 Release 中添加文件
2224
goos: ${{ matrix.goos }}
2325
goarch: ${{ matrix.goarch }}
2426
goversion: 1.18 # 可以指定编译使用的 Golang 版本
2527
binary_name: "go-ldap-admin" # 可以指定二进制文件的名称
26-
extra_files: LICENSE config.yml go-ldap-admin-priv.pem go-ldap-admin-pub.pem rbac_model.conf README.md # 需要包含的额外文件
28+
extra_files: LICENSE config.yml README.md # 需要包含的额外文件
File renamed without changes.

.github/workflows/go-ci.yml renamed to .github/workflows/go-ci-check.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,20 @@ jobs:
1111
with:
1212
go-version: 1.18
1313
- uses: actions/checkout@v3
14+
- run: |
15+
release_url=$(curl -s https://api.github.com/repos/eryajf/go-ldap-admin-ui/releases/latest | grep "browser_download_url" | grep -v 'dist.zip.md5' | cut -d '"' -f 4); wget $release_url && unzip dist.zip && rm dist.zip && mv dist public/static
1416
- name: golangci-lint
1517
uses: golangci/golangci-lint-action@v3
1618
with:
17-
version: v1.47.3
19+
version: v1.57.2
1820
args: --timeout=5m --skip-files="public/client/feishu/feishu.go"
1921
build:
2022
name: go-build
2123
runs-on: ubuntu-latest
2224
steps:
2325
- uses: actions/checkout@v3
26+
- run: |
27+
release_url=$(curl -s https://api.github.com/repos/eryajf/go-ldap-admin-ui/releases/latest | grep "browser_download_url" | grep -v 'dist.zip.md5' | cut -d '"' -f 4); wget $release_url && unzip dist.zip && rm dist.zip && mv dist public/static
2428
- name: Set up Go
2529
uses: actions/setup-go@v3
2630
with:
File renamed without changes.
File renamed without changes.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ go-ldap-admin.db
2323
# Dependency directories (remove the comment below to include it)
2424
# vendor/
2525
tmp
26-
docs/docker-compose/data
26+
docs/docker-compose/data
27+
dist

Dockerfile

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,29 @@
1-
FROM golang:1.18.10-alpine3.16 AS builder
1+
FROM registry.cn-hangzhou.aliyuncs.com/ali_eryajf/golang:1.18.10-alpine3.17 AS builder
22

3-
# ENV GOPROXY https://goproxy.io
3+
WORKDIR /app
44

5-
RUN mkdir /app && apk add --no-cache --virtual .build-deps \
6-
ca-certificates \
7-
gcc \
8-
g++
5+
RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories \
6+
&& apk upgrade && apk add --no-cache --virtual .build-deps \
7+
ca-certificates gcc g++ curl
98

10-
ADD . /app/
9+
ADD . .
1110

12-
WORKDIR /app
11+
RUN release_url=$(curl -s https://api.github.com/repos/eryajf/go-ldap-admin-ui/releases/latest | grep "browser_download_url" | grep -v 'dist.zip.md5' | cut -d '"' -f 4); wget $release_url && unzip dist.zip && rm dist.zip && mv dist public/static
1312

1413
RUN sed -i 's@localhost:389@openldap:389@g' /app/config.yml \
1514
&& sed -i 's@host: localhost@host: mysql@g' /app/config.yml && go build -o go-ldap-admin .
1615

1716
### build final image
18-
FROM alpine:3.16
19-
20-
# we set the timezone `Asia/Shanghai` by default, you can be modified
21-
# by `docker build --build-arg="TZ=Other_Timezone ..."`
22-
ARG TZ="Asia/Shanghai"
17+
FROM registry.cn-hangzhou.aliyuncs.com/ali_eryajf/alpine:3.19
2318

24-
ENV TZ ${TZ}
25-
26-
RUN mkdir /app
19+
LABEL maintainer [email protected]
2720

2821
WORKDIR /app
2922

30-
COPY --from=builder /app/ .
31-
32-
33-
RUN apk upgrade \
34-
&& apk add bash tzdata sqlite vim \
35-
&& ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \
36-
&& echo ${TZ} > /etc/timezone
23+
COPY --from=builder /app/wait .
24+
COPY --from=builder /app/LICENSE .
25+
COPY --from=builder /app/config.yml .
26+
COPY --from=builder /app/go-ldap-admin .
3727

3828
RUN chmod +x wait go-ldap-admin
3929

config.yml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ system:
88
port: 8888
99
# 是否初始化数据(没有初始数据时使用, 已发布正式版改为false)
1010
init-data: true
11-
# rsa公钥文件路径(config.yml相对路径, 也可以填绝对路径)
12-
rsa-public-key: go-ldap-admin-pub.pem
13-
# rsa私钥文件路径(config.yml相对路径, 也可以填绝对路径)
14-
rsa-private-key: go-ldap-admin-priv.pem
1511

1612
logs:
1713
# 日志等级(-1:Debug, 0:Info, 1:Warn, 2:Error, 3:DPanic, 4:Panic, 5:Fatal, -1<=level<=5, 参照zap.level源码)
@@ -55,11 +51,6 @@ mysql:
5551
# 字符集(utf8mb4_general_ci速度比utf8mb4_unicode_ci快些)
5652
collation: utf8mb4_general_ci
5753

58-
# casbin配置
59-
casbin:
60-
# 模型配置文件, config.yml相对路径
61-
model-path: 'rbac_model.conf'
62-
6354
# jwt配置
6455
jwt:
6556
# jwt标识

config/config.go

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package config
22

33
import (
4+
_ "embed"
45
"fmt"
56
"os"
67

@@ -15,12 +16,18 @@ import (
1516
// 全局配置变量
1617
var Conf = new(config)
1718

19+
//go:embed go-ldap-admin-priv.pem
20+
var priv []byte
21+
22+
//go:embed go-ldap-admin-pub.pem
23+
var pub []byte
24+
1825
type config struct {
19-
System *SystemConfig `mapstructure:"system" json:"system"`
20-
Logs *LogsConfig `mapstructure:"logs" json:"logs"`
21-
Database *Database `mapstructure:"database" json:"database"`
22-
Mysql *MysqlConfig `mapstructure:"mysql" json:"mysql"`
23-
Casbin *CasbinConfig `mapstructure:"casbin" json:"casbin"`
26+
System *SystemConfig `mapstructure:"system" json:"system"`
27+
Logs *LogsConfig `mapstructure:"logs" json:"logs"`
28+
Database *Database `mapstructure:"database" json:"database"`
29+
Mysql *MysqlConfig `mapstructure:"mysql" json:"mysql"`
30+
// Casbin *CasbinConfig `mapstructure:"casbin" json:"casbin"`
2431
Jwt *JwtConfig `mapstructure:"jwt" json:"jwt"`
2532
RateLimit *RateLimitConfig `mapstructure:"rate-limit" json:"rateLimit"`
2633
Ldap *LdapConfig `mapstructure:"ldap" json:"ldap"`
@@ -50,8 +57,8 @@ func InitConfig() {
5057
panic(fmt.Errorf("初始化配置文件失败:%s", err))
5158
}
5259
// 读取rsa key
53-
Conf.System.RSAPublicBytes = RSAReadKeyFromFile(Conf.System.RSAPublicKey)
54-
Conf.System.RSAPrivateBytes = RSAReadKeyFromFile(Conf.System.RSAPrivateKey)
60+
Conf.System.RSAPublicBytes = pub
61+
Conf.System.RSAPrivateBytes = priv
5562
})
5663

5764
if err != nil {
@@ -62,36 +69,16 @@ func InitConfig() {
6269
panic(fmt.Errorf("初始化配置文件失败:%s", err))
6370
}
6471
// 读取rsa key
65-
Conf.System.RSAPublicBytes = RSAReadKeyFromFile(Conf.System.RSAPublicKey)
66-
Conf.System.RSAPrivateBytes = RSAReadKeyFromFile(Conf.System.RSAPrivateKey)
67-
68-
}
69-
70-
// 从文件中读取RSA key
71-
func RSAReadKeyFromFile(filename string) []byte {
72-
f, err := os.Open(filename)
73-
var b []byte
72+
Conf.System.RSAPublicBytes = pub
73+
Conf.System.RSAPrivateBytes = priv
7474

75-
if err != nil {
76-
return b
77-
}
78-
defer f.Close()
79-
fileInfo, _ := f.Stat()
80-
b = make([]byte, fileInfo.Size())
81-
_, err = f.Read(b)
82-
if err != nil {
83-
return b
84-
}
85-
return b
8675
}
8776

8877
type SystemConfig struct {
8978
Mode string `mapstructure:"mode" json:"mode"`
9079
UrlPathPrefix string `mapstructure:"url-path-prefix" json:"urlPathPrefix"`
9180
Port int `mapstructure:"port" json:"port"`
9281
InitData bool `mapstructure:"init-data" json:"initData"`
93-
RSAPublicKey string `mapstructure:"rsa-public-key" json:"rsaPublicKey"`
94-
RSAPrivateKey string `mapstructure:"rsa-private-key" json:"rsaPrivateKey"`
9582
RSAPublicBytes []byte `mapstructure:"-" json:"-"`
9683
RSAPrivateBytes []byte `mapstructure:"-" json:"-"`
9784
}
@@ -123,9 +110,9 @@ type MysqlConfig struct {
123110
Collation string `mapstructure:"collation" json:"collation"`
124111
}
125112

126-
type CasbinConfig struct {
127-
ModelPath string `mapstructure:"model-path" json:"modelPath"`
128-
}
113+
// type CasbinConfig struct {
114+
// ModelPath string `mapstructure:"model-path" json:"modelPath"`
115+
// }
129116

130117
type JwtConfig struct {
131118
Realm string `mapstructure:"realm" json:"realm"`
File renamed without changes.
File renamed without changes.

docs/docker-compose/docker-compose.yaml

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ services:
7272
hostname: go-ldap-admin-server
7373
restart: always
7474
environment:
75-
TZ: Asia/Shanghai
7675
WAIT_HOSTS: mysql:3306, openldap:389
7776
ports:
7877
- 8888:8888
@@ -86,19 +85,3 @@ services:
8685
- openldap:go-ldap-admin-openldap # ldap容器的 service_name:container_name
8786
networks:
8887
- go-ldap-admin
89-
90-
go-ldap-admin-ui:
91-
image: registry.cn-hangzhou.aliyuncs.com/ali_eryajf/go-ldap-admin-ui
92-
container_name: go-ldap-admin-ui
93-
hostname: go-ldap-admin-ui
94-
restart: always
95-
environment:
96-
TZ: Asia/Shanghai
97-
ports:
98-
- 8090:80
99-
depends_on:
100-
- go-ldap-admin-server
101-
links:
102-
- go-ldap-admin-server:go-ldap-admin-server
103-
networks:
104-
- go-ldap-admin

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func main() {
6868
// 启动定时任务
6969
logic.InitCron()
7070

71-
common.Log.Info(fmt.Sprintf("Server is running at %s:%d/%s", host, port, config.Conf.System.UrlPathPrefix))
71+
common.Log.Info(fmt.Sprintf("Server is running at http://%s:%d", host, port))
7272

7373
// Wait for interrupt signal to gracefully shutdown the server with
7474
// a timeout of 5 seconds.

middleware/EmbedMiddleware.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package middleware
2+
3+
import (
4+
"embed"
5+
"io/fs"
6+
"net/http"
7+
"os"
8+
"path"
9+
"strings"
10+
11+
"github.com/gin-gonic/gin"
12+
)
13+
14+
const INDEX = "index.html"
15+
16+
type ServeFileSystem interface {
17+
http.FileSystem
18+
Exists(prefix string, path string) bool
19+
}
20+
21+
type localFileSystem struct {
22+
http.FileSystem
23+
root string
24+
indexes bool
25+
}
26+
27+
func LocalFile(root string, indexes bool) *localFileSystem {
28+
return &localFileSystem{
29+
FileSystem: gin.Dir(root, indexes),
30+
root: root,
31+
indexes: indexes,
32+
}
33+
}
34+
35+
func (l *localFileSystem) Exists(prefix string, filepath string) bool {
36+
if p := strings.TrimPrefix(filepath, prefix); len(p) < len(filepath) {
37+
name := path.Join(l.root, p)
38+
stats, err := os.Stat(name)
39+
if err != nil {
40+
return false
41+
}
42+
if stats.IsDir() {
43+
if !l.indexes {
44+
index := path.Join(name, INDEX)
45+
_, err := os.Stat(index)
46+
if err != nil {
47+
return false
48+
}
49+
}
50+
}
51+
return true
52+
}
53+
return false
54+
}
55+
56+
func ServeRoot(urlPrefix, root string) gin.HandlerFunc {
57+
return Serve(urlPrefix, LocalFile(root, false))
58+
}
59+
60+
// Static returns a middleware handler that serves static files in the given directory.
61+
func Serve(urlPrefix string, fs ServeFileSystem) gin.HandlerFunc {
62+
fileserver := http.FileServer(fs)
63+
if urlPrefix != "" {
64+
fileserver = http.StripPrefix(urlPrefix, fileserver)
65+
}
66+
return func(c *gin.Context) {
67+
if fs.Exists(urlPrefix, c.Request.URL.Path) {
68+
fileserver.ServeHTTP(c.Writer, c.Request)
69+
c.Abort()
70+
}
71+
}
72+
}
73+
74+
type embedFileSystem struct {
75+
http.FileSystem
76+
}
77+
78+
func (e embedFileSystem) Exists(prefix string, path string) bool {
79+
_, err := e.Open(path)
80+
return err == nil
81+
}
82+
83+
func EmbedFolder(fsEmbed embed.FS, targetPath string) ServeFileSystem {
84+
fsys, err := fs.Sub(fsEmbed, targetPath)
85+
if err != nil {
86+
panic(err)
87+
}
88+
return embedFileSystem{
89+
FileSystem: http.FS(fsys),
90+
}
91+
}

0 commit comments

Comments
 (0)