Compare commits
8
Commits
v0.1.2
..
a6d97b4a6f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6d97b4a6f | ||
|
|
53ece08ba8 | ||
|
|
9146c87cad | ||
|
|
b1b3ac5b6b | ||
|
|
a2635698e0 | ||
|
|
b3ff70167f | ||
|
|
7ec8cd5c0e | ||
|
|
fb96934abe |
+2
-1
@@ -1,2 +1,3 @@
|
|||||||
node_modules
|
frontend/node_modules
|
||||||
dist
|
dist
|
||||||
|
frontend/dist
|
||||||
+4
-1
@@ -27,9 +27,12 @@ COPY --from=backend-builder /app/ushare /usr/local/bin/ushare
|
|||||||
# 配置 Nginx
|
# 配置 Nginx
|
||||||
RUN rm /etc/nginx/conf.d/default.conf
|
RUN rm /etc/nginx/conf.d/default.conf
|
||||||
COPY deployment/nginx.conf /etc/nginx/conf.d
|
COPY deployment/nginx.conf /etc/nginx/conf.d
|
||||||
|
COPY deployment/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
|
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
# 开放端口
|
# 开放端口
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
# 启动服务
|
# 启动服务
|
||||||
CMD ["sh", "-c", "ushare & nginx -g 'daemon off;'"]
|
ENTRYPOINT ["entrypoint.sh"]
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 启动后端服务(带参数后台运行)
|
||||||
|
echo "启动后端服务,参数: $@"
|
||||||
|
ushare "$@" &
|
||||||
|
BACKEND_PID=$!
|
||||||
|
|
||||||
|
# 定义优雅关闭函数
|
||||||
|
graceful_shutdown() {
|
||||||
|
echo "接收到终止信号,开始优雅关闭..."
|
||||||
|
|
||||||
|
# 先关闭 Nginx
|
||||||
|
echo "关闭 Nginx..."
|
||||||
|
nginx -s quit 2>/dev/null || kill -TERM $NGINX_PID 2>/dev/null
|
||||||
|
|
||||||
|
# 关闭后端服务
|
||||||
|
echo "关闭后端服务 PID $BACKEND_PID..."
|
||||||
|
kill -TERM $BACKEND_PID 2>/dev/null
|
||||||
|
|
||||||
|
# 等待进程终止
|
||||||
|
wait $BACKEND_PID $NGINX_PID 2>/dev/null
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 捕获系统信号
|
||||||
|
trap 'graceful_shutdown' SIGTERM SIGINT
|
||||||
|
|
||||||
|
# 启动 Nginx(前台运行)
|
||||||
|
echo "启动 Nginx..."
|
||||||
|
nginx -g "daemon off;" &
|
||||||
|
NGINX_PID=$!
|
||||||
|
|
||||||
|
# 等待所有后台进程
|
||||||
|
wait $BACKEND_PID $NGINX_PID
|
||||||
@@ -18,5 +18,10 @@ server {
|
|||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_read_timeout 3600s;
|
||||||
|
proxy_send_timeout 3600s;
|
||||||
|
send_timeout 3600s;
|
||||||
|
proxy_buffering off;
|
||||||
|
gzip off;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,6 +104,10 @@ func (m *meta) Start(ctx context.Context) {
|
|||||||
ticker := time.NewTicker(time.Minute)
|
ticker := time.NewTicker(time.Minute)
|
||||||
m.ctx = ctx
|
m.ctx = ctx
|
||||||
|
|
||||||
|
if err := os.MkdirAll(opt.Cfg.DataPath, 0644); err != nil {
|
||||||
|
log.Fatal("controller.MetaManager.Start: mkdir datapath failed, path = %s, err = %s", opt.Cfg.DataPath, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
// 清理 2 分钟内没有继续上传的 part
|
// 清理 2 分钟内没有继续上传的 part
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
@@ -131,14 +135,25 @@ func (m *meta) Start(ctx context.Context) {
|
|||||||
|
|
||||||
// 清理一天前的文件
|
// 清理一天前的文件
|
||||||
go func() {
|
go func() {
|
||||||
|
if opt.Cfg.CleanInterval <= 0 {
|
||||||
|
log.Warn("meta.Clean: no clean interval set, plz clean manual!!!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ticker := time.NewTicker(5 * time.Minute)
|
ticker := time.NewTicker(5 * time.Minute)
|
||||||
|
duration := time.Duration(opt.Cfg.CleanInterval) * time.Hour
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
case now := <-ticker.C:
|
case now := <-ticker.C:
|
||||||
|
//log.Debug("meta.Clean: 开始清理过期文件 = %v", duration)
|
||||||
_ = filepath.Walk(opt.Cfg.DataPath, func(path string, info os.FileInfo, err error) error {
|
_ = filepath.Walk(opt.Cfg.DataPath, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if info == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -164,12 +179,16 @@ func (m *meta) Start(ctx context.Context) {
|
|||||||
|
|
||||||
code := strings.TrimPrefix(name, ".meta.")
|
code := strings.TrimPrefix(name, ".meta.")
|
||||||
|
|
||||||
if now.Sub(time.UnixMilli(mi.CreatedAt)) > 24*time.Hour {
|
if now.Sub(time.UnixMilli(mi.CreatedAt)) > duration {
|
||||||
|
|
||||||
log.Debug("controller.meta: file out of date, code = %s, user_key = %s", code, mi.Uploader)
|
log.Debug("controller.meta: file out of date, code = %s, user_key = %s", code, mi.Uploader)
|
||||||
|
|
||||||
os.RemoveAll(opt.FilePath(code))
|
if err = os.RemoveAll(opt.FilePath(code)); err != nil {
|
||||||
os.RemoveAll(path)
|
log.Warn("meta.Clean: remove file failed, file = %s, err = %s", opt.FilePath(code), err.Error())
|
||||||
|
}
|
||||||
|
if err = os.RemoveAll(path); err != nil {
|
||||||
|
log.Warn("meta.Clean: remove file failed, file = %s, err = %s", path, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
m.Lock()
|
m.Lock()
|
||||||
delete(m.m, code)
|
delete(m.m, code)
|
||||||
|
|||||||
+5
-4
@@ -7,10 +7,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
Debug bool
|
Debug bool
|
||||||
Address string
|
Address string
|
||||||
DataPath string
|
DataPath string
|
||||||
Auth string
|
Auth string
|
||||||
|
CleanInterval int
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/loveuer/ushare/internal/api"
|
"github.com/loveuer/ushare/internal/api"
|
||||||
"github.com/loveuer/ushare/internal/controller"
|
"github.com/loveuer/ushare/internal/controller"
|
||||||
"github.com/loveuer/ushare/internal/opt"
|
"github.com/loveuer/ushare/internal/opt"
|
||||||
|
"github.com/loveuer/ushare/internal/pkg/tool"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
@@ -16,11 +17,12 @@ func init() {
|
|||||||
flag.StringVar(&opt.Cfg.Address, "address", "0.0.0.0:9119", "")
|
flag.StringVar(&opt.Cfg.Address, "address", "0.0.0.0:9119", "")
|
||||||
flag.StringVar(&opt.Cfg.DataPath, "data", "/data", "")
|
flag.StringVar(&opt.Cfg.DataPath, "data", "/data", "")
|
||||||
flag.StringVar(&opt.Cfg.Auth, "auth", "", "auth required(admin, password)")
|
flag.StringVar(&opt.Cfg.Auth, "auth", "", "auth required(admin, password)")
|
||||||
|
flag.IntVar(&opt.Cfg.CleanInterval, "clean", 24, "清理文件的周期, 单位: 小时, 0 则表示不自动清理")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if opt.Cfg.Debug {
|
if opt.Cfg.Debug {
|
||||||
log.SetLogLevel(log.LogLevelDebug)
|
log.SetLogLevel(log.LogLevelDebug)
|
||||||
log.Debug("start server with debug mode")
|
tool.TablePrinter(opt.Cfg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user