Skip to content

Commit

Permalink
feat: 将静态内容调整为embed嵌入,减少外部依赖文件 (opsre#325)
Browse files Browse the repository at this point in the history
* feat: 将静态内容调整为embed嵌入,减少外部依赖文件
  • Loading branch information
eryajf authored Apr 4, 2024
1 parent 114a7c3 commit 103d765
Show file tree
Hide file tree
Showing 27 changed files with 179 additions and 176 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tmp
logs
public/static/dist
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: build
name: build and push binary to release

on:
release:
Expand All @@ -16,11 +16,13 @@ jobs:
goos: windows
steps:
- uses: actions/checkout@v3
- 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
- uses: wangyoucao577/go-release-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }} # 一个默认的变量,用来实现往 Release 中添加文件
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
goversion: 1.18 # 可以指定编译使用的 Golang 版本
binary_name: "go-ldap-admin" # 可以指定二进制文件的名称
extra_files: LICENSE config.yml go-ldap-admin-priv.pem go-ldap-admin-pub.pem rbac_model.conf README.md # 需要包含的额外文件
extra_files: LICENSE config.yml README.md # 需要包含的额外文件
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@ jobs:
with:
go-version: 1.18
- uses: actions/checkout@v3
- 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
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.47.3
version: v1.57.2
args: --timeout=5m --skip-files="public/client/feishu/feishu.go"
build:
name: go-build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- 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
- name: Set up Go
uses: actions/setup-go@v3
with:
Expand Down
File renamed without changes.
File renamed without changes.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ go-ldap-admin.db
# Dependency directories (remove the comment below to include it)
# vendor/
tmp
docs/docker-compose/data
docs/docker-compose/data
dist
36 changes: 13 additions & 23 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,39 +1,29 @@
FROM golang:1.18.10-alpine3.16 AS builder
FROM registry.cn-hangzhou.aliyuncs.com/ali_eryajf/golang:1.18.10-alpine3.17 AS builder

# ENV GOPROXY https://goproxy.io
WORKDIR /app

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

ADD . /app/
ADD . .

WORKDIR /app
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

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

### build final image
FROM alpine:3.16

# we set the timezone `Asia/Shanghai` by default, you can be modified
# by `docker build --build-arg="TZ=Other_Timezone ..."`
ARG TZ="Asia/Shanghai"
FROM registry.cn-hangzhou.aliyuncs.com/ali_eryajf/alpine:3.19

ENV TZ ${TZ}

RUN mkdir /app
LABEL maintainer [email protected]

WORKDIR /app

COPY --from=builder /app/ .


RUN apk upgrade \
&& apk add bash tzdata sqlite vim \
&& ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone
COPY --from=builder /app/wait .
COPY --from=builder /app/LICENSE .
COPY --from=builder /app/config.yml .
COPY --from=builder /app/go-ldap-admin .

RUN chmod +x wait go-ldap-admin

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

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

# casbin配置
casbin:
# 模型配置文件, config.yml相对路径
model-path: 'rbac_model.conf'

# jwt配置
jwt:
# jwt标识
Expand Down
51 changes: 19 additions & 32 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
_ "embed"
"fmt"
"os"

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

//go:embed go-ldap-admin-priv.pem
var priv []byte

//go:embed go-ldap-admin-pub.pem
var pub []byte

type config struct {
System *SystemConfig `mapstructure:"system" json:"system"`
Logs *LogsConfig `mapstructure:"logs" json:"logs"`
Database *Database `mapstructure:"database" json:"database"`
Mysql *MysqlConfig `mapstructure:"mysql" json:"mysql"`
Casbin *CasbinConfig `mapstructure:"casbin" json:"casbin"`
System *SystemConfig `mapstructure:"system" json:"system"`
Logs *LogsConfig `mapstructure:"logs" json:"logs"`
Database *Database `mapstructure:"database" json:"database"`
Mysql *MysqlConfig `mapstructure:"mysql" json:"mysql"`
// Casbin *CasbinConfig `mapstructure:"casbin" json:"casbin"`
Jwt *JwtConfig `mapstructure:"jwt" json:"jwt"`
RateLimit *RateLimitConfig `mapstructure:"rate-limit" json:"rateLimit"`
Ldap *LdapConfig `mapstructure:"ldap" json:"ldap"`
Expand Down Expand Up @@ -50,8 +57,8 @@ func InitConfig() {
panic(fmt.Errorf("初始化配置文件失败:%s", err))
}
// 读取rsa key
Conf.System.RSAPublicBytes = RSAReadKeyFromFile(Conf.System.RSAPublicKey)
Conf.System.RSAPrivateBytes = RSAReadKeyFromFile(Conf.System.RSAPrivateKey)
Conf.System.RSAPublicBytes = pub
Conf.System.RSAPrivateBytes = priv
})

if err != nil {
Expand All @@ -62,36 +69,16 @@ func InitConfig() {
panic(fmt.Errorf("初始化配置文件失败:%s", err))
}
// 读取rsa key
Conf.System.RSAPublicBytes = RSAReadKeyFromFile(Conf.System.RSAPublicKey)
Conf.System.RSAPrivateBytes = RSAReadKeyFromFile(Conf.System.RSAPrivateKey)

}

// 从文件中读取RSA key
func RSAReadKeyFromFile(filename string) []byte {
f, err := os.Open(filename)
var b []byte
Conf.System.RSAPublicBytes = pub
Conf.System.RSAPrivateBytes = priv

if err != nil {
return b
}
defer f.Close()
fileInfo, _ := f.Stat()
b = make([]byte, fileInfo.Size())
_, err = f.Read(b)
if err != nil {
return b
}
return b
}

type SystemConfig struct {
Mode string `mapstructure:"mode" json:"mode"`
UrlPathPrefix string `mapstructure:"url-path-prefix" json:"urlPathPrefix"`
Port int `mapstructure:"port" json:"port"`
InitData bool `mapstructure:"init-data" json:"initData"`
RSAPublicKey string `mapstructure:"rsa-public-key" json:"rsaPublicKey"`
RSAPrivateKey string `mapstructure:"rsa-private-key" json:"rsaPrivateKey"`
RSAPublicBytes []byte `mapstructure:"-" json:"-"`
RSAPrivateBytes []byte `mapstructure:"-" json:"-"`
}
Expand Down Expand Up @@ -123,9 +110,9 @@ type MysqlConfig struct {
Collation string `mapstructure:"collation" json:"collation"`
}

type CasbinConfig struct {
ModelPath string `mapstructure:"model-path" json:"modelPath"`
}
// type CasbinConfig struct {
// ModelPath string `mapstructure:"model-path" json:"modelPath"`
// }

type JwtConfig struct {
Realm string `mapstructure:"realm" json:"realm"`
Expand Down
File renamed without changes.
File renamed without changes.
17 changes: 0 additions & 17 deletions docs/docker-compose/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ services:
hostname: go-ldap-admin-server
restart: always
environment:
TZ: Asia/Shanghai
WAIT_HOSTS: mysql:3306, openldap:389
ports:
- 8888:8888
Expand All @@ -86,19 +85,3 @@ services:
- openldap:go-ldap-admin-openldap # ldap容器的 service_name:container_name
networks:
- go-ldap-admin

go-ldap-admin-ui:
image: registry.cn-hangzhou.aliyuncs.com/ali_eryajf/go-ldap-admin-ui
container_name: go-ldap-admin-ui
hostname: go-ldap-admin-ui
restart: always
environment:
TZ: Asia/Shanghai
ports:
- 8090:80
depends_on:
- go-ldap-admin-server
links:
- go-ldap-admin-server:go-ldap-admin-server
networks:
- go-ldap-admin
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func main() {
// 启动定时任务
logic.InitCron()

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

// Wait for interrupt signal to gracefully shutdown the server with
// a timeout of 5 seconds.
Expand Down
91 changes: 91 additions & 0 deletions middleware/EmbedMiddleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package middleware

import (
"embed"
"io/fs"
"net/http"
"os"
"path"
"strings"

"github.com/gin-gonic/gin"
)

const INDEX = "index.html"

type ServeFileSystem interface {
http.FileSystem
Exists(prefix string, path string) bool
}

type localFileSystem struct {
http.FileSystem
root string
indexes bool
}

func LocalFile(root string, indexes bool) *localFileSystem {
return &localFileSystem{
FileSystem: gin.Dir(root, indexes),
root: root,
indexes: indexes,
}
}

func (l *localFileSystem) Exists(prefix string, filepath string) bool {
if p := strings.TrimPrefix(filepath, prefix); len(p) < len(filepath) {
name := path.Join(l.root, p)
stats, err := os.Stat(name)
if err != nil {
return false
}
if stats.IsDir() {
if !l.indexes {
index := path.Join(name, INDEX)
_, err := os.Stat(index)
if err != nil {
return false
}
}
}
return true
}
return false
}

func ServeRoot(urlPrefix, root string) gin.HandlerFunc {
return Serve(urlPrefix, LocalFile(root, false))
}

// Static returns a middleware handler that serves static files in the given directory.
func Serve(urlPrefix string, fs ServeFileSystem) gin.HandlerFunc {
fileserver := http.FileServer(fs)
if urlPrefix != "" {
fileserver = http.StripPrefix(urlPrefix, fileserver)
}
return func(c *gin.Context) {
if fs.Exists(urlPrefix, c.Request.URL.Path) {
fileserver.ServeHTTP(c.Writer, c.Request)
c.Abort()
}
}
}

type embedFileSystem struct {
http.FileSystem
}

func (e embedFileSystem) Exists(prefix string, path string) bool {
_, err := e.Open(path)
return err == nil
}

func EmbedFolder(fsEmbed embed.FS, targetPath string) ServeFileSystem {
fsys, err := fs.Sub(fsEmbed, targetPath)
if err != nil {
panic(err)
}
return embedFileSystem{
FileSystem: http.FS(fsys),
}
}
Loading

0 comments on commit 103d765

Please sign in to comment.